Merge branch 'futatuki-configure-with-2to3-as-different-name'

* futatuki-configure-with-2to3-as-different-name:
  Apply patch to configure with 2to3 rename for 3.0.12
diff --git a/.gitignore b/.gitignore
index e94087e..d2e6b84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,6 +66,7 @@
 CCache/config.h
 CCache/config.log
 CCache/config.status
+CCache/config_win32.h
 Examples/Makefile
 Examples/d/example.mk
 Examples/guile/Makefile
@@ -85,6 +86,8 @@
 # Build Artifacts
 .dirstamp
 CCache/ccache-swig
+CCache/ccache-swig.1
+CCache/web/ccache-swig-man.html
 Lib/swigwarn.swg
 Source/CParse/parser.c
 Source/CParse/parser.h
diff --git a/.travis.yml b/.travis.yml
index 709bc49..a82b2bc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,9 +9,6 @@
     - compiler: gcc
       os: linux
       env: SWIGLANG=
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=
       sudo: required
       dist: trusty
     - os: linux
@@ -55,6 +52,8 @@
     - compiler: gcc
       os: linux
       env: SWIGLANG=javascript ENGINE=node
+      sudo: required
+      dist: trusty
     - compiler: gcc
       os: linux
       env: SWIGLANG=javascript ENGINE=jsc
@@ -165,6 +164,14 @@
       env: SWIGLANG=python SWIG_FEATURES=-builtin
       sudo: required
       dist: trusty
+    - os: linux
+      env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
+      sudo: required
+      dist: trusty
+    - os: linux
+      env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 PY3=3 VER=3.5
+      sudo: required
+      dist: trusty
     - compiler: gcc
       os: linux
       env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
diff --git a/CCache/Makefile.in b/CCache/Makefile.in
index 67fd3f3..d1bb8c5 100644
--- a/CCache/Makefile.in
+++ b/CCache/Makefile.in
@@ -8,6 +8,7 @@
 mandir=@mandir@
 INSTALLCMD=@INSTALL@
 PACKAGE_NAME=@PACKAGE_NAME@
+PROGRAM_NAME=@PROGRAM_NAME@
 # Soft link test can be skipped on systems that don't support soft linking
 NOSOFTLINKSTEST=
 
@@ -17,13 +18,10 @@
 SWIG_LIB=../$(srcdir)/../Lib
 EXEEXT=@EXEEXT@
 
-# Use standard autoconf approach to transform executable name using --program-prefix and --program-suffix
-transform = @program_transform_name@
-
 LIBS= @LIBS@
 OBJS= ccache.o mdfour.o hash.o execute.o util.o args.o stats.o \
 	cleanup.o snprintf.o unify.o
-HEADERS = ccache.h mdfour.h
+HEADERS = ccache.h mdfour.h config.h config_win32.h
 
 all: $(PACKAGE_NAME)$(EXEEXT)
 
@@ -32,7 +30,7 @@
 	$(SHELL) ./config.status
 
 # Note that HTML documentation is actually generated and used from the main SWIG documentation Makefile
-docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html
+docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
 
 $(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS)
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
@@ -40,40 +38,43 @@
 $(srcdir)/$(PACKAGE_NAME).1: $(srcdir)/ccache.yo
 	-yodl2man -o $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/ccache.yo
 
-$(srcdir)/web/ccache-man.html: $(srcdir)/ccache.yo
-	yodl2html -o $(srcdir)/web/ccache-man.html $(srcdir)/ccache.yo
+$(srcdir)/web/$(PACKAGE_NAME)-man.html: $(srcdir)/ccache.yo
+	yodl2html -o $(srcdir)/web/$(PACKAGE_NAME)-man.html $(srcdir)/ccache.yo
 
 install: $(PACKAGE_NAME)$(EXEEXT)
 	@echo "Installing $(PACKAGE_NAME)"
-	@echo "Installing $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)"
+	@echo "Installing $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)"
 	${INSTALLCMD} -d $(DESTDIR)${bindir}
-	${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
+	${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)
 
 install-docs: $(srcdir)/$(PACKAGE_NAME).1
-	@echo "Installing $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1"
+	@echo "Installing $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1"
 	${INSTALLCMD} -d $(DESTDIR)${mandir}/man1
-	${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
+	${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1
 
 uninstall: $(PACKAGE_NAME)$(EXEEXT)
-	rm -f $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
+	rm -f $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)
 
 uninstall-docs: $(srcdir)/$(PACKAGE_NAME).1
-	rm -f $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
+	rm -f $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1
 
-clean:
+clean: clean-docs
 	/bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT)
 
+clean-docs:
+	rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
+
 test: test.sh
-	SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' $(srcdir)/test.sh
+	SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' CCACHE='../$(PACKAGE_NAME)' CCACHE_PROG=$(PROGRAM_NAME) $(srcdir)/test.sh
 
 check: test
 
 distclean: clean
-	/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h
+	/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h config_win32.h
 	/bin/rm -rf autom4te.cache
 
 maintainer-clean: distclean
-	/bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html
+	/bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html
 
 
 # FIXME: To fix this, test.sh needs to be able to take ccache from the
diff --git a/CCache/ccache.h b/CCache/ccache.h
index a79d883..25e7864 100644
--- a/CCache/ccache.h
+++ b/CCache/ccache.h
@@ -6,7 +6,7 @@
 #include "config.h"
 #else
 #include <sys/locking.h>
-#define PACKAGE_NAME "ccache-swig.exe"
+#include "config_win32.h"
 #endif
 
 #include <stdio.h>
@@ -51,7 +51,7 @@
 #define STATUS_FATAL 4
 #define STATUS_NOCACHE 5
 
-#define MYNAME PACKAGE_NAME
+#define MYNAME PROGRAM_NAME
 
 #define LIMIT_MULTIPLE 0.8
 
diff --git a/CCache/config_win32.h.in b/CCache/config_win32.h.in
new file mode 100644
index 0000000..2d5ab97
--- /dev/null
+++ b/CCache/config_win32.h.in
@@ -0,0 +1,3 @@
+#if !defined(PROGRAM_NAME)
+#define PROGRAM_NAME "@PROGRAM_NAME@.exe"
+#endif
diff --git a/CCache/configure.ac b/CCache/configure.ac
index dfbf86d..e1c7618 100644
--- a/CCache/configure.ac
+++ b/CCache/configure.ac
@@ -7,6 +7,7 @@
 AC_MSG_NOTICE([Configuring ccache])
 
 AC_CONFIG_HEADER(config.h)
+AC_CONFIG_FILES([config_win32.h])
 
 dnl Checks for programs.
 AC_PROG_CC
@@ -14,6 +15,20 @@
 AC_PROG_INSTALL
 AC_ARG_PROGRAM # for program_transform_name
 
+AC_SUBST(PROGRAM_NAME)
+if test "x$program_prefix" != "xNONE" -a "x$program_prefix" != "x" 
+then
+	PROGRAM_NAME="$program_prefix$PACKAGE_NAME"
+else
+	PROGRAM_NAME="$PACKAGE_NAME"
+fi
+if test "x$program_suffix" != "xNONE" -a "x$program_suffix" != "x" 
+then
+	PROGRAM_NAME="$PROGRAM_NAME$program_suffix"
+fi
+
+AC_DEFINE_UNQUOTED(PROGRAM_NAME, "$PROGRAM_NAME", [Define my program name])
+   
 AC_DEFINE([_GNU_SOURCE], 1,
           [Define _GNU_SOURCE so that we get all necessary prototypes])
 
diff --git a/CCache/test.sh b/CCache/test.sh
index 438e782..5b6f92a 100755
--- a/CCache/test.sh
+++ b/CCache/test.sh
@@ -20,7 +20,12 @@
 PATH="`echo $PATH | \
  sed -e 's!:/usr\(/local\)*/lib\([0-9]\)*/ccache\(/\)*!!g'`"
 
-CCACHE=../ccache-swig
+if test -n "$CCACHE"; then
+ CCACHE="$CCACHE"
+else
+ CCACHE=../ccache-swig
+fi
+
 TESTDIR=test.$$
 
 test_failed() {
@@ -406,6 +411,10 @@
 # main program
 rm -rf $TESTDIR
 mkdir $TESTDIR
+if test -n "$CCACHE_PROG"; then
+  ln -s $CCACHE $TESTDIR/$CCACHE_PROG
+  CCACHE=./$CCACHE_PROG
+fi
 cd $TESTDIR || exit 1
 
 unset CCACHE_DIR
diff --git a/CHANGES b/CHANGES
index 836bf4b..8376c0b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -21116,7 +21116,7 @@
               typedef __name vector<T>;
               %enddef
 
-           An a specific instantiation is created in exactly the same way:
+           A specific instantiation is created in exactly the same way:
 
              %template(intvec) vector<int>;
 
diff --git a/CHANGES.current b/CHANGES.current
index 584fa6c..f76e5a5 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,292 @@
 Version 4.0.0 (in progress)
 ===========================
 
+2017-09-18: wsfulton
+            Fix type promotion wrapping constant expressions of the form:
+              # define EXPR_MIXED1    (0x80 + 11.1) - 1
+            This was previously an integral type instead of a floating point type.
+
+2017-09-17: wsfulton
+            Fix generated code for constant expressions containing wchar_t L literals such as:
+              # define __WCHAR_MAX    (0x7fffffff + L'\0')
+              # define __WCHAR_MIN    (-__WCHAR_MAX - 1)
+
+2017-09-10: mlamarre
+            [Python] Patch #1083. Define_DEBUG to 1 to do exactly like Visual Studio
+            /LDd, /MDd or /MTd compiler options.
+
+2017-08-25: wsfulton
+            Issue #1059. Add support for C++11 ref-qualifiers on non-static member functions.
+            Members with lvalue ref-qualifiers such as:
+
+              struct RQ {
+                void m1(int x) &;
+                void m2(int x) const &;
+              };
+
+            are wrapped like any other member function. Member functions with rvalue ref-qualifiers
+            are ignored by default, such as:
+
+              struct RQ {
+                void m3(int x) &&;
+                void m4(int x) const &&;
+              };
+
+              example.i:7: Warning 405: Method with rvalue ref-qualifier m3(int) && ignored.
+              example.i:8: Warning 405: Method with rvalue ref-qualifier m4(int) const && ignored.
+
+            These can be unignored and exposed to the target language, see further documentation in
+            CPlusPlus11.html.
+
+2017-08-16: wsfulton
+            Fix #1063. Add using declarations to templates into typedef table.
+
+            Using declarations to templates were missing in SWIG's internal typedef tables.
+            This led to a few problems, such as, templates that did not instantiate and generated
+            C++ code that did not compile as SWIG did not know what scope the template was
+            in. This happened mostly when a using declaration was used on a template type in a
+            completely unrelated namespace.
+
+2017-08-16: wsfulton
+            Fix type lookup in the presence of using directives and using declarations.
+
+            Fix some cases of type lookup failure via a combination of both using directives and
+            using declarations resulting in C++ code that did not compile as the generated type was
+            not fully qualified for use in the global namespace. Example below:
+
+              namespace Space5 {
+                namespace SubSpace5 {
+                  namespace SubSubSpace5 {
+                    struct F {};
+                  }
+                }
+                using namespace SubSpace5;
+                using SubSubSpace5::F;
+                void func(SubSubSpace5::F f);
+              }
+
+2017-08-16: wsfulton
+            Issue #1051. %template scope enforcement and class definition fixes.
+
+            The scoping rules around %template have been specified and enforced.
+            The %template directive for a class template is the equivalent to an
+            explicit instantiation of a C++ class template. The scope for a valid
+            %template instantiation is now the same as the scope required for a
+            valid explicit instantiation of a C++ template. A definition of the
+            template for the explicit instantiation must be in scope where the
+            instantiation is declared and must not be enclosed within a different
+            namespace.
+
+            For example, a few %template and C++ explicit instantiations of std::vector
+            are shown below:
+
+              // valid
+              namespace std {
+                %template(vin) vector<int>;
+                template class vector<int>;
+              }
+
+              // valid
+              using namespace std;
+              %template(vin) vector<int>;
+              template class vector<int>;
+
+              // valid
+              using std::vector;
+              %template(vin) vector<int>;
+              template class vector<int>;
+
+              // ill-formed
+              namespace unrelated {
+                using std::vector;
+                %template(vin) vector<int>;
+                template class vector<int>;
+              }
+
+              // ill-formed
+              namespace unrelated {
+                using namespace std;
+                %template(vin) vector<int>;
+                template class vector<int>;
+              }
+
+              // ill-formed
+              namespace unrelated {
+                namespace std {
+                  %template(vin) vector<int>;
+                  template class vector<int>;
+                }
+              }
+
+              // ill-formed
+              namespace unrelated {
+                %template(vin) std::vector<int>;
+                template class std::vector<int>;
+              }
+
+            When the scope is incorrect, an error now occurs such as:
+
+              cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and
+              was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
+
+            Previously SWIG accepted the ill-formed examples above but this led to
+            numerous subtle template scope problems especially in the presence of
+            using declarations and using directives as well as with %feature and %typemap.
+
+            Actually, a valid instantiation is one which conforms to the C++03
+            standard as C++11 made a change to disallow using declarations and
+            using directives to find a template.
+
+              // valid C++03, ill-formed C++11
+              using std::vector;
+              template class vector<int>;
+
+            Similar fixes for defining classes using forward class references have
+            also been put in place. For example:
+
+              namespace Space1 {
+                struct A;
+              }
+              namespace Space2 {
+                struct Space1::A {
+                  void x();
+                }
+              }
+
+            will now error out with:
+
+              cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
+              was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
+
+2017-08-16: wsfulton
+            Fix scope lookup for template parameters containing unary scope operators.
+
+            Fixes cases like:
+
+            namespace Alloc {
+              template<typename T> struct Rebind {
+                typedef int Integer;
+              };
+            }
+            %template(RebindBucket) Alloc::Rebind< Bucket >;
+            OR
+            %template(RebindBucket) Alloc::Rebind< ::Bucket >;
+
+            Alloc::Rebind< Bucket >::Integer Bucket1();
+            Alloc::Rebind< ::Bucket >::Integer Bucket2();
+            Alloc::Rebind<::template TemplateBucket<double>>::Integer Bucket3();
+
+2017-08-16: wsfulton
+            For templates only, the template parameters are fully resolved when
+            handling typemaps. Without this, it is too hard to have decent rules
+            to apply typemaps when parameter types are typedef'd and template
+            parameters have default values.
+
+            Fixes %clear for typedefs in templates, eg:
+
+              %typemap("in") XXX<int>::Long "..."
+              template typename<T> struct XXX {
+                typedef long Long;
+              };
+              %clear XXX<int>::Long;
+
+            as the typemap was previously incorrectly stored as a typemap for long
+            instead of XXX<int>::Long.
+
+2017-08-05: olly
+	    [C++11] Allow static_assert at the top level (and disallow it right
+	    after template<T>).  Fixes https://github.com/swig/swig/issues/1031
+	    reported by Artem V L.
+
+2017-08-02: wsfulton
+            Fix incorrectly shown warning when an empty template instantiation was used on a
+            class used as a base class and that base class was explicitly ignored with %ignore.
+            Example of the warning which will no longer appear:
+
+              Warning 401: Base class 'Functor< int,int >' has no name as it is an empty
+              template instantiated with '%template()'. Ignored.
+
+2017-07-17: fflexo
+            [Java] #674 Add std_list.i to add support for std::list containers. The Java proxy
+            extends java.util.AbstractSequentialList and makes the C++ std::list container look
+            and feel much like a java.util.LinkedList from Java.
+
+2017-07-07: wsfulton
+            [Python] Fix display of documented template types when using the autodoc
+            feature. For example when wrapping:
+
+              %feature("autodoc");
+              template<typename X> struct T {};
+              %template(TInteger) T<int>;
+
+            the generated documentation contains:
+              """Proxy of C++ T< int > class."""
+            instead of:
+              """Proxy of C++ T<(int)> class."""
+            and
+              """__init__(TInteger self) -> TInteger"""
+            instead of
+              """__init__(T<(int)> self) -> TInteger"""
+
+2017-06-27: nihaln
+	    [PHP] Update the OUTPUT Typemap to add return statement to the
+	    PHP Wrapper.
+
+2017-06-27: nihaln
+	    [PHP] Update the enum and value examples to use the OO wrappers
+	    rather than the flat functions produced with -noproxy.  There's
+	    not been a good reason to use -noproxy for since PHP5 OO wrapping
+	    was fixed back in 2005.
+
+2017-06-23: m7thon
+            [Python] fix and improve default argument handling:
+
+            1. Fix negative octals. Currently not handled correctly by `-py3`
+               (unusual case, but incorrect).
+            2. Fix arguments of type "octal + something" (e.g. `0640 | 04`).
+               Currently drops everything after the first octal. Nasty!
+            3. Fix bool arguments "0 + something" (e.g. `0 | 1`) are always
+               "False" (unusual case, but incorrect).
+            4. Remove special handling of "TRUE" and "FALSE" from
+               `convertValue` since there's no reason these have to match
+               "true" and "false".
+            5. Remove the Python 2 vs. Python 3 distinction based on the
+               `-py3` flag. Now the same python code is produced for default
+               arguments for Python 2 and Python 3. For this, octal default
+               arguments, e.g. 0644, are now wrapped as `int('644', 8)`. This
+               is required, as Python 2 and Python 3 have incompatible syntax
+               for octal literals.
+
+            Fixes #707
+
+2017-06-21: futatuki
+            #1004 - Fix ccache-swig executable name to respect configure's --program-prefix and
+            --program-suffix values if used.
+
+2017-06-21: tamuratak
+            [Ruby] #911 - Add std::wstring support.
+
+2017-06-19: wsfulton
+            [Python] Fix handling of rich comparisons when wrapping overloaded operators:
+
+              operator<  operator<=  operator>  operator>=  operator==  operator!=
+
+            Previously a TypeError was always thrown if the type was not correct. NotImplemented
+            is now returned from these wrapped functions if the type being compared with is
+            not correct. The subsequent behaviour varies between different versions of Python
+            and the comparison function being used, but is now consistent with normal Python
+            behaviour. For example, for the first 4 operator overloads above, a TypeError
+            'unorderable types' is thrown in Python 3, but Python 2 will return True or False.
+            NotImplemented should be returned when the comparison cannot be done, see PEP 207 and
+            https://docs.python.org/3/library/constants.html#NotImplemented
+
+            Note that the bug was only present when overloaded operators did not also have a
+            function overload.
+
+            Fixes SF bug #1208 (3441262) and SF patch #303.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
 2017-06-17: fabrice102
             [Go] Fix Go callback example.  Fixes github #600, #955, #1000.
 
diff --git a/Doc/Manual/Allegrocl.html b/Doc/Manual/Allegrocl.html
index ddb6fba..c4d8981 100644
--- a/Doc/Manual/Allegrocl.html
+++ b/Doc/Manual/Allegrocl.html
@@ -155,7 +155,7 @@
 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 a an
+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
diff --git a/Doc/Manual/Android.html b/Doc/Manual/Android.html
index b295b5e..7263142 100644
--- a/Doc/Manual/Android.html
+++ b/Doc/Manual/Android.html
@@ -409,7 +409,7 @@
 
 <p>
 First create an Android project called <tt>SwigClass</tt> in a subdirectory called <tt>class</tt>.
-The steps below create and build a the JNI C++ app.
+The steps below create and build the JNI C++ app.
 Adjust the <tt>--target</tt> id as mentioned earlier in the <a href="Android.html#Android_examples_intro">Examples introduction</a>.
 </p>
 
diff --git a/Doc/Manual/CCache.html b/Doc/Manual/CCache.html
index d23b0cb..521184f 100644
--- a/Doc/Manual/CCache.html
+++ b/Doc/Manual/CCache.html
@@ -411,7 +411,7 @@
 
 
 <p>
-ccache was inspired by the compilercache shell script script written
+ccache was inspired by the compilercache shell script written
 by Erik Thiele and I would like to thank him for an excellent piece of
 work. See
 <a href="http://www.erikyyy.de/compilercache/">http://www.erikyyy.de/compilercache/</a>
diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html
index d349445..f9281bd 100644
--- a/Doc/Manual/CPlusPlus11.html
+++ b/Doc/Manual/CPlusPlus11.html
@@ -42,6 +42,7 @@
 <li><a href="#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
 <li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
 <li><a href="#CPlusPlus11_attributes">Attributes</a>
+<li><a href="#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
 </ul>
 <li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
 <ul>
@@ -877,7 +878,8 @@
 
 
 <p>
-SWIG correctly parses the new <tt>static_assert</tt> declarations.
+SWIG correctly parses the new <tt>static_assert</tt> declarations (though 3.0.12 and earlier
+had a bug which meant this wasn't accepted at file scope).
 This is a C++ compile time directive so there isn't anything useful that SWIG can do with it.
 </p>
 
@@ -970,6 +972,104 @@
 [[noreturn, nothrow]] void f [[noreturn]] ();
 </pre></div>
 
+
+<H3><a name="CPlusPlus11_ref_qualifiers">7.2.29 Methods with ref-qualifiers</a></H3>
+
+
+<p>
+C++11 non-static member functions can be declared with ref-qualifiers.
+Member functions declared with a <tt>&amp;</tt> lvalue ref-qualifiers are wrapped like any other function without ref-qualifiers.
+Member functions declared with a <tt>&amp;&amp;</tt> rvalue ref-qualifiers are ignored by default
+as they are unlikely to be required from non-C++ languages where the concept of <i>rvalue-ness</i>
+for the implied *this pointer does not apply.
+The warning is hidden by default, but can be displayed as described in the section on <a href="Warnings.html#Warnings_nn4">Enabling extra warnings</a>.
+</p>
+
+<p>
+Consider:
+</p>
+
+<div class="code"><pre>
+struct RQ {
+  void m1(int x) &amp;;
+  void m2(int x) &amp;&amp;;
+};
+</pre></div>
+
+<p>
+The only wrapped method will be the lvalue ref-qualified method <tt>m1</tt>
+and if SWIG is run with the <tt>-Wextra</tt> command-line option, the following warning will be issued indicating <tt>m2</tt> is not wrapped:
+</p>
+
+<div class="shell">
+<pre>
+example.i:7: Warning 405: Method with rvalue ref-qualifier m2(int) &amp;&amp; ignored.
+</pre>
+</div>
+
+<p>
+If you unignore the method as follows, wrappers for <tt>m2</tt> will be generated:
+</p>
+
+<div class="code"><pre>
+%feature("ignore", "0") RQ::m2(int x) &amp;&amp;;
+struct RQ {
+  void m1(int x) &amp;;
+  void m2(int x) &amp;&amp;;
+};
+</pre></div>
+
+<p>
+Inspection of the generated C++ code, will show that <tt>std::move</tt> is used on the instance
+of the <tt>RQ *</tt> class:
+</p>
+
+<div class="code"><pre>
+  RQ *arg1 = (RQ *) 0 ;
+  int arg2 ;
+
+  arg1 = ...marshalled from target language...
+  arg2 = ...marshalled from target language...
+
+  std::move(*arg1).m2(arg2);
+</pre></div>
+
+<p>
+This will compile but when run, the move effects may not be what you want.
+As stated earlier, rvalue ref-qualifiers aren't really applicable outside the world of C++.
+However, if you really know what you are doing, full control over the call to the method is
+possible via the low-level "action" feature.
+This feature completely replaces the call to the underlying function, that is, the last line in the snippet of code above.
+</p>
+
+<div class="code"><pre>
+%feature("ignore", "0") RQ::m2(int x) &amp;&amp;;
+%feature("action") RQ::m2(int x) &amp;&amp; %{
+  RQ().m2(arg2);
+%}
+struct RQ {
+  void m1(int x) &amp;;
+  void m2(int x) &amp;&amp;;
+};
+</pre></div>
+
+<p>
+resulting in:
+</p>
+
+<div class="code"><pre>
+  RQ *arg1 = (RQ *) 0 ;
+  int arg2 ;
+
+  arg1 = ...marshalled from target language...
+  arg2 = ...marshalled from target language...
+
+  RQ().m2(arg2);
+</pre></div>
+
+<p>
+<b>Compatibility note:</b> SWIG-4.0.0 was the first version to support ref-qualifiers.
+</p>
 <H2><a name="CPlusPlus11_standard_library_changes">7.3 Standard library changes</a></H2>
 
 
@@ -1176,5 +1276,6 @@
 You could just go with the more attractive option of just using <tt>double</tt> as the return type in the function declaration instead of <tt>result_of</tt>!
 </p>
 
+
 </body>
 </html>
diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html
index 5be63a3..70010c9 100644
--- a/Doc/Manual/CSharp.html
+++ b/Doc/Manual/CSharp.html
@@ -677,7 +677,7 @@
 <div class="code">
 <pre>
 public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
-    examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
+  examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
 }
 </pre>
 </div>
@@ -997,9 +997,9 @@
 <div class="code">
 <pre>
 public class runme {
-    static void Main() {
-      example.positivesonly(-1);
-    }
+  static void Main() {
+    example.positivesonly(-1);
+  }
 }
 </pre>
 </div>
@@ -1772,7 +1772,7 @@
 
 
 <p>
-When using <a href="Modules.html#Modules">multiple modules</a> it is is possible to compile each SWIG generated wrapper
+When using <a href="Modules.html#Modules">multiple modules</a> it is possible to compile each SWIG generated wrapper
 into a different assembly.
 However, by default the generated code may not compile if 
 generated classes in one assembly use generated classes in another assembly.
@@ -1846,12 +1846,12 @@
 
 <div class="code">
 <pre>
-      Wheel wheel = new Bike(10).getWheel();
-      Console.WriteLine("wheel size: " + wheel.size);
-      // Simulate a garbage collection
-      global::System.GC.Collect();
-      global::System.GC.WaitForPendingFinalizers();
-      global::System.Console.WriteLine("wheel size: " + wheel.size);
+  Wheel wheel = new Bike(10).getWheel();
+  Console.WriteLine("wheel size: " + wheel.size);
+  // Simulate a garbage collection
+  global::System.GC.Collect();
+  global::System.GC.WaitForPendingFinalizers();
+  global::System.Console.WriteLine("wheel size: " + wheel.size);
 </pre>
 </div>
 
@@ -1980,9 +1980,9 @@
 
 <div class="code">
 <pre>
-      Container container = new Container();
-      Element element = new Element(20);
-      container.setElement(element);
+  Container container = new Container();
+  Element element = new Element(20);
+  container.setElement(element);
 </pre>
 </div>
 
@@ -1993,14 +1993,14 @@
 
 <div class="code">
 <pre>
-      Container container = new Container();
-      Element element = new Element(20);
-      container.setElement(element);
-      Console.WriteLine("element.value: " + container.getElement().value);
-      // Simulate a garbage collection
-      global::System.GC.Collect();
-      global::System.GC.WaitForPendingFinalizers();
-      global::System.Console.WriteLine("element.value: " + container.getElement().value);
+  Container container = new Container();
+  Element element = new Element(20);
+  container.setElement(element);
+  Console.WriteLine("element.value: " + container.getElement().value);
+  // Simulate a garbage collection
+  global::System.GC.Collect();
+  global::System.GC.WaitForPendingFinalizers();
+  global::System.Console.WriteLine("element.value: " + container.getElement().value);
 </pre>
 </div>
 
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 56afca8..f3beb22 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -228,7 +228,6 @@
 <li><a href="SWIGPlus.html#SWIGPlus_nn12">Static members</a>
 <li><a href="SWIGPlus.html#SWIGPlus_member_data">Member data</a>
 </ul>
-<li><a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a>
 <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>
@@ -236,16 +235,27 @@
 <li><a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nn20">Inheritance</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers,  and type checking</a>
-<li><a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a>
+<li><a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a>
+<li><a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>
 <ul>
 <li><a href="SWIGPlus.html#SWIGPlus_nn24">Dispatch function generation</a>
-<li><a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in Overloading</a>
-<li><a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
+<li><a href="SWIGPlus.html#SWIGPlus_nn25">Ambiguity in overloading</a>
+<li><a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nn27">Comments on overloading</a>
 </ul>
-<li><a href="SWIGPlus.html#SWIGPlus_nn28">Wrapping overloaded operators</a>
+<li><a href="SWIGPlus.html#SWIGPlus_nn28">Overloaded operators</a>
 <li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
 <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_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>
+<li><a href="SWIGPlus.html#SWIGPlus_template_more">More on templates</a>
+</ul>
 <li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
 <ul>
 <li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
@@ -300,6 +310,7 @@
 <li><a href="CPlusPlus11.html#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
 <li><a href="CPlusPlus11.html#CPlusPlus11_alignment">Control and query object alignment</a>
 <li><a href="CPlusPlus11.html#CPlusPlus11_attributes">Attributes</a>
+<li><a href="CPlusPlus11.html#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
 </ul>
 <li><a href="CPlusPlus11.html#CPlusPlus11_standard_library_changes">Standard library changes</a>
 <ul>
@@ -347,26 +358,32 @@
 <div class="sectiontoc">
 <ul>
 <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>
+<li><a href="Library.html#Library_nn3">C arrays and pointers</a>
 <ul>
 <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>
 <li><a href="Library.html#Library_nn7">cdata.i</a>
 </ul>
-<li><a href="Library.html#Library_nn8">C String Handling</a>
+<li><a href="Library.html#Library_nn8">C string handling</a>
 <ul>
 <li><a href="Library.html#Library_nn9">Default string handling</a>
 <li><a href="Library.html#Library_nn10">Passing binary data</a>
 <li><a href="Library.html#Library_nn11">Using %newobject to release memory</a>
 <li><a href="Library.html#Library_nn12">cstring.i</a>
 </ul>
-<li><a href="Library.html#Library_stl_cpp_library">STL/C++ Library</a>
+<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_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>
+<ul>
+<li><a href="Library.html#Library_shared_ptr_basics">shared_ptr basics</a>
+<li><a href="Library.html#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
+<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_auto_ptr">auto_ptr smart pointer</a>
 </ul>
 <li><a href="Library.html#Library_nn16">Utility Libraries</a>
diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html
index 0e5fb28..269e659 100644
--- a/Doc/Manual/Customization.html
+++ b/Doc/Manual/Customization.html
@@ -356,7 +356,7 @@
 named "allocate".  This would include both global and member
 functions.  The names supplied to <tt>%exception</tt> follow the same
 rules as for <tt>%rename</tt> described in the section on 
-<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>.
+<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>.
 For example, if you wanted to define
 an exception handler for a specific class, you might write this:
 </p>
@@ -516,7 +516,7 @@
     $action
   } 
   catch (MemoryError) {
-      croak("Out of memory in $decl");
+    croak("Out of memory in $decl");
   }
 }
 void log(const char *message);
@@ -796,7 +796,7 @@
 </div>
 
 <p>
-The name matching rules outlined in the <a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
+The name matching rules outlined in the <a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
 section applies to all <tt>%feature</tt> directives.
 In fact the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>. 
 The matching rules mean that features are very flexible and can be applied with
diff --git a/Doc/Manual/D.html b/Doc/Manual/D.html
index 45b57e1..1a317a0 100644
--- a/Doc/Manual/D.html
+++ b/Doc/Manual/D.html
@@ -280,7 +280,7 @@
   ...
 }
 </pre></div>
-    <p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
+    <p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but if it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
     <p>The <tt>$importtype</tt> macro helps you to elegantly solve this problem:</p>
 <div class="code"><pre>
 %typemap(dimports) RemoteMpe %{
diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html
index bf70b69..b566578 100644
--- a/Doc/Manual/Extending.html
+++ b/Doc/Manual/Extending.html
@@ -1576,7 +1576,7 @@
 
 <div class="indent">
 Returns the last child node.   You might use this if you wanted to append a new
-node to the of a class.
+node to the children of a class.
 </div>
 
 <p>
@@ -2592,36 +2592,36 @@
 <pre>
 void Language::main(int argc, char *argv[]) {
   for (int i = 1; i &lt; argc; i++) {
-      if (argv[i]) {
-          if (strcmp(argv[i], "-interface") == 0) {
-            if (argv[i+1]) {
-              interface = NewString(argv[i+1]);
-              Swig_mark_arg(i);
-              Swig_mark_arg(i+1);
-              i++;
-            } else {
-              Swig_arg_error();
-            }
-          } else if (strcmp(argv[i], "-globals") == 0) {
-            if (argv[i+1]) {
-              global_name = NewString(argv[i+1]);
-              Swig_mark_arg(i);
-              Swig_mark_arg(i+1);
-              i++;
-            } else {
-              Swig_arg_error();
-            }
-          } else if ((strcmp(argv[i], "-proxy") == 0)) {
-            proxy_flag = 1;
-            Swig_mark_arg(i);
-          } else if (strcmp(argv[i], "-keyword") == 0) {
-            use_kw = 1;
-            Swig_mark_arg(i);
-          } else if (strcmp(argv[i], "-help") == 0) {
-            fputs(usage, stderr);
-          }
-          ...
+    if (argv[i]) {
+      if (strcmp(argv[i], "-interface") == 0) {
+        if (argv[i+1]) {
+          interface = NewString(argv[i+1]);
+          Swig_mark_arg(i);
+          Swig_mark_arg(i+1);
+          i++;
+        } else {
+          Swig_arg_error();
+        }
+      } else if (strcmp(argv[i], "-globals") == 0) {
+        if (argv[i+1]) {
+          global_name = NewString(argv[i+1]);
+          Swig_mark_arg(i);
+          Swig_mark_arg(i+1);
+          i++;
+        } else {
+          Swig_arg_error();
+        }
+      } else if ((strcmp(argv[i], "-proxy") == 0)) {
+        proxy_flag = 1;
+        Swig_mark_arg(i);
+      } else if (strcmp(argv[i], "-keyword") == 0) {
+        use_kw = 1;
+        Swig_mark_arg(i);
+      } else if (strcmp(argv[i], "-help") == 0) {
+        fputs(usage, stderr);
       }
+      ...
+    }
   }
 }
 </pre>
@@ -3164,7 +3164,7 @@
 </p>
 
 <dt> <b>Examples/Makefile.in</b>
-<dd> Nothing special here; see comments at top the of this file
+<dd> Nothing special here; see comments at the top of this file
 and look to the existing languages for examples.
 
 <dt> <b>Examples/qux99/check.list</b>
diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html
index f25e985..820921b 100644
--- a/Doc/Manual/Go.html
+++ b/Doc/Manual/Go.html
@@ -639,12 +639,12 @@
   virtual ~FooBarAbstract() {};
 
   std::string FooBar() {
-          return this->Foo() + ", " + this->Bar();
+    return this-&gt;Foo() + ", " + this-&gt;Bar();
   };
 
 protected:
   virtual std::string Foo() {
-          return "Foo";
+    return "Foo";
   };
 
   virtual std::string Bar() = 0;
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html
index e017846..85757d1 100644
--- a/Doc/Manual/Java.html
+++ b/Doc/Manual/Java.html
@@ -3935,9 +3935,9 @@
 
 <div class="code">
 <pre>
-    static void raise(JNIEnv *jenv, jthrowable throwable) {
-      throw DirectorException(jenv, throwable);
-    }
+  static void raise(JNIEnv *jenv, jthrowable throwable) {
+    throw DirectorException(jenv, throwable);
+  }
 </pre>
 </div>
 
@@ -4105,7 +4105,7 @@
 </p>
 
 <p>Note that the "directorthrows" typemaps are important
-only if it is important for the the exceptions passed through the C++
+only if it is important for the exceptions passed through the C++
 layer to be mapped to distinct C++ exceptions.  If director methods
 are being called by C++ code that is itself wrapped in a
 SWIG generated Java wrapper and access is always through this wrapper,
@@ -4335,16 +4335,16 @@
 
 %extend Vector {
   char *toString() {
-      static char tmp[1024];
-      sprintf(tmp, "Vector(%g, %g, %g)", $self-&gt;x, $self-&gt;y, $self-&gt;z);
-      return tmp;
+    static char tmp[1024];
+    sprintf(tmp, "Vector(%g, %g, %g)", $self-&gt;x, $self-&gt;y, $self-&gt;z);
+    return tmp;
   }
   Vector(double x, double y, double z) {
-      Vector *v = (Vector *) malloc(sizeof(Vector));
-      v-&gt;x = x;
-      v-&gt;y = y;
-      v-&gt;z = z;
-      return v;
+    Vector *v = (Vector *) malloc(sizeof(Vector));
+    v-&gt;x = x;
+    v-&gt;y = y;
+    v-&gt;z = z;
+    return v;
   }
 };
 </pre>
@@ -5278,7 +5278,7 @@
       throw bad_alloc();
     pJalloc-&gt;ref = 0;
     return static_cast&lt;void *&gt;(
-        static_cast&lt;char *&gt;(static_cast&lt;void *&gt;(pJalloc)) + sizeof(Jalloc));
+      static_cast&lt;char *&gt;(static_cast&lt;void *&gt;(pJalloc)) + sizeof(Jalloc));
   }
 }
 
@@ -7240,7 +7240,7 @@
     example.print_args(animals);
     String args[] = example.get_args();
     for (int i=0; i&lt;args.length; i++)
-        System.out.println(i + ":" + args[i]);
+      System.out.println(i + ":" + args[i]);
   }
 }
 </pre></div>
diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html
index a800c2d..8939c8d 100644
--- a/Doc/Manual/Library.html
+++ b/Doc/Manual/Library.html
@@ -12,26 +12,32 @@
 <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>
+<li><a href="#Library_nn3">C arrays and pointers</a>
 <ul>
 <li><a href="#Library_nn4">cpointer.i</a>
 <li><a href="#Library_carrays">carrays.i</a>
 <li><a href="#Library_nn6">cmalloc.i</a>
 <li><a href="#Library_nn7">cdata.i</a>
 </ul>
-<li><a href="#Library_nn8">C String Handling</a>
+<li><a href="#Library_nn8">C string handling</a>
 <ul>
 <li><a href="#Library_nn9">Default string handling</a>
 <li><a href="#Library_nn10">Passing binary data</a>
 <li><a href="#Library_nn11">Using %newobject to release memory</a>
 <li><a href="#Library_nn12">cstring.i</a>
 </ul>
-<li><a href="#Library_stl_cpp_library">STL/C++ Library</a>
+<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_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>
+<ul>
+<li><a href="#Library_shared_ptr_basics">shared_ptr basics</a>
+<li><a href="#Library_shared_ptr_inheritance">shared_ptr and inheritance</a>
+<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_auto_ptr">auto_ptr smart pointer</a>
 </ul>
 <li><a href="#Library_nn16">Utility Libraries</a>
@@ -92,7 +98,7 @@
 The directories that are searched are displayed when using <tt>-verbose</tt> commandline option.
 </p>
 
-<H2><a name="Library_nn3">9.2 C Arrays and Pointers</a></H2>
+<H2><a name="Library_nn3">9.2 C arrays and pointers</a></H2>
 
 
 <p>
@@ -411,7 +417,7 @@
 Now, in a scripting language, you might write this:
 </p>
 
-<div class="code">
+<div class="targetlang">
 <pre>
 a = new_doubleArray(10)             # Create an array
 for i in range(0, 10):
@@ -475,7 +481,7 @@
 Allows you to do this:
 </p>
 
-<div class="code">
+<div class="targetlang">
 <pre>
 import example
 c = example.doubleArray(10)  # Create double[10]
@@ -761,7 +767,7 @@
 Clearly they are unsafe.
 </p>
 
-<H2><a name="Library_nn8">9.3 C String Handling</a></H2>
+<H2><a name="Library_nn8">9.3 C string handling</a></H2>
 
 
 <p>
@@ -801,7 +807,7 @@
 and you wrote this,
 </p>
 
-<div class="code">
+<div class="targetlang">
 <pre>
 % foo Hello
 </pre>
@@ -852,7 +858,7 @@
 Now, in the target language, you can use binary string data like this:
 </p>
 
-<div class="code">
+<div class="targetlang">
 <pre>
 &gt;&gt;&gt; s = "H\x00\x15eg\x09\x20"
 &gt;&gt;&gt; parity(s, 0)
@@ -1365,7 +1371,7 @@
 </li>
 </ul>
 
-<H2><a name="Library_stl_cpp_library">9.4 STL/C++ Library</a></H2>
+<H2><a name="Library_stl_cpp_library">9.4 STL/C++ library</a></H2>
 
 
 <p>
@@ -1728,6 +1734,9 @@
 <H3><a name="Library_std_shared_ptr">9.4.4 shared_ptr smart pointer</a></H3>
 
 
+<H4><a name="Library_shared_ptr_basics">9.4.4.1 shared_ptr basics</a></H4>
+
+
 <p>
 Some target languages have support for handling the shared_ptr reference counted smart pointer.
 This smart pointer is available in the standard C++11 library as <tt>std::shared_ptr</tt>.
@@ -1821,8 +1830,11 @@
 </pre>
 </div>
 
+<H4><a name="Library_shared_ptr_inheritance">9.4.4.2 shared_ptr and inheritance</a></H4>
+
+
 <p>
-This shared_ptr library works quite differently to SWIG's normal, but somewhat limited, 
+The shared_ptr library works quite differently to SWIG's normal, but somewhat limited, 
 <a href="SWIGPlus.html#SWIGPlus_smart_pointers">smart pointer handling</a>.
 The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class.
 The normal proxy class including inheritance relationships is generated as usual.
@@ -1900,7 +1912,7 @@
 
 <div class="code">
 <pre>
-%include "boost_shared_ptr.i"
+%include &lt;boost_shared_ptr.i&gt;
 %shared_ptr(GrandParent);
 %shared_ptr(Parent);
 %shared_ptr(Child);
@@ -1909,8 +1921,52 @@
 </pre>
 </div>
 
+<H4><a name="Library_shared_ptr_templates">9.4.4.3 shared_ptr and templates</a></H4>
+
 <p>
-<b>Note:</b> There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
+The <tt>%shared_ptr</tt> macro should be used for all the required instantiations
+of the template before each of the <tt>%template</tt> instantiations.
+For example, consider <tt>number.h</tt> containing the following illustrative template:
+</p>
+
+<div class="code">
+<pre>
+#include &lt;memory&gt;
+
+template&lt;int N&gt; struct Number {
+  int num;
+  Number() : num(N) {}
+  static std::shared_ptr&lt;Number&lt;N&gt;&gt; make() { return std::make_shared&lt;Number&lt;N&gt;&gt;(); }
+};
+</pre>
+</div>
+
+<p>
+The SWIG code below shows the required ordering:
+</p>
+
+<div class="code">
+<pre>
+%include &lt;std_shared_ptr.i&gt;
+
+%shared_ptr(Number&lt;10&gt;);
+%shared_ptr(Number&lt;42&gt;);
+
+%{
+  #include "number.h"
+%}
+%include "number.h"
+
+%template(Number10) Number&lt;10&gt;;
+%template(Number42) Number&lt;42&gt;;
+</pre>
+</div>
+
+<H4><a name="Library_shared_ptr_directors">9.4.4.4 shared_ptr and directors</a></H4>
+
+
+<p>
+There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
 and the degrees of success varies among the different target languages.
 Please help to improve this support by providing patches with improvements.
 </p>
diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html
index c94fe31..c5c9442 100644
--- a/Doc/Manual/Lua.html
+++ b/Doc/Manual/Lua.html
@@ -1008,11 +1008,10 @@
 <p>
 SWIG also accepts the <tt>__str__()</tt> member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the <tt>print()</tt> and <tt>tostring()</tt> functions in Lua. Assuming the complex class has a function
 </p>
-<div class="code"><pre>const char* __str__()
-{
-        static char buffer[255];
-        sprintf(buffer, "Complex(%g, %g)", this-&gt;re(), this-&gt;im());
-        return buffer;
+<div class="code"><pre>const char* __str__() {
+  static char buffer[255];
+  sprintf(buffer, "Complex(%g, %g)", this-&gt;re(), this-&gt;im());
+  return buffer;
 }
 </pre></div>
 <p>
@@ -1031,11 +1030,10 @@
 <p>
 It is also possible to overload the operator<tt>[]</tt>, but currently this cannot be automatically performed. To overload the operator<tt>[]</tt> you need to provide two functions, <tt>__getitem__()</tt> and <tt>__setitem__()</tt>
 </p>
-<div class="code"><pre>class Complex
-{
-        //....
-        double __getitem__(int i)const; // i is the index, returns the data
-        void __setitem__(int i, double d); // i is the index, d is the data
+<div class="code"><pre>class Complex {
+  //....
+  double __getitem__(int i)const; // i is the index, returns the data
+  void __setitem__(int i, double d); // i is the index, d is the data
 };
 </pre></div>
 <p>
diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html
index 96e9f75..8ea43ad 100644
--- a/Doc/Manual/Perl5.html
+++ b/Doc/Manual/Perl5.html
@@ -949,7 +949,7 @@
 }
 
 Foo *IncrFoo(Foo *f, int i) {
-    return f+i;
+  return f+i;
 }
 %}
 </pre>
@@ -1057,7 +1057,7 @@
 <div class="code">
 <pre>
 int *Foo_x_get(Foo *self) {
-    return self-&gt;x;
+  return self-&gt;x;
 };
 </pre>
 </div>
@@ -1092,11 +1092,11 @@
 <div class="code">
 <pre>
 Foo *Bar_f_get(Bar *b) {
-    return &amp;b-&gt;f;
+  return &amp;b-&gt;f;
 }
 
 void Bar_f_set(Bar *b, Foo *val) {
-    b-&gt;f = *val;
+  b-&gt;f = *val;
 }
 </pre>
 </div>
@@ -1633,9 +1633,8 @@
     void setitem(int i, double val) {
       if ((i &gt;= 0) &amp;&amp; (i &lt; n))
         ptr[i] = val;
-      else {
+      else
         throw RangeError();
-      }
     }
   };
 </pre></div>
@@ -1888,9 +1887,9 @@
 <div class="targetlang">
 <pre>
 %typemap(out) int {
-    $result = sv_newmortal();
-    set_setiv($result, (IV) $1);
-    argvi++;
+  $result = sv_newmortal();
+  set_setiv($result, (IV) $1);
+  argvi++;
 }
 </pre>
 </div>
@@ -2313,8 +2312,8 @@
 <div class="code"><pre>
 #define SIZE  8
 typedef struct {
-    int   values[SIZE];
-    ...
+  int   values[SIZE];
+  ...
 } Foo;
 
 </pre></div>
@@ -2328,10 +2327,10 @@
 
 <div class="code"><pre>
 %typemap(memberin) int [SIZE] {
-    int i;
-    for (i = 0; i &lt; SIZE; i++) {
-        $1[i] = $input[i];
-    }
+  int i;
+  for (i = 0; i &lt; SIZE; i++) {
+    $1[i] = $input[i];
+  }
 }
 
 </pre></div>
@@ -2600,48 +2599,48 @@
 %BLESSEDMEMBERS = ();
 
 sub new () {
-    my $self = shift;
-    my @args = @_;
-    $self = vectorc::new_Vector(@args);
-    return undef if (!defined($self));
-    bless $self, "example::Vector";
-    $OWNER{$self} = 1;
-    my %retval;
-    tie %retval, "example::Vector", $self;
-    return bless \%retval, "Vector";
+  my $self = shift;
+  my @args = @_;
+  $self = vectorc::new_Vector(@args);
+  return undef if (!defined($self));
+  bless $self, "example::Vector";
+  $OWNER{$self} = 1;
+  my %retval;
+  tie %retval, "example::Vector", $self;
+  return bless \%retval, "Vector";
 }
 
 sub DESTROY {
-    return unless $_[0]-&gt;isa('HASH');
-    my $self = tied(%{$_[0]});
-    delete $ITERATORS{$self};
-    if (exists $OWNER{$self}) {
-        examplec::delete_Vector($self));
-        delete $OWNER{$self};
-    }
+  return unless $_[0]-&gt;isa('HASH');
+  my $self = tied(%{$_[0]});
+  delete $ITERATORS{$self};
+  if (exists $OWNER{$self}) {
+    examplec::delete_Vector($self));
+    delete $OWNER{$self};
+  }
 }
 
 sub FETCH {
-    my ($self, $field) = @_;
-    my $member_func = "vectorc::Vector_${field}_get";
-    my $val = &amp;$member_func($self);
-    if (exists $BLESSEDMEMBERS{$field}) {
-        return undef if (!defined($val));
-        my %retval;
-        tie %retval, $BLESSEDMEMBERS{$field}, $val;
-        return bless \%retval, $BLESSEDMEMBERS{$field};
-    }
-    return $val;
+  my ($self, $field) = @_;
+  my $member_func = "vectorc::Vector_${field}_get";
+  my $val = &amp;$member_func($self);
+  if (exists $BLESSEDMEMBERS{$field}) {
+    return undef if (!defined($val));
+    my %retval;
+    tie %retval, $BLESSEDMEMBERS{$field}, $val;
+    return bless \%retval, $BLESSEDMEMBERS{$field};
+  }
+  return $val;
 }
 
 sub STORE {
-    my ($self, $field, $newval) = @_;
-    my $member_func = "vectorc::Vector_${field}_set";
-    if (exists $BLESSEDMEMBERS{$field}) {
-        &amp;$member_func($self, tied(%{$newval}));
-    } else {
-        &amp;$member_func($self, $newval);
-    }
+  my ($self, $field, $newval) = @_;
+  my $member_func = "vectorc::Vector_${field}_set";
+  if (exists $BLESSEDMEMBERS{$field}) {
+    &amp;$member_func($self, tied(%{$newval}));
+  } else {
+    &amp;$member_func($self, $newval);
+  }
 }
 </pre></div>
 
@@ -2842,11 +2841,11 @@
 
 <div class="targetlang"><pre>
 sub dot_product {
-    my @args = @_;
-    $args[0] = tied(%{$args[0]});         # Get the real pointer values
-    $args[1] = tied(%{$args[1]});
-    my $result = vectorc::dot_product(@args);
-    return $result;
+  my @args = @_;
+  $args[0] = tied(%{$args[0]});         # Get the real pointer values
+  $args[1] = tied(%{$args[1]});
+  my $result = vectorc::dot_product(@args);
+  return $result;
 }
 </pre></div>
 
@@ -2985,7 +2984,7 @@
     for (my $j = 0; $j &lt; 4, $j++)
     {
       mat44_set($a, $i, $j, $x-&gt;[i][j])
-      }
+    }
   }
   example.set_transform($im, $a);
   free_mat44($a);
@@ -3104,14 +3103,14 @@
 %feature("director") Foo;
 class Foo {
 public:
-    Foo(int foo);
-    virtual void one();
-    virtual void two();
+  Foo(int foo);
+  virtual void one();
+  virtual void two();
 };
 
 class Bar: public Foo {
 public:
-    virtual void three();
+  virtual void three();
 };
 </pre>
 </div>
@@ -3279,9 +3278,9 @@
 <div class="code">
 <pre>
 %feature("director:except") {
-    if ($error != NULL) {
-        throw Swig::DirectorMethodException();
-    }
+  if ($error != NULL) {
+    throw Swig::DirectorMethodException();
+  }
 }
 </pre>
 </div>
@@ -3305,8 +3304,8 @@
 <div class="code">
 <pre>
 %exception {
-    try { $action }
-    catch (Swig::DirectorException &amp;e) { SWIG_fail; }
+  try { $action }
+  catch (Swig::DirectorException &amp;e) { SWIG_fail; }
 }
 </pre>
 </div>
diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html
index 7d3d33a..9fbfd75 100644
--- a/Doc/Manual/Php.html
+++ b/Doc/Manual/Php.html
@@ -163,7 +163,7 @@
 <p>
 For some SAPIs (for example, the CLI SAPI) you can instead use the
 <a href="http://php.net/manual/en/function.dl.php">dl() function</a> to load
-an extension at run time, by adding a like like this to the start of each
+an extension at run time, by adding a line like this to the start of each
 PHP script which uses your extension:
 </p>
 
@@ -390,8 +390,7 @@
 will generate dispatch functions which will use <tt>%typecheck</tt>
 typemaps to allow overloading.  This dispatch function's operation and
 precedence is described in <a
-href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping
-Overloaded Functions and Methods</a>.
+href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>.
 </p>
 
 <!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
@@ -986,14 +985,14 @@
 %feature("director") Foo;
 class Foo {
 public:
-    Foo(int foo);
-    virtual void one();
-    virtual void two();
+  Foo(int foo);
+  virtual void one();
+  virtual void two();
 };
 
 class Bar: public Foo {
 public:
-    virtual void three();
+  virtual void three();
 };
 </pre>
 </div>
@@ -1125,12 +1124,12 @@
 <pre>
 class Foo {
 public:
-    ...
+  ...
 };
 class FooContainer {
 public:
-    void addFoo(Foo *);
-    ...
+  void addFoo(Foo *);
+  ...
 };
 </pre>
 </div>
@@ -1175,9 +1174,9 @@
 <div class="code">
 <pre>
 %feature("director:except") {
-    if ($error == FAILURE) {
-        throw Swig::DirectorMethodException();
-    }
+  if ($error == FAILURE) {
+    throw Swig::DirectorMethodException();
+  }
 }
 </pre>
 </div>
@@ -1204,8 +1203,8 @@
 <div class="code">
 <pre>
 %exception {
-    try { $action }
-    catch (Swig::DirectorException &amp;e) { SWIG_fail; }
+  try { $action }
+  catch (Swig::DirectorException &amp;e) { SWIG_fail; }
 }
 </pre>
 </div>
diff --git a/Doc/Manual/Pike.html b/Doc/Manual/Pike.html
index 22ab4e2..a8bc0d4 100644
--- a/Doc/Manual/Pike.html
+++ b/Doc/Manual/Pike.html
@@ -230,8 +230,8 @@
 class Shape
 {
 public:
-    static void print();
-    static int nshapes;
+  static void print();
+  static int nshapes;
 };
 </pre></div>
 
diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html
index 9b3afbd..0c0023d 100644
--- a/Doc/Manual/Python.html
+++ b/Doc/Manual/Python.html
@@ -226,16 +226,15 @@
 #include "example.h"
 
 int fact(int n) {
-    if (n &lt; 0){ /* This should probably return an error, but this is simpler */
-        return 0;
-    }
-    if (n == 0) {
-        return 1;
-    }
-    else {
-        /* testing for overflow would be a good idea here */
-        return n * fact(n-1);
-    }
+  if (n &lt; 0) { /* This should probably return an error, but this is simpler */
+    return 0;
+  }
+  if (n == 0) {
+    return 1;
+  } else {
+    /* testing for overflow would be a good idea here */
+    return n * fact(n-1);
+  }
 }
 
 </pre>
@@ -1276,7 +1275,7 @@
 }
 
 Foo *IncrFoo(Foo *f, int i) {
-    return f+i;
+  return f+i;
 }
 %}
 </pre>
@@ -1386,7 +1385,7 @@
 <div class="code">
 <pre>
 struct Bar {
-    int  x[16];
+  int  x[16];
 };
 </pre>
 </div>
@@ -1716,9 +1715,9 @@
 <pre>
 class Foo {
 public:
-    Foo();
-    Foo(const Foo &amp;);
-    ...
+  Foo();
+  Foo(const Foo &amp;);
+  ...
 };
 </pre>
 </div>
@@ -1894,6 +1893,14 @@
 overloaded assignment operators don't map to Python semantics and will be ignored.
 </p>
 
+<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 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">36.3.12 C++ namespaces</a></H3>
 
 
@@ -1943,11 +1950,11 @@
 %rename(Bar_spam) Bar::spam;
 
 namespace Foo {
-    int spam();
+  int spam();
 }
 
 namespace Bar {
-    int spam();
+  int spam();
 }
 </pre>
 </div>
@@ -2158,9 +2165,9 @@
 <pre>
 class Foo {
 public:
-    int x;
-    int spam(int);
-    ...
+  int x;
+  int spam(int);
+  ...
 </pre>
 </div>
 
@@ -2171,19 +2178,19 @@
 <div class="code">
 <pre>
 Foo *new_Foo() {
-    return new Foo();
+  return new Foo();
 }
 void delete_Foo(Foo *f) {
-    delete f;
+  delete f;
 }
 int Foo_x_get(Foo *f) {
-    return f-&gt;x;
+  return f-&gt;x;
 }
 void Foo_x_set(Foo *f, int value) {
-    f-&gt;x = value;
+  f-&gt;x = value;
 }
 int Foo_spam(Foo *f, int arg1) {
-    return f-&gt;spam(arg1);
+  return f-&gt;spam(arg1);
 }
 </pre>
 </div>
@@ -2302,10 +2309,10 @@
 <div class="code">
 <pre>
 typedef struct {
-    PyObject_HEAD
-    PyObject *dict;
-    PyObject *args;
-    PyObject *message;
+  PyObject_HEAD
+  PyObject *dict;
+  PyObject *args;
+  PyObject *message;
 } PyBaseExceptionObject;
 </pre>
 </div>
@@ -2315,12 +2322,12 @@
 <div class="code">
 <pre>
 typedef struct {
-    PyObject_HEAD
-    void *ptr;
-    swig_type_info *ty;
-    int own;
-    PyObject *next;
-    PyObject *dict;
+  PyObject_HEAD
+  void *ptr;
+  swig_type_info *ty;
+  int own;
+  PyObject *next;
+  PyObject *dict;
 } SwigPyObject;
 </pre>
 </div>
@@ -2331,13 +2338,13 @@
 <pre>
 class MyException {
 public:
-    MyException (const char *msg_);
-    ~MyException ();
+  MyException (const char *msg_);
+  ~MyException ();
 
-    const char *what () const;
+  const char *what () const;
 
 private:
-    char *msg;
+  char *msg;
 };
 </pre>
 </div>
@@ -2364,9 +2371,9 @@
 <pre>
 class MyString {
 public:
-    MyString (const char *init);
-    MyString operator+ (const char *other) const;
-    ...
+  MyString (const char *init);
+  MyString operator+ (const char *other) const;
+  ...
 };
 </pre>
 </div>
@@ -2465,11 +2472,12 @@
 <pre>
 class Twit {
 public:
-    Twit operator+ (const Twit&amp; twit) const;
+  Twit operator+ (const Twit&amp; twit) const;
 
-    // Forward to operator+
-    Twit add (const Twit&amp; twit) const
-    { return *this + twit; }
+  // Forward to operator+
+  Twit add (const Twit&amp; twit) const {
+    return *this + twit;
+  }
 };
 </pre>
 </div>
@@ -2557,9 +2565,9 @@
 <div class="code">
 <pre>
 static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
-    ...
-    (hashfunc) myHashFunc,       /* tp_hash */
-    ...
+  ...
+  (hashfunc) myHashFunc,       /* tp_hash */
+  ...
 </pre>
 </div>
 
@@ -2628,8 +2636,8 @@
 <pre>
 class Foo {
 public:
-    Foo();
-    Foo bar();
+  Foo();
+  Foo bar();
 };
 </pre>
 </div>
@@ -2658,9 +2666,9 @@
 <pre>
 class Foo {
 public:
-    ...
-    Foo *spam();
-    ...
+  ...
+  Foo *spam();
+  ...
 };
 </pre>
 </div>
@@ -2699,8 +2707,8 @@
 %module example
 
 struct Foo {
-    int  value;
-    Foo  *next;
+  int  value;
+  Foo  *next;
 };
 
 Foo *head = 0;
@@ -2931,15 +2939,15 @@
 %feature("director") Foo;
 class Foo {
 public:
-    Foo(int foo);
-    virtual ~Foo();
-    virtual void one();
-    virtual void two();
+  Foo(int foo);
+  virtual ~Foo();
+  virtual void one();
+  virtual void two();
 };
 
 class Bar: public Foo {
 public:
-    virtual void three();
+  virtual void three();
 };
 </pre>
 </div>
@@ -3079,12 +3087,12 @@
 <pre>
 class Foo {
 public:
-    ...
+  ...
 };
 class FooContainer {
 public:
-    void addFoo(Foo *);
-    ...
+  void addFoo(Foo *);
+  ...
 };
 </pre>
 </div>
@@ -3125,9 +3133,9 @@
 <div class="code">
 <pre>
 %feature("director:except") {
-    if ($error != NULL) {
-        throw Swig::DirectorMethodException();
-    }
+  if ($error != NULL) {
+    throw Swig::DirectorMethodException();
+  }
 }
 </pre>
 </div>
@@ -3154,8 +3162,8 @@
 <div class="code">
 <pre>
 %exception {
-    try { $action }
-    catch (Swig::DirectorException &amp;e) { SWIG_fail; }
+  try { $action }
+  catch (Swig::DirectorException &amp;e) { SWIG_fail; }
 }
 </pre>
 </div>
@@ -3232,7 +3240,7 @@
 <pre>
 class Foo {
 &hellip;
-    virtual const int&amp; bar();
+  virtual const int&amp; bar();
 &hellip;
 };
 </pre>
@@ -3250,7 +3258,7 @@
 <pre>
 class Foo {
 &hellip;
-    virtual int bar();
+  virtual int bar();
 &hellip;
 };
 </pre>
@@ -3503,7 +3511,7 @@
 
 class Foo {
 public:
-    int bar(int x);
+  int bar(int x);
 };
 </pre>
 </div>
@@ -3540,7 +3548,7 @@
 
 class Foo {
 public:
-    int bar(int x);
+  int bar(int x);
 };
 </pre>
 </div>
@@ -3569,7 +3577,7 @@
 
 class Foo {
 public:
-    int bar(int x);
+  int bar(int x);
 };
 </pre>
 </div>
@@ -3598,8 +3606,8 @@
 
 class Foo {
 public:
-    int bar(int x);
-    int bar();
+  int bar(int x);
+  int bar();
 };
 </pre>
 </div>
@@ -4134,11 +4142,11 @@
 <div class="code">
 <pre>
 int sumitems(int *first, int nitems) {
-    int i, sum = 0;
-    for (i = 0; i &lt; nitems; i++) {
-        sum += first[i];
-    }
-    return sum;
+  int i, sum = 0;
+  for (i = 0; i &lt; nitems; i++) {
+    sum += first[i];
+  }
+  return sum;
 }
 </pre>
 </div>
@@ -6038,7 +6046,7 @@
 
 <p>
 When SWIG creates wrappers from an interface file, say foo.i, two Python modules are
-created.  There is a pure Python module module (foo.py) and C/C++ code which is
+created.  There is a pure Python module (foo.py) and C/C++ code which is
 built and linked into a dynamically (or statically) loaded low-level module _foo
 (see the <a href="Python.html#Python_nn3">Preliminaries section</a> for details).  So, the interface
 file really defines two Python modules.   How these two modules are loaded is
@@ -6518,7 +6526,7 @@
 %inline %{
 
 const char* non_utf8_c_str(void) {
-        return "h\xe9llo w\xc3\xb6rld";
+  return "h\xe9llo w\xc3\xb6rld";
 }
 
 %}
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index e5b441f..d677a22 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -389,7 +389,7 @@
 /* bar not wrapped unless foo has been defined and 
    the declaration of bar within foo has already been parsed */
 int foo::bar(int) {
-    ... whatever ...
+  ... whatever ...
 }
 </pre>
 </div>
@@ -1043,14 +1043,14 @@
 <div class="targetlang"><pre>
 # Copy a file 
 def filecopy(source, target):
-  f1 = fopen(source, "r")
-  f2 = fopen(target, "w")
-  buffer = malloc(8192)
-  nbytes = fread(buffer, 8192, 1, f1)
-  while (nbytes &gt; 0):
-    fwrite(buffer, 8192, 1, f2)
-          nbytes = fread(buffer, 8192, 1, f1)
-  free(buffer)
+    f1 = fopen(source, "r")
+    f2 = fopen(target, "w")
+    buffer = malloc(8192)
+    nbytes = fread(buffer, 8192, 1, f1)
+    while (nbytes &gt; 0):
+        fwrite(buffer, 8192, 1, f2)
+            nbytes = fread(buffer, 8192, 1, f1)
+    free(buffer)
 </pre></div>
 
 <p>
@@ -1236,9 +1236,9 @@
 
 <div class="code"><pre>
 double wrap_dot_product(Vector *a, Vector *b) {
-    Vector x = *a;
-    Vector y = *b;
-    return dot_product(x, y);
+  Vector x = *a;
+  Vector y = *b;
+  return dot_product(x, y);
 }
 </pre></div>
 
@@ -1266,12 +1266,12 @@
 
 <div class="code"><pre>
 Vector *wrap_cross_product(Vector *v1, Vector *v2) {
-        Vector x = *v1;
-        Vector y = *v2;
-        Vector *result;
-        result = (Vector *) malloc(sizeof(Vector));
-        *(result) = cross(x, y);
-        return result;
+  Vector x = *v1;
+  Vector y = *v2;
+  Vector *result;
+  result = (Vector *) malloc(sizeof(Vector));
+  *(result) = cross(x, y);
+  return result;
 }
 </pre></div>
 
@@ -1280,10 +1280,10 @@
 
 <div class="code"><pre>
 Vector *wrap_cross(Vector *v1, Vector *v2) {
-        Vector x = *v1;
-        Vector y = *v2;
-        Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
-        return result;
+  Vector x = *v1;
+  Vector y = *v2;
+  Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
+  return result;
 }
 </pre></div>
 
@@ -1737,6 +1737,16 @@
 avoid these problems.</p>
 
 <p>
+When wrapping C code, simple use of identifiers/symbols with <tt>%rename</tt> usually suffices.
+When wrapping C++ code, simple use of simple identifiers/symbols with <tt>%rename</tt> might be too
+limiting when using C++ features such as function overloading, default arguments, namespaces, template specialization etc.
+If you are using the <tt>%rename</tt> directive and C++, make sure you read the
+<a href="SWIGPlus.html">SWIG and C++</a> chapter and in particular the section on
+<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
+for method overloading and default arguments.
+</p>
+
+<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:
 </p>
@@ -2078,7 +2088,7 @@
 <p>
 Finally, variants of <tt>%rename</tt> and <tt>%ignore</tt> directives can be used to help
 wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the
-<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section in the C++ chapter.
+<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a> section in the C++ chapter.
 </p>
 
 
@@ -2368,10 +2378,10 @@
 
 <div class="code"><pre>
 struct Vector *new_Vector() {
-    return (Vector *) calloc(1, sizeof(struct Vector));
+  return (Vector *) calloc(1, sizeof(struct Vector));
 }
 void delete_Vector(struct Vector *obj) {
-    free(obj);
+  free(obj);
 }
 </pre>
 </div>
@@ -2602,10 +2612,10 @@
 <div class="code">
 <pre>
 WORD Foo_w_get(Foo *f) {
-    return f-&gt;w;
+  return f-&gt;w;
 }
 void Foo_w_set(FOO *f, WORD value) {
-    f-&gt;w = value;
+  f-&gt;w = value;
 }
 </pre>
 </div>
@@ -2896,7 +2906,7 @@
 <pre>
 // Add a new attribute to Vector
 %extend Vector {
-    const double magnitude;
+  const double magnitude;
 }
 // Now supply the implementation of the Vector_magnitude_get function
 %{
@@ -3293,11 +3303,27 @@
   return (Vector *) malloc(sizeof(Vector));
 }
 %}
-
 </pre></div>
 
 <p>
-The <tt>%inline</tt> directive inserts all of the code that follows
+This is the same as writing:
+</p>
+
+<div class="code"><pre>
+%{
+/* Create a new vector */
+Vector *new_Vector() {
+  return (Vector *) malloc(sizeof(Vector));
+}
+%}
+
+/* Create a new vector */
+Vector *new_Vector() {
+  return (Vector *) malloc(sizeof(Vector));
+}
+</pre></div>
+<p>
+In other words, the <tt>%inline</tt> directive inserts all of the code that follows
 verbatim into the header portion of an interface file. The code is
 then parsed by both the SWIG preprocessor and parser.
 Thus, the above example creates a new command <tt>new_Vector</tt> using only one
@@ -3305,6 +3331,11 @@
 is given to both the C compiler and SWIG, it is illegal to include any
 SWIG directives inside a <tt>%{ ... %}</tt> block.</p>
 
+
+<p>
+<b>Note:</b> The usual SWIG C preprocessor rules apply to code in <tt>%apply</tt> blocks when SWIG parses this code. For example, as mentioned earlier, <a href="SWIG.html#SWIG_nn6">SWIG's C Preprocessor</a> does not follow <tt>#include</tt> directives by default.
+</p>
+
 <H3><a name="SWIG_nn44">5.6.4 Initialization blocks</a></H3>
 
 
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index 3e7860b..18059b4 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -31,7 +31,6 @@
 <li><a href="#SWIGPlus_nn12">Static members</a>
 <li><a href="#SWIGPlus_member_data">Member data</a>
 </ul>
-<li><a href="#SWIGPlus_default_args">Default arguments</a>
 <li><a href="#SWIGPlus_nn15">Protection</a>
 <li><a href="#SWIGPlus_nn16">Enums and constants</a>
 <li><a href="#SWIGPlus_nn17">Friends</a>
@@ -39,16 +38,27 @@
 <li><a href="#SWIGPlus_nn19">Pass and return by value</a>
 <li><a href="#SWIGPlus_nn20">Inheritance</a>
 <li><a href="#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers,  and type checking</a>
-<li><a href="#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a>
+<li><a href="#SWIGPlus_default_args">Default arguments</a>
+<li><a href="#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>
 <ul>
 <li><a href="#SWIGPlus_nn24">Dispatch function generation</a>
-<li><a href="#SWIGPlus_nn25">Ambiguity in Overloading</a>
-<li><a href="#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
+<li><a href="#SWIGPlus_nn25">Ambiguity in overloading</a>
+<li><a href="#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a>
 <li><a href="#SWIGPlus_nn27">Comments on overloading</a>
 </ul>
-<li><a href="#SWIGPlus_nn28">Wrapping overloaded operators</a>
+<li><a href="#SWIGPlus_nn28">Overloaded operators</a>
 <li><a href="#SWIGPlus_class_extension">Class extension</a>
 <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_specialization">Template specialization</a>
+<li><a href="#SWIGPlus_template_member">Member templates</a>
+<li><a href="#SWIGPlus_template_scoping">Scoping and templates</a>
+<li><a href="#SWIGPlus_template_more">More on templates</a>
+</ul>
 <li><a href="#SWIGPlus_namespaces">Namespaces</a>
 <ul>
 <li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
@@ -346,8 +356,8 @@
 
 class Spam {
 public:
-      Foo *value;
-      ...
+  Foo *value;
+  ...
 };
 </pre>
 </div>
@@ -706,7 +716,7 @@
 protected:
   Foo();         // Not wrapped.
 public:
-    ...
+  ...
 };
 </pre>
 </div>
@@ -726,7 +736,7 @@
 
 class Grok : public Bar {
 public:
-      Grok();            // Not wrapped. No implementation of abstract spam().
+  Grok();              // Not wrapped. No implementation of abstract spam().
 };
 </pre>
 </div>
@@ -777,9 +787,9 @@
 <pre>
 class List {
 public:
-    List();    
-    List(const List &amp;);      // Copy constructor
-    ...
+  List();    
+  List(const List &amp;);      // Copy constructor
+  ...
 };
 </pre>
 </div>
@@ -803,7 +813,7 @@
 <div class="code">
 <pre>
 List *copy_List(List *f) {
-    return new List(*f);
+  return new List(*f);
 }
 </pre>
 </div>
@@ -832,7 +842,7 @@
 
 class List {
 public:
-    List();    
+  List();    
 };
 </pre>
 </div>
@@ -851,9 +861,9 @@
 <pre>
 class Foo {
 public:
-    Foo();
+  Foo();
   %name(CopyFoo) Foo(const Foo &amp;);
-    ...
+  ...
 };
 </pre>
 </div>
@@ -969,8 +979,8 @@
 <pre>
 class Foo {
 public:
-    List items;
-    ...
+  List items;
+  ...
 </pre>
 </div>
 
@@ -982,10 +992,10 @@
 <div class="code">
 <pre>
 List *Foo_items_get(Foo *self) {
-    return &amp;self-&gt;items;
+  return &amp;self-&gt;items;
 }
 void Foo_items_set(Foo *self, List *value) {
-    self-&gt;items = *value;
+  self-&gt;items = *value;
 }
 </pre>
 </div>
@@ -1007,10 +1017,10 @@
 <div class="code">
 <pre>
 const List &amp;Foo_items_get(Foo *self) {
-    return self-&gt;items;
+  return self-&gt;items;
 }
 void Foo_items_set(Foo *self, const List &amp;value) {
-    self-&gt;items = value;
+  self-&gt;items = value;
 }
 </pre>
 </div>
@@ -1094,113 +1104,7 @@
 customization features.
 </p>
 
-<H2><a name="SWIGPlus_default_args">6.7 Default arguments</a></H2>
-
-
-<p>
-SWIG will wrap all types of functions that have default arguments. For example member functions:
-</p>
-
-<div class="code">
-<pre>
-class Foo {
-public:
-    void bar(int x, int y = 3, int z = 4);
-};
-</pre>
-</div>
-
-<p>
-SWIG handles default arguments by generating an extra overloaded method for each defaulted argument.
-SWIG is effectively handling methods with default arguments as if it was wrapping the equivalent overloaded methods.
-Thus for the example above, it is as if we had instead given the following to SWIG:
-</p>
-
-<div class="code">
-<pre>
-class Foo {
-public:
-    void bar(int x, int y, int z);
-    void bar(int x, int y);
-    void bar(int x);
-};
-</pre>
-</div>
-
-<p>
-The wrappers produced are exactly the same as if the above code was instead fed into SWIG.
-Details of this are covered later in the <a href="#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a> section.
-This approach allows SWIG to wrap all possible default arguments, but can be verbose.
-For example if a method has ten default arguments, then eleven wrapper methods are generated.
-</p>
-
-<p>
-Please see the <a href="Customization.html#Customization_features_default_args">Features and default arguments</a>
-section for more information on using <tt>%feature</tt> with functions with default arguments.
-The <a href="#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section 
-also deals with using <tt>%rename</tt> and <tt>%ignore</tt> on methods with default arguments.
-If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a <tt>typecheck</tt> typemap.
-See the <a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a> section for details or otherwise
-use the <tt>compactdefaultargs</tt> feature flag as mentioned below.
-</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.
-If the size of the wrappers are a concern then this approach to wrapping methods with default arguments
-can be re-activated by using the <tt>compactdefaultargs</tt> 
-<a href="Customization.html#Customization_feature_flags">feature flag</a>.
-</p>
-
-<div class="code">
-<pre>
-%feature("compactdefaultargs") Foo::bar;
-class Foo {
-public:
-    void bar(int x, int y = 3, int z = 4);
-};
-</pre>
-</div>
-
-
-<p>
-This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages,
-such as C# and Java,
-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">
-<pre>
-class Foo {
-private:
-  static const int spam;
-public:
-  void bar(int x, int y = spam);   // Won't work with %feature("compactdefaultargs") -
-                                   // private default value
-};
-</pre>
-</div>
-
-<p>
-This produces uncompilable wrapper code because default values in C++ are
-evaluated in the same scope as the member function whereas SWIG
-evaluates them in the scope of a wrapper function (meaning that the
-values have to be public). 
-</p>
-
-<p>
-The <tt>compactdefaultargs</tt> feature is automatically turned on when wrapping <a href="SWIG.html#SWIG_default_args">C code with default arguments</a>.
-Some target languages will also automatically turn on this feature
-if the keyword arguments feature (kwargs) is specified for either C or C++ functions, and the target language supports kwargs,
-the <tt>compactdefaultargs</tt> feature is also automatically turned on.
-Keyword arguments are a language feature of some scripting languages, for example Ruby and Python.
-SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used.
-</p>
-
-<H2><a name="SWIGPlus_nn15">6.8 Protection</a></H2>
+<H2><a name="SWIGPlus_nn15">6.7 Protection</a></H2>
 
 
 <p>
@@ -1220,7 +1124,7 @@
 the same convention used by C++).
 </p>
 
-<H2><a name="SWIGPlus_nn16">6.9 Enums and constants</a></H2>
+<H2><a name="SWIGPlus_nn16">6.8 Enums and constants</a></H2>
 
 
 <p>
@@ -1250,7 +1154,7 @@
 Members declared as <tt>const</tt> are wrapped as read-only members and do not create constants.
 </p>
 
-<H2><a name="SWIGPlus_nn17">6.10 Friends</a></H2>
+<H2><a name="SWIGPlus_nn17">6.9 Friends</a></H2>
 
 
 <p>
@@ -1278,7 +1182,7 @@
 <pre>
 class Foo {
 public:
-    ...
+  ...
 };
 
 void blah(Foo *f);    
@@ -1311,7 +1215,7 @@
 and a wrapper for the method 'blah' will not be generated.
 </p>
 
-<H2><a name="SWIGPlus_nn18">6.11 References and pointers</a></H2>
+<H2><a name="SWIGPlus_nn18">6.10 References and pointers</a></H2>
 
 
 <p>
@@ -1411,7 +1315,7 @@
 </p>
 
 
-<H2><a name="SWIGPlus_nn19">6.12 Pass and return by value</a></H2>
+<H2><a name="SWIGPlus_nn19">6.11 Pass and return by value</a></H2>
 
 
 <p>
@@ -1485,8 +1389,8 @@
 
 %feature("valuewrapper") B;
 struct B { 
-    B();
-    // ....
+  B();
+  // ....
 };   
 </pre></div>
 
@@ -1515,7 +1419,7 @@
 It is not used for C++ pointers or references.
 </p>
 
-<H2><a name="SWIGPlus_nn20">6.13 Inheritance</a></H2>
+<H2><a name="SWIGPlus_nn20">6.12 Inheritance</a></H2>
 
 
 <p>
@@ -1701,7 +1605,7 @@
 class.
 </p>
 
-<H2><a name="SWIGPlus_nn21">6.14 A brief discussion of multiple inheritance, pointers,  and type checking</a></H2>
+<H2><a name="SWIGPlus_nn21">6.13 A brief discussion of multiple inheritance, pointers,  and type checking</a></H2>
 
 
 <p>
@@ -1833,7 +1737,113 @@
 In practice, the pointer is held as an integral number in the target language proxy class.
 </p>
 
-<H2><a name="SWIGPlus_overloaded_methods">6.15 Wrapping Overloaded Functions and Methods</a></H2>
+<H2><a name="SWIGPlus_default_args">6.14 Default arguments</a></H2>
+
+
+<p>
+SWIG will wrap all types of functions that have default arguments. For example member functions:
+</p>
+
+<div class="code">
+<pre>
+class Foo {
+public:
+  void bar(int x, int y = 3, int z = 4);
+};
+</pre>
+</div>
+
+<p>
+SWIG handles default arguments by generating an extra overloaded method for each defaulted argument.
+SWIG is effectively handling methods with default arguments as if it was wrapping the equivalent overloaded methods.
+Thus for the example above, it is as if we had instead given the following to SWIG:
+</p>
+
+<div class="code">
+<pre>
+class Foo {
+public:
+  void bar(int x, int y, int z);
+  void bar(int x, int y);
+  void bar(int x);
+};
+</pre>
+</div>
+
+<p>
+The wrappers produced are exactly the same as if the above code was instead fed into SWIG.
+Details of this are covered in the next section <a href="#SWIGPlus_overloaded_methods">Overloaded functions and methods</a>.
+This approach allows SWIG to wrap all possible default arguments, but can be verbose.
+For example if a method has ten default arguments, then eleven wrapper methods are generated.
+</p>
+
+<p>
+Please see the <a href="Customization.html#Customization_features_default_args">Features and default arguments</a>
+section for more information on using <tt>%feature</tt> with functions with default arguments.
+The <a href="#SWIGPlus_ambiguity_resolution_renaming">Renaming and ambiguity resolution</a> section 
+also deals with using <tt>%rename</tt> and <tt>%ignore</tt> on methods with default arguments.
+If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a <tt>typecheck</tt> typemap.
+See the <a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a> section for details or otherwise
+use the <tt>compactdefaultargs</tt> feature flag as mentioned below.
+</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.
+If the size of the wrappers are a concern then this approach to wrapping methods with default arguments
+can be re-activated by using the <tt>compactdefaultargs</tt> 
+<a href="Customization.html#Customization_feature_flags">feature flag</a>.
+</p>
+
+<div class="code">
+<pre>
+%feature("compactdefaultargs") Foo::bar;
+class Foo {
+public:
+  void bar(int x, int y = 3, int z = 4);
+};
+</pre>
+</div>
+
+
+<p>
+This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages,
+such as C# and Java,
+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">
+<pre>
+class Foo {
+private:
+  static const int spam;
+public:
+  void bar(int x, int y = spam);   // Won't work with %feature("compactdefaultargs") -
+                                   // private default value
+};
+</pre>
+</div>
+
+<p>
+This produces uncompilable wrapper code because default values in C++ are
+evaluated in the same scope as the member function whereas SWIG
+evaluates them in the scope of a wrapper function (meaning that the
+values have to be public). 
+</p>
+
+<p>
+The <tt>compactdefaultargs</tt> feature is automatically turned on when wrapping <a href="SWIG.html#SWIG_default_args">C code with default arguments</a>.
+Some target languages will also automatically turn on this feature
+if the keyword arguments feature (kwargs) is specified for either C or C++ functions, and the target language supports kwargs,
+the <tt>compactdefaultargs</tt> feature is also automatically turned on.
+Keyword arguments are a language feature of some scripting languages, for example Ruby and Python.
+SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used.
+</p>
+
+<H2><a name="SWIGPlus_overloaded_methods">6.15 Overloaded functions and methods</a></H2>
 
 
 <p>
@@ -2021,7 +2031,7 @@
 If you're still confused, don't worry about it---SWIG is probably doing the right thing.
 </p>
 
-<H3><a name="SWIGPlus_nn25">6.15.2 Ambiguity in Overloading</a></H3>
+<H3><a name="SWIGPlus_nn25">6.15.2 Ambiguity in overloading</a></H3>
 
 
 <p>
@@ -2139,7 +2149,7 @@
 functions and methods.  The only way to fix the problem is to read the next section.
 </p>
 
-<H3><a name="SWIGPlus_ambiguity_resolution_renaming">6.15.3 Ambiguity resolution and renaming</a></H3>
+<H3><a name="SWIGPlus_ambiguity_resolution_renaming">6.15.3 Renaming and ambiguity resolution</a></H3>
 
 
 <p>
@@ -2399,8 +2409,8 @@
 is used.
 </li>
 
-<li><p>The name matching rules strictly follow member qualification rules.
-For example, if you have a class like this:</p>
+<li><p>The name matching rules strictly follow member qualifier rules.
+For example, if you have a class and member with a member that is const qualified like this:</p>
 
 <div class="code">
 <pre>
@@ -2424,7 +2434,7 @@
 </div>
 
 <p>
-will not apply as there is no unqualified member <tt>bar()</tt>. The following will apply as
+will not apply as there is no unqualified member <tt>bar()</tt>. The following will apply the rename as
 the qualifier matches correctly:
 </p>
 
@@ -2435,6 +2445,26 @@
 </div>
 
 <p>
+Similarly for combinations of cv-qualifiers and ref-qualifiers, all the qualifiers must be specified to match correctly:
+</p>
+
+<div class="code">
+<pre>
+%rename(name) Jam::bar();          // will not match
+%rename(name) Jam::bar() &amp;;        // will not match
+%rename(name) Jam::bar() const;    // will not match
+%rename(name) Jam::bar() const &amp;;  // ok, will match
+
+class Jam {
+public:
+  ...
+  void bar() const &amp;;
+  ...
+};
+</pre>
+</div>
+
+<p>
 An often overlooked C++ feature is that classes can define two different overloaded members
 that differ only in their qualifiers, like this:
 </p>
@@ -2466,7 +2496,7 @@
 <p>
 Similarly, if you
 merely wanted to ignore one of the declarations, use <tt>%ignore</tt>
-with the full qualification.  For example, the following directive
+with the full qualifier.  For example, the following directive
 would tell SWIG to ignore the <tt>const</tt> version of <tt>bar()</tt>
 above:
 </p>
@@ -2532,8 +2562,7 @@
 <p>
 The C++ method can then be called from the target language with the new name no matter how many arguments are specified, for example:
 <tt>newbar(2, 2.0)</tt>, <tt>newbar(2)</tt> or <tt>newbar()</tt>.
-However, if the <tt>%rename</tt> does not contain the default arguments, it will only apply to the single equivalent target language overloaded method.
-So if instead we have:
+However, if the <tt>%rename</tt> does not contain the default arguments:
 </p>
 
 <div class="code">
@@ -2543,8 +2572,23 @@
 </div>
 
 <p>
+then only one of the three equivalent overloaded methods will be renamed and wrapped as if SWIG parsed:
+</p>
+
+<div class="code">
+<pre>
+void Spam::newbar(int i, double d);
+void Spam::bar(int i);
+void Spam::bar();
+</pre>
+</div>
+
+<p>
 The C++ method must then be called from the target language with the new name <tt>newbar(2, 2.0)</tt> when both arguments are supplied
 or with the original name as <tt>bar(2)</tt> (one argument) or <tt>bar()</tt> (no arguments).
+</p>
+
+<p>
 In fact it is possible to use <tt>%rename</tt> on the equivalent overloaded methods, to rename all the equivalent overloaded methods:
 </p>
 
@@ -2586,7 +2630,7 @@
 than dynamically typed languages like Perl, Python, Ruby, and Tcl.
 </p>
 
-<H2><a name="SWIGPlus_nn28">6.16 Wrapping overloaded operators</a></H2>
+<H2><a name="SWIGPlus_nn28">6.16 Overloaded operators</a></H2>
 
 
 <p>
@@ -2779,7 +2823,7 @@
 <tt>this[type key] { get { ... } set { ... }}</tt>, Python uses
 <tt>__getitem__</tt> and <tt>__setitem__</tt>, etc. In C++ if the return
 type of <tt>operator[]</tt> is a reference and the method is const, it is often indicative of the <i>setter</i>,
-and and the <i>getter</i> is usually a const function return an object by value.
+and the <i>getter</i> is usually a const function return an object by value.
 In the absence of any hard and fast rules and the fact that there may be multiple index operators,
 it is up to the user to choose the getter and setter to use by using %rename as shown earlier.
 </p>
@@ -2936,63 +2980,76 @@
 accept either variant.
 </p>
 
+<H3><a name="SWIGPlus_template_directive">6.18.1 The %template directive</a></H3>
+
+
 <p>
-Starting with SWIG-1.3.7, simple C++ template declarations can also be
-wrapped.  SWIG-1.3.12 greatly expands upon the earlier implementation. Before discussing this any further, there are a few things
-you need to know about template wrapping.  First, a bare C++ template
+There are a couple of important points about template wrapping.
+First, a bare C++ template
 does not define any sort of runnable object-code for which SWIG can
 normally create a wrapper.  Therefore, in order to wrap a template,
 you need to give SWIG information about a particular template
-instantiation (e.g., <tt>vector&lt;int&gt;</tt>,
+instantiation (e.g., <tt>vector&lt;int&gt;</tt>, 
 <tt>array&lt;double&gt;</tt>, etc.).  Second, an instantiation name
 such as <tt>vector&lt;int&gt;</tt> is generally not a valid identifier
 name in most target languages.  Thus, you will need to give the
-template instantiation a more suitable name such as <tt>intvector</tt>
-when creating a wrapper.
+template instantiation a more suitable name such as <tt>intvector</tt>.
 </p>
 
 <p>
-To illustrate, consider the following template definition:
+To illustrate, consider the following class template definition:
 </p>
 
 <div class="code"><pre>
 template&lt;class T&gt; class List {
 private:
-    T *data;
-    int nitems;
-    int maxitems;
+  T *data;
+  int nitems;
+  int maxitems;
 public:
-    List(int max) {
-      data = new T [max];
-      nitems = 0;
-      maxitems = max;
+  List(int max) {
+    data = new T [max];
+    nitems = 0;
+    maxitems = max;
+  }
+  ~List() {
+    delete [] data;
+  };
+  void append(T obj) {
+    if (nitems &lt; maxitems) {
+      data[nitems++] = obj;
     }
-    ~List() {
-      delete [] data;
-    };
-    void append(T obj) {
-      if (nitems &lt; maxitems) {
-        data[nitems++] = obj;
-      }
-    }
-    int length() {
-      return nitems;
-    }
-    T get(int n) {
-      return data[n];
-    }
+  }
+  int length() {
+    return nitems;
+  }
+  T get(int n) {
+    return data[n];
+  }
 };
 </pre></div>
 
 <p>
-By itself, this template declaration is useless--SWIG simply ignores it
-because it doesn't know how to generate any code until unless a definition of
+By itself, this class template is useless--SWIG simply ignores it
+because it doesn't know how to generate any code unless a definition of
 <tt>T</tt> is provided.
+The <tt>%template</tt> directive is required to instantiate the template for use in a target language.
+The directive requires an identifier name for use in the target language plus the template for instantiation.
+The example below instantiates <tt>List&lt;int&gt;</tt> for use as a class named <tt>intList</tt>:
 </p>
 
+<div class="code">
+<pre>
+%template(intList) List&lt;int&gt;;
+</pre>
+</div>
+
 <p>
-One way to create wrappers for a specific template instantiation is to simply
-provide an expanded version of the class directly like this:
+The instantiation expands the template code as a C++ compiler would do and then makes it available
+under the given identifier name.
+Essentially it is the same as wrapping the following concept code where 
+the class template definition has <tt>T</TT> expanded to <tt>int</tt>
+(note that this is not entirely valid syntax):
 </p>
 
 <div class="code">
@@ -3000,43 +3057,21 @@
 %rename(intList) List&lt;int&gt;;       // Rename to a suitable identifier
 class List&lt;int&gt; {
 private:
-    int *data;
-    int nitems;
-    int maxitems;
+  int *data;
+  int nitems;
+  int maxitems;
 public:
-    List(int max);
-    ~List();
-    void append(int obj);
-    int length();
-    int get(int n);
+  List(int max);
+  ~List();
+  void append(int obj);
+  int length();
+  int get(int n);
 };
 </pre>
 </div>
 
 
 <p>
-The <tt>%rename</tt> directive is needed to give the template class an appropriate identifier
-name in the target language (most languages would not recognize C++ template syntax as a valid
-class name).  The rest of the code is the same as what would appear in a normal
-class definition.
-</p>
-
-<p>
-Since manual expansion of templates gets old in a hurry, the <tt>%template</tt> directive can
-be used to create instantiations of a template class.  Semantically, <tt>%template</tt> is
-simply a shortcut---it expands template code in exactly the same way as shown above.  Here
-are some examples:
-</p>
-
-<div class="code">
-<pre>
-/* Instantiate a few different versions of the template */
-%template(intList) List&lt;int&gt;;
-%template(doubleList) List&lt;double&gt;;
-</pre>
-</div>
-
-<p>
 The argument to <tt>%template()</tt> is the name of the instantiation
 in the target language.  The name you choose should not conflict with
 any other declarations in the interface file with one exception---it
@@ -3053,7 +3088,81 @@
 </div>
 
 <p>
-SWIG can also generate wrappers for function templates using a similar technique.
+The <tt>%template</tt> directive
+must always appear <em>after</em> the definition of the template to be expanded, so the following will work:
+</p>
+
+<div class="code">
+<pre>
+template&lt;class T&gt; class List { ... };
+%template(intList) List&lt;int&gt;;
+</pre>
+</div>
+
+<p>
+but if %template is used before the template definition, such as:
+</p>
+
+<div class="code">
+<pre>
+%template(intList) List&lt;int&gt;;
+template&lt;class T&gt; class List { ... };
+</pre>
+</div>
+
+<p>
+SWIG will generate an error:
+</p>
+
+<div class="shell">
+<pre>
+example.i:3: Error: Template 'List' undefined.
+</pre>
+</div>
+
+<p>
+Since the type system knows how to handle <tt>typedef</tt>, it is
+generally not necessary to instantiate different versions of a template
+for typenames that are equivalent.  For instance, consider this code:
+</p>
+
+<div class="code">
+<pre>
+%template(intList) List&lt;int&gt;;
+typedef int Integer;
+...
+void foo(List&lt;Integer&gt; *x);
+</pre>
+</div>
+
+<p>
+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).
+</p>
+
+<p>
+The template provide to <tt>%template</tt> for instantiation must be the actual template and not a typedef to a template.
+</p>
+
+<div class="code">
+<pre>
+typedef List&lt;int&gt; ListOfInt;
+
+%template(intList) List&lt;int&gt;; // ok
+%template(intList) ListOfInt; // illegal - Syntax error
+</pre>
+</div>
+
+
+<H3><a name="SWIGPlus_template_functions">6.18.2 Function templates</a></H3>
+
+
+<p>
+SWIG can also generate wrappers for function templates using a similar technique
+to that shown above for class templates.
 For example:
 </p>
 
@@ -3074,6 +3183,28 @@
 </p>
 
 <p>
+SWIG even supports overloaded templated functions.  As usual the <tt>%template</tt> directive
+is used to wrap templated functions. For example:
+</p>
+
+<div class="code">
+<pre>
+template&lt;class T&gt; void foo(T x) { };
+template&lt;class T&gt; void foo(T x, T y) { };
+
+%template(foo) foo&lt;int&gt;;
+</pre>
+</div>
+
+<p>
+This will generate two overloaded wrapper methods, the first will take a single integer as an argument
+and the second will take two integer arguments.
+</p>
+
+<H3><a name="SWIGPlus_template_classes">6.18.3 Default template arguments</a></H3>
+
+
+<p>
 The number of arguments supplied to <tt>%template</tt> should match that in the
 original template definition.  Template default arguments are supported.  For example:
 </p>
@@ -3110,28 +3241,8 @@
 bloat.
 </p>
 
-<p>
-Since the type system knows how to handle <tt>typedef</tt>, it is
-generally not necessary to instantiate different versions of a template
-for typenames that are equivalent.  For instance, consider this code:
-</p>
+<H3><a name="SWIGPlus_template_class_inheritance">6.18.4 Template base classes</a></H3>
 
-<div class="code">
-<pre>
-%template(intList) vector&lt;int&gt;;
-typedef int Integer;
-...
-void foo(vector&lt;Integer&gt; *x);
-</pre>
-</div>
-
-<p>
-In this case, <tt>vector&lt;Integer&gt;</tt> is exactly the same type as
-<tt>vector&lt;int&gt;</tt>.  Any use of <tt>Vector&lt;Integer&gt;</tt> is mapped back to the 
-instantiation of <tt>vector&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).
-</p>
 
 <p>
 When a template is instantiated using <tt>%template</tt>, information
@@ -3158,13 +3269,13 @@
 
 <div class="shell">
 <pre>
-example.h:42: Warning 401. Nothing known about class 'List&lt;int &gt;'. Ignored. 
-example.h:42: Warning 401. Maybe you forgot to instantiate 'List&lt;int &gt;' using %template. 
+example.h:42: Warning 401. Nothing known about class 'List&lt; int &gt;'. Ignored. 
+example.h:42: Warning 401. Maybe you forgot to instantiate 'List&lt; int &gt;' using %template. 
 </pre>
 </div>
 
 <p>
-If a template class inherits from another template class, you need to
+If a class template inherits from another class template, you need to
 make sure that base classes are instantiated before derived classes.
 For example:
 </p>
@@ -3235,6 +3346,9 @@
 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>
+
+
 <p>
 The SWIG template mechanism <em>does</em> support specialization. For instance, if you define
 a class like this,
@@ -3244,15 +3358,15 @@
 <pre>
 template&lt;&gt; class List&lt;int&gt; {
 private:
-    int *data;
-    int nitems;
-    int maxitems;
+  int *data;
+  int nitems;
+  int maxitems;
 public:
-    List(int max);
-    ~List();
-    void append(int obj);
-    int length();
-    int get(int n);
+  List(int max);
+  ~List();
+  void append(int obj);
+  int length();
+  int get(int n);
 };
 </pre>
 </div>
@@ -3275,15 +3389,15 @@
 <pre>
 template&lt;class T&gt; class List&lt;T*&gt; {
 private:
-    T *data;
-    int nitems;
-    int maxitems;
+  T *data;
+  int nitems;
+  int maxitems;
 public:
-    List(int max);
-    ~List();
-    void append(int obj);
-    int length();
-    T get(int n);
+  List(int max);
+  ~List();
+  void append(T obj);
+  int length();
+  T get(int n);
 };
 </pre>
 </div>
@@ -3322,10 +3436,13 @@
 </pre>
 </div>
 
+<H3><a name="SWIGPlus_template_member">6.18.6 Member templates</a></H3>
+
+
 <p>
-Member function templates are supported.  The underlying principle is the same
+Member templates are supported.  The underlying principle is the same
 as for normal templates--SWIG can't create a wrapper unless you provide
-more information about types.  For example, a class with a member template might
+more information about types.  For example, a class with a member function template might
 look like this:
 </p>
 
@@ -3400,11 +3517,6 @@
 
 
 <p>
-Note: because of the way that templates are handled, the <tt>%template</tt> directive
-must always appear <em>after</em> the definition of the template to be expanded.
-</p>
-
-<p>
 Now, if your target language supports overloading, you can even try
 </p>
 
@@ -3424,7 +3536,7 @@
 
 <p>
 When used with members, the <tt>%template</tt> directive may be placed in another
-template class.  Here is a slightly perverse example:
+class template.  Here is a slightly perverse example:
 </p>
 
 <div class="code">
@@ -3475,7 +3587,7 @@
 <p>
 This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored
 unless you explicitly expand it.  To do that, you could expand a few versions of the constructor
-in the template class itself.  For example:
+in the class template itself.  For example:
 </p>
 
 <div class="code">
@@ -3536,6 +3648,110 @@
 type.
 </p>
 
+<H3><a name="SWIGPlus_template_scoping">6.18.7 Scoping and templates</a></H3>
+
+
+<p>
+The <tt>%template</tt> directive for a class template is the equivalent to an explicit instantiation
+of a C++ class template. The scope for a valid <tt>%template</tt> instantiation is the same
+as the scope required for a valid explicit instantiation of a C++ template.
+A definition of the template for the explicit instantiation must be in scope
+where the instantiation is declared and must not be enclosed within a different namespace.
+</p>
+
+<p>
+For example, a few <tt>%template</tt> instantiations and C++ explicit instantiations are shown below:
+</p>
+
+<div class="code">
+<pre>
+namespace N {
+  template&lt;typename T&gt; class C {};
+}
+
+// valid
+%template(cin) N::C&lt;int&gt;;
+template class N::C&lt;int&gt;;
+
+// valid
+namespace N {
+  %template(cin) C&lt;int&gt;;
+  template class C&lt;int&gt;;
+}
+
+// valid
+using namespace N;
+%template(cin) C&lt;int&gt;;
+template class C&lt;int&gt;;
+
+// valid
+using N::C;
+%template(cin) C&lt;int&gt;;
+template class C&lt;int&gt;;
+
+// ill-formed
+namespace unrelated {
+  using N::C;
+  %template(cin) C&lt;int&gt;;
+  template class C&lt;int&gt;;
+}
+
+// ill-formed
+namespace unrelated {
+  using namespace N;
+  %template(cin) C&lt;int&gt;;
+  template class C&lt;int&gt;;
+}
+
+// ill-formed
+namespace unrelated {
+  namespace N {
+    %template(cin) C&lt;int&gt;;
+    template class C&lt;int&gt;;
+  }
+}
+
+// ill-formed
+namespace unrelated {
+  %template(cin) N::C&lt;int&gt;;
+  template class N::C&lt;int&gt;;
+}
+</pre>
+</div>
+
+<p>
+When the scope is incorrect, such as for the ill-formed examples above, an error occurs:
+</p>
+
+<div class="shell">
+<pre>
+cpp_template_scope.i:34: Error: 'C' resolves to 'N::C' and was incorrectly instantiated
+in scope 'unrelated' instead of within scope 'N'.
+</pre>
+</div>
+
+<p>
+A note for the C++ standard geeks out there; a valid instantiation is one which conforms to
+the C++03 standard as C++11 made a change to disallow using declarations and using directives to find a template.
+</p>
+
+<div class="code">
+<pre>
+// valid C++03, ill-formed C++11
+using N::C;
+template class C&lt;int&gt;;
+</pre>
+</div>
+
+<p>
+<b>Compatibility Note</b>:  Versions prior to SWIG-4.0.0 did not error out with incorrectly scoped
+<tt>%template</tt> declarations, but this led to numerous subtle template scope problems.
+</p>
+
+ 
+<H3><a name="SWIGPlus_template_more">6.18.8 More on templates</a></H3>
+
+
 <p>
 If all of this isn't quite enough and you really want to make
 someone's head explode, SWIG directives such as
@@ -3568,7 +3784,7 @@
 </p>
 
 <p>
-It is also possible to separate these declarations from the template class.  For example:
+It is also possible to separate these declarations from the class template.  For example:
 </p>
 
 <div class="code">
@@ -3587,11 +3803,11 @@
 
 ...
 template&lt;class T&gt; class List {
-    ...
-    public:
-    List() { }
-    T get(int index);
-    ...
+  ...
+  public:
+  List() { }
+  T get(int index);
+  ...
 };
 </pre>
 </div>
@@ -3609,33 +3825,14 @@
 %template(intList) List&lt;int&gt;;
 
 %extend List&lt;int&gt; {
-    void blah() {
-          printf("Hey, I'm an List&lt;int&gt;!\n");
-    }
+  void blah() {
+    printf("Hey, I'm an List&lt;int&gt;!\n");
+  }
 };
 </pre>
 </div>
 
 <p>
-SWIG even supports overloaded templated functions.  As usual the <tt>%template</tt> directive
-is used to wrap templated functions. For example:
-</p>
-
-<div class="code">
-<pre>
-template&lt;class T&gt; void foo(T x) { };
-template&lt;class T&gt; void foo(T x, T y) { };
-
-%template(foo) foo&lt;int&gt;;
-</pre>
-</div>
-
-<p>
-This will generate two overloaded wrapper methods, the first will take a single integer as an argument
-and the second will take two integer arguments.
-</p>
-
-<p>
 It is even possible to extend a class via <tt>%extend</tt> with template methods, for example:
 </p>
 
@@ -3694,20 +3891,20 @@
 <pre>
 template &lt;class T&gt; class OuterTemplateClass {};
 
-// The nested class OuterClass::InnerClass inherits from the template class
+// The nested class OuterClass::InnerClass inherits from the class template
 // OuterTemplateClass&lt;OuterClass::InnerStruct&gt; and thus the template needs
 // to be expanded with %template before the OuterClass declaration.
 %template(OuterTemplateClass_OuterClass__InnerStruct)
-    OuterTemplateClass&lt;OuterClass::InnerStruct&gt;
+  OuterTemplateClass&lt;OuterClass::InnerStruct&gt;
 
 
 // Don't forget to use %feature("flatnested") for OuterClass::InnerStruct and
 // OuterClass::InnerClass if the target language doesn't support nested classes.
 class OuterClass {
-    public:
-        // Forward declarations:
-        struct InnerStruct;
-        class InnerClass;
+  public:
+    // Forward declarations:
+    struct InnerStruct;
+    class InnerClass;
 };
 
 struct OuterClass::InnerStruct {};
@@ -3736,7 +3933,7 @@
 <pre>
 %template(vectori) vector&lt;int&gt;;
 %extend vectori {
-    void somemethod() { }
+  void somemethod() { }
 };
 </pre>
 </div>
@@ -3750,7 +3947,7 @@
 <pre>
 %template(vectori) vector&lt;int&gt;;
 %extend vector&lt;int&gt; {
-    void somemethod() { }
+  void somemethod() { }
 };
 </pre>
 </div>
@@ -3915,6 +4112,8 @@
 <tt>spam()</tt>, and <tt>blah()</tt> in the target language.  SWIG
 does not prepend the names with a namespace prefix nor are the
 functions packaged in any kind of nested scope.
+Note that the default handling of flattening all the namespace scopes in the target language
+can be changed via the <a href="#SWIGPlus_nspace">nspace feature</a>.
 </p>
 
 <p>
@@ -4009,7 +4208,7 @@
 <div class="code">
 <pre>
 namespace foo {
-    template&lt;typename T&gt; T max(T a, T b) { return a &gt; b ? a : b; }
+  template&lt;typename T&gt; T max(T a, T b) { return a &gt; b ? a : b; }
 }
 
 using foo::max;
@@ -4018,8 +4217,8 @@
 %template(maxfloat) foo::max&lt;float&gt;;    // Okay (qualified name).
 
 namespace bar {
-    using namespace foo;
-    %template(maxdouble)  max&lt;double&gt;;    // Okay.
+  using namespace foo;
+  %template(maxdouble)  max&lt;double&gt;;    // Okay.
 }
 </pre>
 </div>
@@ -4040,7 +4239,7 @@
   typedef int Integer;
   class bar {
     public:
-      ...
+    ...
   };
 }
 
@@ -4203,9 +4402,7 @@
 <p>
 <b>Note:</b> The flattening of namespaces is only intended to serve as
 a basic namespace implementation.  
-None of the target language modules are currently programmed
-with any namespace awareness.   In the future, language modules may or may not provide
-more advanced namespace support.
+More advanced handling of namespaces is discussed next.
 </p>
 
 <H3><a name="SWIGPlus_nspace">6.19.1 The nspace feature for namespaces</a></H3>
@@ -4301,9 +4498,9 @@
 
 <div class="code">
 <pre>
-%rename(bbb) Space::ABC::aaa(T t);                  // will match but with lower precedence than ccc
+%rename(bbb) Space::ABC::aaa(T t);                     // will match but with lower precedence than ccc
 %rename(ccc) Space::ABC&lt;Space::XYZ&gt;::aaa(Space::XYZ t);// will match but with higher precedence
-                                                             // than bbb
+                                                       // than bbb
 
 namespace Space {
   class XYZ {};
@@ -4381,9 +4578,9 @@
 
 class Foo {
 public:
-    ...
-    void blah() throw(Error);
-    ...
+  ...
+  void blah() throw(Error);
+  ...
 };
 </pre>
 </div>
@@ -4445,10 +4642,10 @@
 
 class Foo {
 public:
-    ...
-    void bar();
-    void blah() throw(Error1, Error2, Error3, Error4);
-    ...
+  ...
+  void bar();
+  void blah() throw(Error1, Error2, Error3, Error4);
+  ...
 };
 </pre>
 </div>
@@ -4524,7 +4721,7 @@
 <p>
 In some C++ programs, objects are often encapsulated by smart-pointers
 or proxy classes.   This is sometimes done to implement automatic memory management (reference counting) or
-persistence. Typically a smart-pointer is defined by a template class where
+persistence. Typically a smart-pointer is defined by a class template where
 the <tt>-&gt;</tt> operator has been overloaded.  This class is then wrapped
 around some other class.  For example:
 </p>
@@ -4533,21 +4730,21 @@
 <pre>
 // Smart-pointer class
 template&lt;class T&gt; class SmartPtr {
-    T *pointee;
+  T *pointee;
 public:
-    SmartPtr(T *p) : pointee(p) { ... }
-    T *operator-&gt;() {
-        return pointee;
-    }
-    ...
+  SmartPtr(T *p) : pointee(p) { ... }
+  T *operator-&gt;() {
+    return pointee;
+  }
+  ...
 };
 
 // Ordinary class
 class Foo_Impl {
 public:
-    int x;
-    virtual void bar();
-    ...
+  int x;
+  virtual void bar();
+  ...
 };
 
 // Smart-pointer wrapper
@@ -4555,13 +4752,13 @@
 
 // Create smart pointer Foo
 Foo make_Foo() {
-    return SmartPtr&lt;Foo_Impl&gt;(new Foo_Impl());
+  return SmartPtr&lt;Foo_Impl&gt;(new Foo_Impl());
 }
 
 // Do something with smart pointer Foo
 void do_something(Foo f) {
-    printf("x = %d\n", f-&gt;x);
-    f-&gt;bar();
+  printf("x = %d\n", f-&gt;x);
+  f-&gt;bar();
 }
 
 // Call the wrapped smart pointer proxy class in the target language 'Foo'
@@ -4660,13 +4857,13 @@
 <pre>
 class Foo {
 public:
-    int x;
+  int x;
 };
 
 class Bar {
 public:
-    int x;       
-    Foo *operator-&gt;();
+  int x;       
+  Foo *operator-&gt;();
 };
 </pre>
 </div>
@@ -4915,19 +5112,19 @@
 <pre>
 class Foo {
 public:
-      int  blah(int x);
+  int  blah(int x);
 };
 
 class Bar {
 public:
-      double blah(double x);
+  double blah(double x);
 };
 
 class FooBar : public Foo, public Bar {
 public:
-      using Foo::blah;  
-      using Bar::blah;
-      char *blah(const char *x);
+  using Foo::blah;
+  using Bar::blah;
+  char *blah(const char *x);
 };
 </pre>
 </div>
@@ -4970,14 +5167,14 @@
 <pre>
 class Foo {
 protected:
-    int x;
-    int blah(int x);
+  int x;
+  int blah(int x);
 };
 
 class Bar : public Foo {
 public:
-    using Foo::x;       // Make x public
-    using Foo::blah;    // Make blah public
+  using Foo::x;       // Make x public
+  using Foo::blah;    // Make blah public
 };
 </pre>
 </div>
@@ -5008,14 +5205,14 @@
 class FooBar : public Foo, public Bar {
 public:
 #ifndef SWIG
-      using Foo::blah;  
-      using Bar::blah;
+  using Foo::blah;
+  using Bar::blah;
 #else
-      int blah(int x);         // explicitly tell SWIG about other declarations
-      double blah(double x);
+  int blah(int x);         // explicitly tell SWIG about other declarations
+  double blah(double x);
 #endif
 
-      char *blah(const char *x);
+  char *blah(const char *x);
 };
 </pre>
 </div>
diff --git a/Doc/Manual/Scilab.html b/Doc/Manual/Scilab.html
index 14e03ff..fafb0b5 100644
--- a/Doc/Manual/Scilab.html
+++ b/Doc/Manual/Scilab.html
@@ -121,15 +121,15 @@
 double Foo = 3.0;
 
 int fact(int n) {
-    if (n &lt; 0) {
-        return 0;
-    }
-    else if (n == 0) {
-        return 1;
-    }
-    else {
-        return n * fact(n-1);
-    }
+  if (n &lt; 0) {
+    return 0;
+  }
+  else if (n == 0) {
+    return 1;
+  }
+  else {
+    return n * fact(n-1);
+  }
 }
 %}
 </pre></div>
@@ -896,8 +896,8 @@
 %inline %{
 
 typedef struct {
-    int x;
-    int arr[4];
+  int x;
+  int arr[4];
 } Foo;
 
 %}
@@ -1133,21 +1133,21 @@
 
 
 <p>
-As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors.
+As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a> SWIG provides support for overloaded functions and constructors.
 </p>
 
-<p>As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
+<p>As SWIG knows pointer types, the overloading works also with pointer types, here is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
 </p>
 
 <div class="code"><pre>
 %module example
 
 void magnify(Square *square, double factor) {
-    square-&gt;size *= factor;
+  square-&gt;size *= factor;
 };
 
 void magnify(Circle *circle, double factor) {
-    square-&gt;radius *= factor;
+  square-&gt;radius *= factor;
 };
 </pre></div>
 
@@ -1620,11 +1620,11 @@
 
 
 <p>
-There are no specific typemaps for pointer-to-pointers, they are are mapped as pointers in Scilab.
+There are no specific typemaps for pointer-to-pointers, they are mapped as pointers in Scilab.
 </p>
 
 <p>
-Pointer-to-pointers are sometimes used to implement matrices in C. The following is a an example of this:
+Pointer-to-pointers are sometimes used to implement matrices in C. The following is an example of this:
 </p>
 
 
@@ -2062,7 +2062,7 @@
 Let's give an example how to build a module <tt>example</tt>, composed of two sources, and using a library dependency:
 </p>
 <ul>
-<li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored in in the current directory)</li>
+<li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored in the current directory)</li>
 <li>the library is <tt>libfoo</tt> in <tt>/opt/foo</tt> (headers stored in <tt>/opt/foo/include</tt>, and shared library in <tt>/opt/foo/lib</tt>)</li>
 </ul>
 
diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html
index 7391707..c17f9e8 100644
--- a/Doc/Manual/Sections.html
+++ b/Doc/Manual/Sections.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-3.0 Documentation</title>
+<title>SWIG-4.0 Documentation</title>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#ffffff">
-<H1><a name="Sections">SWIG-3.0 Documentation</a></H1>
+<H1><a name="Sections">SWIG-4.0 Documentation</a></H1>
 
 <p>
 Last update : SWIG-4.0.0 (in progress)
diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html
index 38d4103..41cb786 100644
--- a/Doc/Manual/Tcl.html
+++ b/Doc/Manual/Tcl.html
@@ -958,7 +958,7 @@
 }
 
 Foo *IncrFoo(Foo *f, int i) {
-    return f+i;
+  return f+i;
 }
 %}
 </pre>
@@ -1054,7 +1054,7 @@
 <div class="code">
 <pre>
 struct Bar {
-    int  x[16];
+  int  x[16];
 };
 </pre>
 </div>
@@ -1456,9 +1456,9 @@
 <pre>
 class Foo {
 public:
-    Foo();
-    Foo(const Foo &amp;);
-    ...
+  Foo();
+  Foo(const Foo &amp;);
+  ...
 };
 </pre>
 </div>
@@ -1693,11 +1693,11 @@
 %rename(Bar_spam) Bar::spam;
 
 namespace Foo {
-    int spam();
+  int spam();
 }
 
 namespace Bar {
-    int spam();
+  int spam();
 }
 </pre>
 </div>
@@ -1886,19 +1886,19 @@
 <div class="code">
 <pre>
 Foo *new_Foo() {
-    return new Foo();
+  return new Foo();
 }
 void delete_Foo(Foo *f) {
-    delete f;
+  delete f;
 }
 int Foo_x_get(Foo *f) {
-    return f-&gt;x;
+  return f-&gt;x;
 }
 void Foo_x_set(Foo *f, int value) {
-    f-&gt;x = value;
+  f-&gt;x = value;
 }
 int Foo_spam(Foo *f, int arg1) {
-    return f-&gt;spam(arg1);
+  return f-&gt;spam(arg1);
 }
 </pre>
 </div>
@@ -1945,8 +1945,8 @@
 <pre>
 class Foo {
 public:
-    Foo();
-    Foo bar();
+  Foo();
+  Foo bar();
 };
 </pre>
 </div>
@@ -1975,9 +1975,9 @@
 <pre>
 class Foo {
 public:
-    ...
-    Foo *spam();
-    ...
+  ...
+  Foo *spam();
+  ...
 };
 </pre>
 </div>
@@ -2011,8 +2011,8 @@
 %module example
 
 struct Foo {
-    int  value;
-    Foo  *next;
+  int  value;
+  Foo  *next;
 };
 
 Foo *head = 0;
@@ -2465,9 +2465,9 @@
 %module example
 
 %typemap(in) int {
-    if (Tcl_GetIntFromObj(interp, $input, &amp;$1) == TCL_ERROR)
-      return TCL_ERROR;
-    printf("Received an integer : %d\n", $1);
+  if (Tcl_GetIntFromObj(interp, $input, &amp;$1) == TCL_ERROR)
+    return TCL_ERROR;
+  printf("Received an integer : %d\n", $1);
 }
 %inline %{
 extern int fact(int n);
@@ -2585,7 +2585,7 @@
 <div class="code">
 <pre>
 %typemap(out) int {
-    Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
+  Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
 }
 </pre>
 </div>
@@ -3215,28 +3215,28 @@
 
 %inline %{
 double *new_double(int size) {
-        return (double *) malloc(size*sizeof(double));
+  return (double *) malloc(size*sizeof(double));
 }
 void delete_double(double *a) {
-        free(a);
+  free(a);
 }
 double get_double(double *a, int index) {
-        return a[index];
+  return a[index];
 }
 void set_double(double *a, int index, double val) {
-        a[index] = val;
+  a[index] = val;
 }
 int *new_int(int size) {
-        return (int *) malloc(size*sizeof(int));
+  return (int *) malloc(size*sizeof(int));
 }
 void delete_int(int *a) {
-        free(a);
+  free(a);
 }
 int get_int(int *a, int index) {
-        return a[index];
+  return a[index];
 }
 int set_int(int *a, int index, int val) {
-        a[index] = val;
+  a[index] = val;
 }
 %}
 
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
index f274c92..eeabdd8 100644
--- a/Doc/Manual/Typemaps.html
+++ b/Doc/Manual/Typemaps.html
@@ -4021,7 +4021,7 @@
 Forced inclusion of fragments can be used as a replacement for <a href="SWIG.html#SWIG_nn42">code insertion block</a>, ensuring the
 code block is only generated once.
 Consider the contents of FileA.i below which first uses a code insertion block and then a forced fragment inclusion to generate code:
-<p>
+</p>
 <div class="code">
 <pre>
 // FileA.i
@@ -4058,7 +4058,7 @@
 <p>
 A note of caution must be mentioned when using <tt>%fragment</tt> forced inclusion or code insertion blocks with <tt>%import</tt>.
 If <tt>%import</tt> is used instead:
-<p>
+</p>
 
 <div class="code">
 <pre>
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index fb58ee3..eba8163 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -423,8 +423,8 @@
 <div class="code">
 <pre>
 %typemap(in) (...) {
-    // Get variable length arguments (somehow)
-    ...
+  // Get variable length arguments (somehow)
+  ...
 }
 
 %typemap(in) (const char *fmt, ...) {
diff --git a/Doc/Manual/index.html b/Doc/Manual/index.html
index 26cc81e..e720e70 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-3.0 Documentation</title>
+<title>SWIG-4.0 Documentation</title>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#ffffff">
-<H1><a name="index">SWIG-3.0 Documentation</a></H1>
+<H1><a name="index">SWIG-4.0 Documentation</a></H1>
 
 The SWIG documentation is available in one of the following formats.
 <ul>
diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js
index 851d43c..f326488 100644
--- a/Examples/javascript/enum/runme.js
+++ b/Examples/javascript/enum/runme.js
@@ -30,5 +30,5 @@
 // enum value BLUE of enum color is accessed as property of cconst
 console.log("example.BLUE= " + example.BLUE);
 
-// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst
+// enum value LUDICROUS of enum Foo::speed is accessed as property of cconst
 console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); 
diff --git a/Examples/octave/extend/runme.m b/Examples/octave/extend/runme.m
index bc73184..c88a7c1 100644
--- a/Examples/octave/extend/runme.m
+++ b/Examples/octave/extend/runme.m
@@ -14,7 +14,7 @@
 
 # Create an instance of our employee extension class, CEO. The calls to
 # getName() and getPosition() are standard, the call to getTitle() uses
-# the director wrappers to call CEO.getPosition. e = CEO("Alice")
+# the director wrappers to call CEO.getPosition.
 
 e = CEO("Alice");
 printf("%s is a %s\n",e.getName(),e.getPosition());
diff --git a/Examples/php/enum/Makefile b/Examples/php/enum/Makefile
index 4483f78..063a064 100644
--- a/Examples/php/enum/Makefile
+++ b/Examples/php/enum/Makefile
@@ -5,7 +5,7 @@
 TARGET     = example
 INTERFACE  = example.i
 LIBS       =
-SWIGOPT    = -noproxy
+SWIGOPT    =
 
 check: build
 	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
diff --git a/Examples/php/enum/runme.php b/Examples/php/enum/runme.php
index 55b0bc4..8134766 100644
--- a/Examples/php/enum/runme.php
+++ b/Examples/php/enum/runme.php
@@ -11,22 +11,22 @@
 print "    GREEN  =" . GREEN;
 
 print "\n*** Foo::speed ***";
-print "    Foo_IMPULSE   =" . Foo_IMPULSE;
-print "    Foo_WARP      =" . Foo_WARP;
-print "    Foo_LUDICROUS =" . Foo_LUDICROUS;
+print "    Foo::IMPULSE   =" . Foo::IMPULSE;
+print "    Foo::WARP      =" . Foo::WARP;
+print "    Foo::LUDICROUS =" . Foo::LUDICROUS;
 
 print "\nTesting use of enums with functions\n";
 
-enum_test(RED, Foo_IMPULSE);
-enum_test(BLUE, Foo_WARP);
-enum_test(GREEN, Foo_LUDICROUS);
+enum_test(RED, Foo::IMPULSE);
+enum_test(BLUE, Foo::WARP);
+enum_test(GREEN, Foo::LUDICROUS);
 enum_test(1234,5678);
 
 print "\nTesting use of enum with class method\n";
-$f = new_Foo();
+$f = new Foo();
 
-Foo_enum_test($f,Foo_IMPULSE);
-Foo_enum_test($f,Foo_WARP);
-Foo_enum_test($f,Foo_LUDICROUS);
+$f->enum_test(Foo::IMPULSE);
+$f->enum_test(Foo::WARP);
+$f->enum_test(Foo::LUDICROUS);
 
 ?>
diff --git a/Examples/php/value/Makefile b/Examples/php/value/Makefile
index 28fc3a1..47e5ed9 100644
--- a/Examples/php/value/Makefile
+++ b/Examples/php/value/Makefile
@@ -5,7 +5,7 @@
 TARGET     = example
 INTERFACE  = example.i
 LIBS       =
-SWIGOPT    = -noproxy
+SWIGOPT    =
 
 check: build
 	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run
diff --git a/Examples/php/value/runme.php b/Examples/php/value/runme.php
index 4911537..569c87c 100644
--- a/Examples/php/value/runme.php
+++ b/Examples/php/value/runme.php
@@ -3,15 +3,15 @@
 	require "example.php";
 
 
-	$v = new_vector();
-        vector_x_set($v,1.0);
-        vector_y_set($v,2.0);
-        vector_z_set($v,3.0);
+	$v = new Vector();
+        $v->x = 1.0;
+        $v->y = 2.0;
+        $v->z = 3.0;
 
-	$w = new_vector();
-        vector_x_set($w,10.0);
-        vector_y_set($w,11.0);
-        vector_z_set($w,12.0);
+	$w = new Vector();
+        $w->x = 10.0;
+        $w->y = 11.0;
+        $w->z = 12.0;
 
 	echo "I just created the following vector\n";
 	vector_print($v);
@@ -25,7 +25,7 @@
 
 	echo "\nNow I'm going to add the vectors together\n";
 
-        $r = new_vector();
+        $r = new Vector();
 	vector_add($v, $w, $r);
 
 	vector_print($r);
diff --git a/Examples/php/variables/runme.php b/Examples/php/variables/runme.php
index bbfeb61..14f27f3 100644
--- a/Examples/php/variables/runme.php
+++ b/Examples/php/variables/runme.php
@@ -26,10 +26,10 @@
 	echo "pt	= ".pt_get(), point_print(pt_get()) , "\n";
 
 	/* Try to set the values of some global variables */
-$a = "42.14";
+	$a = "42.14";
 
 	ivar_set($a);
-echo "a = $a\n";
+	echo "a = $a\n";
 	svar_set(-31000);
 	lvar_set(65537);
 	uivar_set(123456);
diff --git a/Examples/php5/variables/runme.php b/Examples/php5/variables/runme.php
index bbfeb61..14f27f3 100644
--- a/Examples/php5/variables/runme.php
+++ b/Examples/php5/variables/runme.php
@@ -26,10 +26,10 @@
 	echo "pt	= ".pt_get(), point_print(pt_get()) , "\n";
 
 	/* Try to set the values of some global variables */
-$a = "42.14";
+	$a = "42.14";
 
 	ivar_set($a);
-echo "a = $a\n";
+	echo "a = $a\n";
 	svar_set(-31000);
 	lvar_set(65537);
 	uivar_set(123456);
diff --git a/Examples/python/extend/runme.py b/Examples/python/extend/runme.py
index 2bb38fa..e97358b 100644
--- a/Examples/python/extend/runme.py
+++ b/Examples/python/extend/runme.py
@@ -18,7 +18,7 @@
 
 # Create an instance of our employee extension class, CEO. The calls to
 # getName() and getPosition() are standard, the call to getTitle() uses
-# the director wrappers to call CEO.getPosition. e = CEO("Alice")
+# the director wrappers to call CEO.getPosition.
 
 e = CEO("Alice")
 print e.getName(), "is a", e.getPosition()
diff --git a/Examples/python/import_packages/namespace_pkg/nonpkg.py b/Examples/python/import_packages/namespace_pkg/nonpkg.py
index acf0aed..dc910b8 100644
--- a/Examples/python/import_packages/namespace_pkg/nonpkg.py
+++ b/Examples/python/import_packages/namespace_pkg/nonpkg.py
@@ -2,4 +2,5 @@
 
 import robin
 
-assert(robin.run() == "AWAY!")
+if not(robin.run() == "AWAY!"):
+    raise RuntimeError("test failed")
diff --git a/Examples/python/import_packages/namespace_pkg/normal.py b/Examples/python/import_packages/namespace_pkg/normal.py
index fc26c02..231d4cc 100644
--- a/Examples/python/import_packages/namespace_pkg/normal.py
+++ b/Examples/python/import_packages/namespace_pkg/normal.py
@@ -4,4 +4,5 @@
 
 from brave import robin
 
-assert(robin.run() == "AWAY!")
+if not(robin.run() == "AWAY!"):
+    raise RuntimeError("test failed")
diff --git a/Examples/python/import_packages/namespace_pkg/split.py b/Examples/python/import_packages/namespace_pkg/split.py
index 1b66c2d..88d17d5 100644
--- a/Examples/python/import_packages/namespace_pkg/split.py
+++ b/Examples/python/import_packages/namespace_pkg/split.py
@@ -6,4 +6,5 @@
 
 from brave import robin
 
-assert(robin.run() == "AWAY!")
+if not(robin.run() == "AWAY!"):
+    raise RuntimeError("test failed")
diff --git a/Examples/python/import_packages/namespace_pkg/zipsplit.py b/Examples/python/import_packages/namespace_pkg/zipsplit.py
index 9e35559..b027b11 100644
--- a/Examples/python/import_packages/namespace_pkg/zipsplit.py
+++ b/Examples/python/import_packages/namespace_pkg/zipsplit.py
@@ -6,4 +6,5 @@
 
 from brave import robin
 
-assert(robin.run() == "AWAY!")
+if not(robin.run() == "AWAY!"):
+    raise RuntimeError("test failed")
diff --git a/Examples/python/import_packages/split_modules/vanilla/runme.py b/Examples/python/import_packages/split_modules/vanilla/runme.py
index a188364..4c46ef2 100644
--- a/Examples/python/import_packages/split_modules/vanilla/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla/runme.py
@@ -7,4 +7,5 @@
 
 print "  Finished importing pkg1.foo"
 
-assert(pkg1.foo.count() == 3)
+if not(pkg1.foo.count() == 3):
+    raise RuntimeError("test failed")
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 a188364..4c46ef2 100644
--- a/Examples/python/import_packages/split_modules/vanilla_split/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla_split/runme.py
@@ -7,4 +7,5 @@
 
 print "  Finished importing pkg1.foo"
 
-assert(pkg1.foo.count() == 3)
+if not(pkg1.foo.count() == 3):
+    raise RuntimeError("test failed")
diff --git a/Examples/test-suite/README b/Examples/test-suite/README
index aac7636..3b7cea4 100644
--- a/Examples/test-suite/README
+++ b/Examples/test-suite/README
@@ -47,6 +47,6 @@
 Further Documentation
 ---------------------
 
-There is documentation about the test-suite and how to use use it in
+There is documentation about the test-suite and how to use it in
 the SWIG documentation - Doc/Manual/Extending.html#Extending_test_suite.
 
diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i
index a2d9f5b..97c05d7 100644
--- a/Examples/test-suite/autodoc.i
+++ b/Examples/test-suite/autodoc.i
@@ -133,6 +133,14 @@
 void banana(S *a, const struct tagS *b, int c, Integer d) {}
 %}
 
+// Check docs for a template type
+%inline %{
+template<typename X> struct T {
+  T inout(T t) { return t; }
+};
+%}
+%template(TInteger) T<int>;
+
 %inline %{
 #ifdef SWIGPYTHON_BUILTIN
 bool is_python_builtin() { return true; }
@@ -140,4 +148,3 @@
 bool is_python_builtin() { return false; }
 #endif
 %}
-  
diff --git a/Examples/test-suite/class_scope_namespace.i b/Examples/test-suite/class_scope_namespace.i
new file mode 100644
index 0000000..730c076
--- /dev/null
+++ b/Examples/test-suite/class_scope_namespace.i
@@ -0,0 +1,160 @@
+// Test a mix of forward class declarations, class definitions, using declarations and using directives.
+
+%module class_scope_namespace
+
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) H::HH;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Space8::I::II;
+
+%inline %{
+struct A;
+namespace Space1 {
+  namespace SubSpace1 {
+    struct A {
+      void aa(Space1::SubSpace1::A, SubSpace1::A, A) {}
+    };
+    void aaa(Space1::SubSpace1::A, SubSpace1::A, A) {}
+  }
+}
+
+namespace Space2 {
+  struct B;
+}
+using Space2::B;
+#ifdef __clang__
+namespace Space2 {
+  struct B {
+    void bb(Space2::B, B) {}
+  };
+}
+#else
+struct B {
+  void bb(Space2::B, B) {}
+};
+#endif
+void bbb(Space2::B, B) {}
+
+namespace Space3 {
+  namespace SubSpace3 {
+    struct C;
+    struct D;
+  }
+}
+struct C;
+struct D;
+namespace Space3 {
+  struct C;
+  struct SubSpace3::C {
+    void cc(Space3::SubSpace3::C, SubSpace3::C) {}
+  };
+  using SubSpace3::D;
+  struct SubSpace3::D {
+    void dd(Space3::SubSpace3::D, SubSpace3::D, D) {}
+  };
+  void ccc(Space3::SubSpace3::C, SubSpace3::C) {}
+  void ddd(Space3::SubSpace3::D, SubSpace3::D, D) {}
+}
+
+namespace Space4 {
+  namespace SubSpace4 {
+    struct E;
+  }
+}
+using namespace Space4;
+using SubSpace4::E;
+// Was added to incorrect namespace in swig-3.0.12
+struct SubSpace4::E {
+  void ee(Space4::SubSpace4::E, SubSpace4::E, E) {}
+};
+void eee(Space4::SubSpace4::E, SubSpace4::E, E) {}
+
+namespace Space5 {
+  namespace SubSpace5 {
+    namespace SubSubSpace5 {
+      struct F;
+    }
+  }
+}
+namespace Space5 {
+  using namespace SubSpace5;
+  using SubSubSpace5::F;
+  // Was added to incorrect namespace in swig-3.0.12
+  struct SubSubSpace5::F {
+    void ff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
+  };
+  void fff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
+}
+
+namespace Space6 {
+  struct G;
+  namespace SubSpace6 {
+    struct G;
+  }
+}
+namespace Space6 {
+  struct SubSpace6::G {
+    void gg(Space6::SubSpace6::G, SubSpace6::G) {}
+  };
+  void ggg(Space6::SubSpace6::G, SubSpace6::G) {}
+}
+
+struct HH;
+struct H {
+  struct HH {
+    void hh(H::HH) {}
+  };
+};
+void hhh(H::HH) {}
+
+namespace Space8 {
+  struct II;
+  struct I {
+    struct II {
+      void ii(Space8::I::II, I::II) {}
+    };
+  };
+  void iii(Space8::I::II, I::II) {}
+}
+
+struct J;
+namespace Space9 {
+  namespace SubSpace9 {
+    struct J {
+      void jj(Space9::SubSpace9::J, SubSpace9::J, J) {}
+    };
+    void jjj(Space9::SubSpace9::J, SubSpace9::J, J) {}
+  }
+}
+
+namespace Space10 {
+  struct K;
+}
+namespace Space10 {
+  namespace SubSpace10 {
+    struct K {
+      void kk(Space10::SubSpace10::K, SubSpace10::K, K) {}
+    };
+    void kkk(Space10::SubSpace10::K, SubSpace10::K, K) {}
+  }
+}
+
+namespace OtherSpace {
+  struct L;
+  struct M;
+}
+using OtherSpace::L;
+namespace Space11 {
+  using OtherSpace::M;
+  namespace SubSpace11 {
+    struct L {
+      void ll(Space11::SubSpace11::L, SubSpace11::L, L) {}
+    };
+    void lll(Space11::SubSpace11::L, SubSpace11::L, L) {}
+    struct M {
+      void mm(Space11::SubSpace11::M, SubSpace11::M, M) {}
+    };
+    void mmm(Space11::SubSpace11::M, SubSpace11::M, M) {}
+  }
+}
+
+%}
+
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index f68451f..4bd657c 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -99,7 +99,7 @@
 
 # Broken C test cases. (Can be run individually using: make testcase.ctest)
 C_TEST_BROKEN += \
-	tag_no_clash_with_variable
+	tag_no_clash_with_variable \
 
 # C++ test cases. (Can be run individually using: make testcase.cpptest)
 CPP_TEST_CASES += \
@@ -136,6 +136,7 @@
 	char_binary \
 	char_strings \
 	chartest \
+	class_scope_namespace \
 	class_forward \
 	class_ignore \
 	class_scope_weird \
@@ -291,6 +292,7 @@
 	multiple_inheritance_shared_ptr \
 	name_cxx \
 	name_warnings \
+	namespace_chase \
 	namespace_class \
 	namespace_enum \
 	namespace_extend \
@@ -418,6 +420,7 @@
 	template_default_inherit \
 	template_default_qualify \
 	template_default_vw \
+	template_empty_inherit \
 	template_enum \
 	template_enum_ns_inherit \
 	template_enum_typedef \
@@ -434,6 +437,7 @@
 	template_methods \
 	template_namespace_forward_declaration \
 	template_using_directive_and_declaration_forward \
+	template_using_directive_typedef \
 	template_nested \
 	template_nested_typemaps \
 	template_ns \
@@ -444,6 +448,7 @@
 	template_ns_enum2 \
 	template_ns_inherit \
 	template_ns_scope \
+	template_parameters_global_scope \
 	template_partial_arg \
 	template_partial_specialization \
 	template_partial_specialization_typedef \
@@ -533,7 +538,7 @@
 	virtual_vs_nonvirtual_base \
 	voidtest \
 	wallkw \
-	wrapmacro
+	wrapmacro \
 
 # C++11 test cases.
 CPP11_TEST_CASES += \
@@ -556,6 +561,9 @@
 	cpp11_noexcept \
 	cpp11_null_pointer_constant \
 	cpp11_raw_string_literals \
+	cpp11_ref_qualifiers \
+	cpp11_ref_qualifiers_rvalue_unignore \
+	cpp11_ref_qualifiers_typemaps \
 	cpp11_result_of \
 	cpp11_rvalue_reference \
 	cpp11_rvalue_reference2 \
@@ -600,9 +608,7 @@
 	smart_pointer_inherit \
 	template_typedef_fnc \
 	template_type_namespace \
-	template_opaque
-#        li_std_list
-
+	template_opaque \
 
 ifndef SKIP_CPP_STD_CASES
 CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
@@ -666,7 +672,7 @@
 	typedef_struct \
 	typemap_subst \
 	union_parameter \
-	unions
+	unions \
 
 
 # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest)
@@ -677,7 +683,7 @@
 	packageoption \
 	mod \
 	template_typedef_import \
-	multi_import
+	multi_import \
 
 # Custom tests - tests with additional commandline options
 wallkw.cpptest: SWIGOPT += -Wallkw
diff --git a/Examples/test-suite/constructor_copy.i b/Examples/test-suite/constructor_copy.i
index 7dcd05e..222c12f 100644
--- a/Examples/test-suite/constructor_copy.i
+++ b/Examples/test-suite/constructor_copy.i
@@ -73,12 +73,18 @@
 
 %include "std_vector.i"
 
-#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB)
+#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB)
 #define SWIG_GOOD_VECTOR
 %ignore std::vector<Space::Flow>::vector(size_type);
 %ignore std::vector<Space::Flow>::resize(size_type);
 #endif
 
+#if defined(SWIGJAVA)
+#define SWIG_GOOD_VECTOR
+%ignore std::vector<Space::Flow>::vector(jint);
+%ignore std::vector<Space::Flow>::resize(jint);
+#endif
+
 #if defined(SWIGTCL) || defined(SWIGPERL)
 #define SWIG_GOOD_VECTOR
 /* here, for languages with bad declaration */
diff --git a/Examples/test-suite/cpp11_ref_qualifiers.i b/Examples/test-suite/cpp11_ref_qualifiers.i
new file mode 100644
index 0000000..e371367
--- /dev/null
+++ b/Examples/test-suite/cpp11_ref_qualifiers.i
@@ -0,0 +1,226 @@
+%module cpp11_ref_qualifiers
+
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra2;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra3;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc2;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc3;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc5;
+
+%include <std_string.i>
+
+%ignore Host::h() const &;
+
+// Basic testing
+%inline %{
+using std::string;
+class Host {
+  string s;
+public:
+  string h1() & { return string(); }
+  string h2() const & { return string(); }
+  string h3() && { return std::move(string()); }
+  string h4() const && { return std::move(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 h() & { return string(); }
+  string h() const & { return string(); }
+  string h() && { return std::move(string()); }
+  string h() const && { return std::move(string()); }
+};
+%}
+
+// %feature testing
+%feature("except") F1() & %{ result = "F1"; %}
+%feature("except") F2 %{ result = "F2"; %}
+%feature("except") F3 %{ result = "F3"; %}
+%feature("except") F3() %{ _should_not_be_used_ %}
+
+%feature("except") C1(int i) const & %{ result = "C1"; %}
+%feature("except") C2 %{ result = "C2"; %}
+%feature("except") C3 %{ result = "C3"; %}
+%feature("except") C3(int i) %{ _should_not_be_used_ %}
+
+%inline %{
+struct Features {
+  string F1() & { return string(); }
+  string F2() & { return string(); }
+  string F3() & { return string(); }
+
+  string C1(int i) const & { return string(); }
+  string C2(int i) const & { return string(); }
+  string C3(int i) const & { return string(); }
+};
+%}
+
+// %rename testing
+%rename(RR1) R1;
+%rename(RR2) R2() &;
+%rename(RR3) R3;
+%rename(RR3Bad) R3();
+
+%rename(SS1) S1;
+%rename(SS2) S2(int i) const &;
+%rename(SS3) S3;
+%rename(SS3Bad) S3(int i);
+%rename(SS3BadConst) S3(int i) const;
+%rename(SS3BadLValue) S3(int i) &;
+
+%inline %{
+struct Renames {
+  string R1() & { return string(); }
+  string R2() & { return string(); }
+  string R3() & { return string(); }
+
+  string S1(int i) const & { return string(); }
+  string S2(int i) const & { return string(); }
+  string S3(int i) const & { return string(); }
+};
+%}
+
+// Conversion operators
+%rename(StringConvertCopy) operator string() &;
+%rename(StringConvertMove) operator string() &&;
+%feature("ignore", "0") operator string() &&; // unignore as it is ignored by default
+
+%inline %{
+struct ConversionOperators {
+  virtual operator string() & { return string(); }
+  virtual operator string() && { return std::move(string()); }
+  virtual ~ConversionOperators() {}
+};
+struct ConversionOperators2 {
+  virtual operator string() && { return std::move(string()); }
+  virtual ~ConversionOperators2() {}
+};
+%}
+
+%inline %{
+struct Funcs {
+  short FF(bool) { return 0; }
+  short CC(bool) const & { return 0; }
+};
+
+class MemberFuncPtrs
+{
+public:
+  // member ref-qualified function pointers, unnamed parameters
+  int aaa1(short (Funcs::*)(bool) &) const;
+  int aaa2(short (Funcs::* const *&)(bool) &) const;
+  int aaa3(short (Funcs::* *&)(bool) &) const;
+  int aaa4(short (Funcs::* *const&)(bool) &) const;
+  int aaa5(short (Funcs::* &)(bool) &) const;
+  int aaa6(short (Funcs::* const)(bool) &) const;
+  int aaa7(short (Funcs::* const&)(bool) &) const;
+
+  int aaa8(short (Funcs::* const&)(bool) &&) const;
+
+  // member cv-qualified and ref-qualified function pointers, unnamed parameters
+  int bbb1(short (Funcs::*)(bool) const &) const;
+  int bbb2(short (Funcs::* const *&)(bool) const &) const;
+  int bbb3(short (Funcs::* *&)(bool) const &) const;
+  int bbb4(short (Funcs::* *const&)(bool) const &) const;
+  int bbb5(short (Funcs::* &)(bool) const &) const;
+  int bbb6(short (Funcs::* const)(bool) const &) const;
+  int bbb7(short (Funcs::* const&)(bool) const &) const;
+
+  int bbb8(short (Funcs::*)(bool) const &&) const;
+
+  // member ref-qualified function pointers, named parameters
+  int qqq1(short (Funcs::* qq1)(bool) &) const;
+  int qqq2(short (Funcs::* const *& qq2)(bool) &) const;
+  int qqq3(short (Funcs::* *& qq3)(bool) &) const;
+  int qqq4(short (Funcs::* *const& qq4)(bool) &) const;
+  int qqq5(short (Funcs::* & qq5)(bool) &) const;
+  int qqq6(short (Funcs::* const qq6)(bool) &) const;
+  int qqq7(short (Funcs::* const& qq7)(bool) &) const;
+
+  int qqq8(short (Funcs::* const& qq8)(bool) &&) const;
+
+  // member cv-qualified and ref-qualified function pointers, named parameters
+  int rrr1(short (Funcs::* rr1)(bool) const &) const;
+  int rrr2(short (Funcs::* const *& rr2)(bool) const &) const;
+  int rrr3(short (Funcs::* *& rr3)(bool) const &) const;
+  int rrr4(short (Funcs::* *const& rr4)(bool) const &) const;
+  int rrr5(short (Funcs::* & rr5)(bool) const &) const;
+  int rrr6(short (Funcs::* const rr6)(bool) const &) const;
+  int rrr7(short (Funcs::* const& rr7)(bool) const &) const;
+
+  int rrr8(short (Funcs::* rr1)(bool) const &&) const;
+};
+
+// member ref-qualified function pointers, unnamed parameters
+int MemberFuncPtrs::aaa1(short (Funcs::*)(bool) &) const { return 0; }
+int MemberFuncPtrs::aaa2(short (Funcs::* const *&)(bool) &) const { return 0; }
+int MemberFuncPtrs::aaa3(short (Funcs::* *&)(bool) &) const { return 0; }
+int MemberFuncPtrs::aaa4(short (Funcs::* *const&)(bool) &) const { return 0; }
+int MemberFuncPtrs::aaa5(short (Funcs::* &)(bool) &) const { return 0; }
+int MemberFuncPtrs::aaa6(short (Funcs::* const)(bool) &) const { return 0; }
+int MemberFuncPtrs::aaa7(short (Funcs::* const&)(bool) &) const { return 0; }
+
+int MemberFuncPtrs::aaa8(short (Funcs::* const&)(bool) &&) const { return 0; }
+
+// member cv-qualified and ref-qualified function pointers, unnamed parameters
+int MemberFuncPtrs::bbb1(short (Funcs::*)(bool) const &) const { return 0; }
+int MemberFuncPtrs::bbb2(short (Funcs::* const *&)(bool) const &) const { return 0; }
+int MemberFuncPtrs::bbb3(short (Funcs::* *&)(bool) const &) const { return 0; }
+int MemberFuncPtrs::bbb4(short (Funcs::* *const&)(bool) const &) const { return 0; }
+int MemberFuncPtrs::bbb5(short (Funcs::* &)(bool) const &) const { return 0; }
+int MemberFuncPtrs::bbb6(short (Funcs::* const)(bool) const &) const { return 0; }
+int MemberFuncPtrs::bbb7(short (Funcs::* const&)(bool) const &) const { return 0; }
+
+int MemberFuncPtrs::bbb8(short (Funcs::*)(bool) const &&) const { return 0; }
+
+// member ref-qualified function pointers, named parameters
+int MemberFuncPtrs::qqq1(short (Funcs::* qq1)(bool) &) const { return 0; }
+int MemberFuncPtrs::qqq2(short (Funcs::* const *& qq2)(bool) &) const { return 0; }
+int MemberFuncPtrs::qqq3(short (Funcs::* *& qq3)(bool) &) const { return 0; }
+int MemberFuncPtrs::qqq4(short (Funcs::* *const& qq4)(bool) &) const { return 0; }
+int MemberFuncPtrs::qqq5(short (Funcs::* & qq5)(bool) &) const { return 0; }
+int MemberFuncPtrs::qqq6(short (Funcs::* const qq6)(bool) &) const { return 0; }
+int MemberFuncPtrs::qqq7(short (Funcs::* const& qq7)(bool) &) const { return 0; }
+
+int MemberFuncPtrs::qqq8(short (Funcs::* const& qq8)(bool) &&) const { return 0; }
+
+// member cv-qualified and ref-qualified function pointers, named parameters
+int MemberFuncPtrs::rrr1(short (Funcs::* rr1)(bool) const &) const { return 0; }
+int MemberFuncPtrs::rrr2(short (Funcs::* const *& rr2)(bool) const &) const { return 0; }
+int MemberFuncPtrs::rrr3(short (Funcs::* *& rr3)(bool) const &) const { return 0; }
+int MemberFuncPtrs::rrr4(short (Funcs::* *const& rr4)(bool) const &) const { return 0; }
+int MemberFuncPtrs::rrr5(short (Funcs::* & rr5)(bool) const &) const { return 0; }
+int MemberFuncPtrs::rrr6(short (Funcs::* const rr6)(bool) const &) const { return 0; }
+int MemberFuncPtrs::rrr7(short (Funcs::* const& rr7)(bool) const &) const { return 0; }
+
+int MemberFuncPtrs::rrr8(short (Funcs::* rr1)(bool) const &&) const { return 0; }
+
+// member cv-qualified and ref-qualified pointer variables
+short (Funcs::* cc1)(bool) const & = &Funcs::CC;
+
+short (Funcs::* const * ccextra2)(bool) const & = &cc1;
+short (Funcs::* * ccextra3)(bool) const & = &cc1;
+short (Funcs::* *const ccextra4)(bool) const & = &cc1;
+
+short (Funcs::* const *& cc2)(bool) const & = ccextra2;
+short (Funcs::* *& cc3)(bool) const & = ccextra3;
+short (Funcs::* *const& cc4)(bool) const & = ccextra4;
+short (Funcs::* & cc5)(bool) const & = cc1;
+short (Funcs::* const cc6)(bool) const & = &Funcs::CC;
+short (Funcs::* const& cc7)(bool) const & = cc1;
+%}
+
+%inline %{
+
+struct Funktions {
+  int addByValue(const int &a, int b) const & { return a+b; }
+  int * addByPointer(const int &a, int b) const & { static int val; val = a+b; return &val; }
+  int & addByReference(const int &a, int b) const & { static int val; val = a+b; return val; }
+};
+
+int call1(int (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return (f.*d)(a, b); }
+//int call2(int * (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return *(f.*d)(a, b); }
+//int call3(int & (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return (f.*d)(a, b); }
+%}
+%constant int (Funktions::*ADD_BY_VALUE)(const int &, int) const & = &Funktions::addByValue;
diff --git a/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i b/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i
new file mode 100644
index 0000000..2f5fadf
--- /dev/null
+++ b/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i
@@ -0,0 +1,15 @@
+%module cpp11_ref_qualifiers_rvalue_unignore
+
+// This is a minimal test that does not include any C++ headers to make sure the required
+// <memory> header is generated from a fragment for the generated std::move call
+
+// m1 and m2 are ignored by default, unignore them
+%feature("ignore", "0") RefQualifier::m1() &&;
+%feature("ignore", "0") RefQualifier::m2() const &&;
+
+%inline %{
+struct RefQualifier {
+  void m1() && {}
+  void m2() const && {}
+};
+%}
diff --git a/Examples/test-suite/cpp11_ref_qualifiers_typemaps.i b/Examples/test-suite/cpp11_ref_qualifiers_typemaps.i
new file mode 100644
index 0000000..0e1c3fe
--- /dev/null
+++ b/Examples/test-suite/cpp11_ref_qualifiers_typemaps.i
@@ -0,0 +1,74 @@
+%module cpp11_ref_qualifiers_typemaps
+
+%typemap(in) SWIGTYPE (CLASS::*) %{
+  _this_will_fail_to_compile_if_used_
+%}
+
+// typemaps to completely ignore the input parm and override it
+%typemap(in) short (Funcs::*ff)(bool) const   %{ $1 = &Funcs::FFF2; %}
+%typemap(in) short (Funcs::*cc)(bool) &       %{ $1 = &Funcs::CCC5; %}
+%typemap(in) short (Funcs::*gg)(bool) const & %{ $1 = &Funcs::GGG8; %}
+%typemap(in) short (Funcs::*hh)(bool) &&      %{ $1 = &Funcs::HHH11; %}
+
+%typemap(in) short (Funcs::*)(bool) const   %{ $1 = &Funcs::FFF3; %}
+%typemap(in) short (Funcs::*)(bool) &       %{ $1 = &Funcs::CCC6; %}
+%typemap(in) short (Funcs::*)(bool) const & %{ $1 = &Funcs::GGG9; %}
+%typemap(in) short (Funcs::*)(bool) &&      %{ $1 = &Funcs::HHH12; %}
+
+%inline %{
+struct Funcs {
+  short FFF1(bool) const { return 1; }
+  short FFF2(bool) const { return 2; }
+  short FFF3(bool) const { return 3; }
+  short CCC4(bool) & { return 4; }
+  short CCC5(bool) & { return 5; }
+  short CCC6(bool) & { return 6; }
+  short GGG7(bool) const & { return 7; }
+  short GGG8(bool) const & { return 8; }
+  short GGG9(bool) const & { return 9; }
+  short HHH10(bool) && { return 10; }
+  short HHH11(bool) && { return 11; }
+  short HHH12(bool) && { return 12; }
+};
+struct TypemapsNamedParms
+{
+  short fff(short (Funcs::*ff)(bool) const) {
+    Funcs funcs;
+    return (funcs.*ff)(true);
+  }
+  short ccc(short (Funcs::*cc)(bool) &) {
+    Funcs funcs;
+    return (funcs.*cc)(true);
+  }
+  short ggg(short (Funcs::*gg)(bool) const &) {
+    Funcs funcs;
+    return (funcs.*gg)(true);
+  }
+  short hhh(short (Funcs::*hh)(bool) &&) {
+    return (Funcs().*hh)(true);
+  }
+};
+struct TypemapsUnnamedParms
+{
+  short fff(short (Funcs::*f)(bool) const) {
+    Funcs funcs;
+    return (funcs.*f)(true);
+  }
+  short ccc(short (Funcs::*c)(bool) &) {
+    Funcs funcs;
+    return (funcs.*c)(true);
+  }
+  short ggg(short (Funcs::*g)(bool) const &) {
+    Funcs funcs;
+    return (funcs.*g)(true);
+  }
+  short hhh(short (Funcs::*h)(bool) &&) {
+    return (Funcs().*h)(true);
+  }
+};
+%}
+
+%constant short (Funcs::*FF1_MFP)(bool) const = &Funcs::FFF1;
+%constant short (Funcs::*CC4_MFP)(bool) & = &Funcs::CCC4;
+%constant short (Funcs::*GG7_MFP)(bool) const & = &Funcs::GGG7;
+%constant short (Funcs::*HH10_MFP)(bool) && = &Funcs::HHH10;
diff --git a/Examples/test-suite/cpp11_static_assert.i b/Examples/test-suite/cpp11_static_assert.i
index 8d616f9..7ca452d 100644
--- a/Examples/test-suite/cpp11_static_assert.i
+++ b/Examples/test-suite/cpp11_static_assert.i
@@ -1,12 +1,32 @@
-/* This test case checks whether SWIG correctly parses and ignores the
-   keywords "static_assert()" inside the class or struct.
+/* This test case checks whether SWIG correctly parses and ignores
+   "static_assert()" in various places.
 */
 %module cpp11_static_assert
 
 %inline %{
+static_assert(sizeof(int) >= 2, "What?  int size is invalid!");
+
+namespace dummy {
+// C++17 allows the message to be omitted, so check that works too.
+// But only show the C++17 version to SWIG, as the compiler may
+// lack C++17 support.
+#ifdef SWIG
+static_assert(sizeof(int) >= sizeof(short));
+#else
+static_assert(sizeof(int) >= sizeof(short), "blah");
+#endif
+}
+
 template <typename T>
 struct Check1 {
   static_assert(sizeof(int) <= sizeof(T), "not big enough");
+  Check1() {
+#ifdef SWIG
+      static_assert(true);
+#else
+      static_assert(true, "true");
+#endif
+  }
 };
 
 template <typename T>
diff --git a/Examples/test-suite/csharp/li_std_map_runme.cs b/Examples/test-suite/csharp/li_std_map_runme.cs
index 0fe1ab5..b21c81e 100644
--- a/Examples/test-suite/csharp/li_std_map_runme.cs
+++ b/Examples/test-suite/csharp/li_std_map_runme.cs
@@ -18,7 +18,7 @@
 
     public static void Main()
     {
-        // Set up an int int map
+        // Set up an string to int map
         StringIntMap simap = new StringIntMap();
         for (int i = 0; i < collectionSize; i++)
         {
diff --git a/Examples/test-suite/csharp/preproc_constants_c_runme.cs b/Examples/test-suite/csharp/preproc_constants_c_runme.cs
index 76c684d..5966d52 100644
--- a/Examples/test-suite/csharp/preproc_constants_c_runme.cs
+++ b/Examples/test-suite/csharp/preproc_constants_c_runme.cs
@@ -36,7 +36,7 @@
     assert( typeof(string) == preproc_constants_c.CONST_STRING2.GetType() );
 
     assert( typeof(int) == preproc_constants_c.INT_AND_BOOL.GetType() );
-//    assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() );
+    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() );
@@ -61,7 +61,9 @@
     assert( typeof(int) == preproc_constants_c.EXPR_LAND.GetType() );
     assert( typeof(int) == preproc_constants_c.EXPR_LOR.GetType() );
     assert( typeof(double) == preproc_constants_c.EXPR_CONDITIONAL.GetType() );
-
+    assert( typeof(double) == preproc_constants_c.EXPR_MIXED1.GetType() );
+    assert( typeof(int) == preproc_constants_c.EXPR_WCHAR_MAX.GetType() );
+    assert( typeof(int) == preproc_constants_c.EXPR_WCHAR_MIN.GetType() );
   }
   static void assert(bool assertion) {
     if (!assertion)
diff --git a/Examples/test-suite/csharp/preproc_constants_runme.cs b/Examples/test-suite/csharp/preproc_constants_runme.cs
index 9fae591..6af8f20 100644
--- a/Examples/test-suite/csharp/preproc_constants_runme.cs
+++ b/Examples/test-suite/csharp/preproc_constants_runme.cs
@@ -35,7 +35,7 @@
     assert( typeof(string) == preproc_constants.CONST_STRING2.GetType() );
 
     assert( typeof(int) == preproc_constants.INT_AND_BOOL.GetType() );
-//    assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() );
+    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() );
@@ -60,6 +60,9 @@
     assert( typeof(bool) == preproc_constants.EXPR_LAND.GetType() );
     assert( typeof(bool) == preproc_constants.EXPR_LOR.GetType() );
     assert( typeof(double) == preproc_constants.EXPR_CONDITIONAL.GetType() );
+    assert( typeof(double) == preproc_constants.EXPR_MIXED1.GetType() );
+    assert( typeof(int) == preproc_constants.EXPR_WCHAR_MAX.GetType() );
+    assert( typeof(int) == preproc_constants.EXPR_WCHAR_MIN.GetType() );
 
   }
   static void assert(bool assertion) {
diff --git a/Examples/test-suite/d/preproc_constants_c_runme.1.d b/Examples/test-suite/d/preproc_constants_c_runme.1.d
index d846c71..a6c2f3d 100644
--- a/Examples/test-suite/d/preproc_constants_c_runme.1.d
+++ b/Examples/test-suite/d/preproc_constants_c_runme.1.d
@@ -36,7 +36,7 @@
   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_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())));
@@ -61,4 +61,7 @@
   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 9bdbb93..786cb48 100644
--- a/Examples/test-suite/d/preproc_constants_c_runme.2.d
+++ b/Examples/test-suite/d/preproc_constants_c_runme.2.d
@@ -36,7 +36,7 @@
   static assert(is(string == 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_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())));
@@ -61,4 +61,7 @@
   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_runme.1.d b/Examples/test-suite/d/preproc_constants_runme.1.d
index 009405f..85fa918 100644
--- a/Examples/test-suite/d/preproc_constants_runme.1.d
+++ b/Examples/test-suite/d/preproc_constants_runme.1.d
@@ -35,7 +35,7 @@
   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_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())));
@@ -60,4 +60,7 @@
   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 2d92ef0..c81e531 100644
--- a/Examples/test-suite/d/preproc_constants_runme.2.d
+++ b/Examples/test-suite/d/preproc_constants_runme.2.d
@@ -35,7 +35,7 @@
   static assert(is(string == 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_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())));
@@ -60,4 +60,7 @@
   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/default_args.i b/Examples/test-suite/default_args.i
index 8828bfe..1f7183f 100644
--- a/Examples/test-suite/default_args.i
+++ b/Examples/test-suite/default_args.i
@@ -5,6 +5,7 @@
 %{
 #if defined(_MSC_VER)
   #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
+  #pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
 #endif
 #if __GNUC__ >= 7
   #pragma GCC diagnostic push
@@ -18,14 +19,20 @@
   #include <string>
 
   // All kinds of numbers: hex, octal (which pose special problems to Python), negative...
-  void trickyvalue1(int first, int pos = -1) {}
-  void trickyvalue2(int first, unsigned rgb = 0xabcdef) {}
-  void trickyvalue3(int first, int mode = 0644) {}
+
+  class TrickyInPython {
+  public:
+    int value_m1(int first, int pos = -1) { return pos; }
+    unsigned value_0xabcdef(int first, unsigned rgb = 0xabcdef) { return rgb; }
+    int value_0644(int first, int mode = 0644) { return mode; }
+    int value_perm(int first, int mode = 0640 | 0004) { return mode; }
+    int value_m01(int first, int val = -01) { return val; }
+    bool booltest2(bool x = 0 | 1) { return x; }
+  };
 
   void doublevalue1(int first, double num = 0.0e-1) {}
   void doublevalue2(int first, double num = -0.0E2) {}
 
-  // Long long arguments are not handled at Python level currently but still work.
   void seek(long long offset = 0LL) {}
   void seek2(unsigned long long offset = 0ULL) {}
   void seek3(long offset = 0L) {}
diff --git a/Examples/test-suite/director_extend.i b/Examples/test-suite/director_extend.i
index cec930a..60a9d4c 100644
--- a/Examples/test-suite/director_extend.i
+++ b/Examples/test-suite/director_extend.i
@@ -25,7 +25,7 @@
   size_t ExceptionMethod()
   {
 // Check positioning of director code in wrapper file
-// Below is what we really want to test, but director exceptions vary too much across across all languages
+// Below is what we really want to test, but director exceptions vary too much across all languages
 //    throw Swig::DirectorException("DirectorException was not in scope!!");
 // Instead check definition of Director class as that is defined in the same place as DirectorException (director.swg)
     size_t size = sizeof(Swig::Director);
diff --git a/Examples/test-suite/errors/cpp_class_definition.i b/Examples/test-suite/errors/cpp_class_definition.i
new file mode 100644
index 0000000..8381e75
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_class_definition.i
@@ -0,0 +1,26 @@
+%module xxx
+
+// This should error but doesn't
+#if 0
+namespace OtherSpace {
+  struct L;
+}
+namespace Space11 {
+  namespace SubSpace11 {
+    using OtherSpace::L;
+    struct L {
+      void ll();
+    };
+  }
+}
+#endif
+
+namespace Space1 {
+  struct A;
+}
+namespace Space2 {
+  struct Space1::A {
+    void x();
+  };
+}
+
diff --git a/Examples/test-suite/errors/cpp_class_definition.stderr b/Examples/test-suite/errors/cpp_class_definition.stderr
new file mode 100644
index 0000000..2c41028
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_class_definition.stderr
@@ -0,0 +1 @@
+cpp_class_definition.i:22: Error: 'Space1::A' resolves to 'Space1::A' and was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
diff --git a/Examples/test-suite/errors/cpp_invalid_qualifiers.i b/Examples/test-suite/errors/cpp_invalid_qualifiers.i
new file mode 100644
index 0000000..fd3b363
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_invalid_qualifiers.i
@@ -0,0 +1,43 @@
+%module cpp_invalid_qualifiers
+
+// Constructors, destructors and static methods cannot have qualifiers
+struct A {
+  ~A() const;
+};
+struct B {
+  virtual ~B() const;
+};
+struct C {
+  ~C() &;
+};
+struct D {
+  virtual ~D() &;
+};
+struct E {
+  ~E() &&;
+};
+struct F {
+  virtual ~F() &&;
+};
+
+struct J {
+  J() const;
+  J(int) const;
+};
+struct K {
+  K() &;
+  K(int) &;
+};
+struct L {
+  L() &&;
+  L(int) &&;
+};
+
+struct M {
+  static void m1() const;
+  static void m2() &;
+  thread_local static void m3() &&;
+  static auto m4() const -> int;
+  static auto m5() & -> int;
+  static auto m6() && -> int;
+};
diff --git a/Examples/test-suite/errors/cpp_invalid_qualifiers.stderr b/Examples/test-suite/errors/cpp_invalid_qualifiers.stderr
new file mode 100644
index 0000000..7b3e442
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_invalid_qualifiers.stderr
@@ -0,0 +1,20 @@
+cpp_invalid_qualifiers.i:5: Error: Destructor ~A() const cannot have a qualifier.
+cpp_invalid_qualifiers.i:8: Error: Destructor ~B() const cannot have a qualifier.
+cpp_invalid_qualifiers.i:11: Error: Destructor ~C() & cannot have a qualifier.
+cpp_invalid_qualifiers.i:14: Error: Destructor ~D() & cannot have a qualifier.
+cpp_invalid_qualifiers.i:17: Error: Destructor ~E() && cannot have a qualifier.
+cpp_invalid_qualifiers.i:20: Error: Destructor ~F() && cannot have a qualifier.
+cpp_invalid_qualifiers.i:24: Error: Constructor cannot have a qualifier.
+cpp_invalid_qualifiers.i:25: Error: Constructor cannot have a qualifier.
+cpp_invalid_qualifiers.i:28: Error: Constructor cannot have a qualifier.
+cpp_invalid_qualifiers.i:29: Error: Constructor cannot have a qualifier.
+cpp_invalid_qualifiers.i:32: Error: Constructor cannot have a qualifier.
+cpp_invalid_qualifiers.i:33: Error: Constructor cannot have a qualifier.
+cpp_invalid_qualifiers.i:37: Error: Static function m1() const cannot have a qualifier.
+cpp_invalid_qualifiers.i:38: Error: Static function m2() & cannot have a qualifier.
+cpp_invalid_qualifiers.i:39: Error: Static function m3() && cannot have a qualifier.
+cpp_invalid_qualifiers.i:39: Warning 405: Method with rvalue ref-qualifier m3() && ignored.
+cpp_invalid_qualifiers.i:40: Error: Static function m4() const cannot have a qualifier.
+cpp_invalid_qualifiers.i:41: Error: Static function m5() & cannot have a qualifier.
+cpp_invalid_qualifiers.i:42: Error: Static function m6() && cannot have a qualifier.
+cpp_invalid_qualifiers.i:42: Warning 405: Method with rvalue ref-qualifier m6() && ignored.
diff --git a/Examples/test-suite/errors/cpp_invalid_template.i b/Examples/test-suite/errors/cpp_invalid_template.i
new file mode 100644
index 0000000..ea0d7be
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_invalid_template.i
@@ -0,0 +1,9 @@
+%module cpp_invalid_scope
+
+%template(abc) SSS::AAA<int>;
+
+namespace UUU {
+  struct JJJ;
+}
+
+%template(xxx) UUU::JJJ<int>;
diff --git a/Examples/test-suite/errors/cpp_invalid_template.stderr b/Examples/test-suite/errors/cpp_invalid_template.stderr
new file mode 100644
index 0000000..f6bfaaf
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_invalid_template.stderr
@@ -0,0 +1,3 @@
+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_namespace_template_bad.i b/Examples/test-suite/errors/cpp_namespace_template_bad.i
new file mode 100644
index 0000000..5c42d6d
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_namespace_template_bad.i
@@ -0,0 +1,40 @@
+%module namespace_template
+
+namespace test {
+  template<typename T> T max(T a, T b) { return (a > b) ? a : b; }
+  template<typename T> class vector { 
+  public:
+    vector() { }
+    ~vector() { }
+  }; 
+}
+
+namespace test2 {
+  using namespace test;
+  %template(maxshort) max<short>;
+  %template(vectorshort) vector<short>;
+}
+
+namespace test3 {
+  using test::max;
+  using test::vector;
+  %template(maxlong) max<long>;
+  %template(vectorlong) vector<long>;
+}
+
+namespace test4 {
+  using namespace test;
+  typedef int Integer;
+}
+
+namespace test4 {
+  %template(maxInteger) max<Integer>;
+  %template(vectorInteger) vector<Integer>;
+}
+
+using namespace test;
+namespace test5 {
+  %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
new file mode 100644
index 0000000..5965d52
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_namespace_template_bad.stderr
@@ -0,0 +1,9 @@
+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'.
diff --git a/Examples/test-suite/errors/cpp_nested_template.stderr b/Examples/test-suite/errors/cpp_nested_template.stderr
index 9e46cff..363a260 100644
--- a/Examples/test-suite/errors/cpp_nested_template.stderr
+++ b/Examples/test-suite/errors/cpp_nested_template.stderr
@@ -1,2 +1,4 @@
+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_refqualifier.i b/Examples/test-suite/errors/cpp_refqualifier.i
new file mode 100644
index 0000000..afd6632
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_refqualifier.i
@@ -0,0 +1,28 @@
+%module cpp_refqualifier
+
+%ignore Host::h_ignored;
+%ignore Host::i_ignored() &&;
+%ignore Host::j_ignored() const &&;
+
+class Host {
+public:
+  void h1() &;
+  void h2() const &;
+  void h3() &&;
+  void h4() const &&;
+
+  void h() &;
+  void h() const &;
+  void h() &&;
+  void h() const &&;
+
+  void h_ignored() &&;
+  void i_ignored() &&;
+  void i_ignored() &&;
+};
+
+%feature("ignore", "0") Unignore::k_unignored() const &&;
+
+struct Unignore {
+  void k_unignored() const &&;
+};
diff --git a/Examples/test-suite/errors/cpp_refqualifier.stderr b/Examples/test-suite/errors/cpp_refqualifier.stderr
new file mode 100644
index 0000000..ea2cd22
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_refqualifier.stderr
@@ -0,0 +1,6 @@
+cpp_refqualifier.i:11: Warning 405: Method with rvalue ref-qualifier h3() && ignored.
+cpp_refqualifier.i:12: Warning 405: Method with rvalue ref-qualifier h4() const && ignored.
+cpp_refqualifier.i:16: Warning 405: Method with rvalue ref-qualifier h() && ignored.
+cpp_refqualifier.i:17: Warning 405: Method with rvalue ref-qualifier h() const && ignored.
+cpp_refqualifier.i:15: Warning 512: Overloaded method Host::h() const & ignored,
+cpp_refqualifier.i:14: Warning 512: using non-const method Host::h() & instead.
diff --git a/Examples/test-suite/errors/cpp_template_scope.i b/Examples/test-suite/errors/cpp_template_scope.i
new file mode 100644
index 0000000..ec0f0a5
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_scope.i
@@ -0,0 +1,57 @@
+%module xxx
+
+namespace std {
+  template<typename T> class vector {};
+}
+
+struct S1 {};
+struct S2 {};
+struct S3 {};
+struct S4 {};
+struct S5 {};
+struct S6 {};
+struct S7 {};
+
+// valid
+namespace std {
+  %template(vi1) vector<S1>;
+  template class vector<S1>;
+}
+
+// valid
+using namespace std;
+%template(vi2) vector<S2>;
+template class vector<S2>;
+
+// valid
+using std::vector;
+%template(vi3) vector<S3>;
+template class vector<S3>;
+
+// ill-formed
+namespace unrelated {
+  using std::vector;
+  %template(vi4) vector<S4>;
+  template class vector<S4>;
+}
+
+// ill-formed
+namespace unrelated {
+  using namespace std;
+  %template(vi5) vector<S5>;
+  template class vector<S5>;
+}
+
+// ill-formed
+namespace unrelated {
+  namespace std {
+    %template(vi6) vector<S6>;
+    template class vector<S6>;
+  }
+}
+
+// ill-formed
+namespace unrelated {
+  %template(vi7) std::vector<S7>;
+  template class std::vector<S7>;
+}
diff --git a/Examples/test-suite/errors/cpp_template_scope.stderr b/Examples/test-suite/errors/cpp_template_scope.stderr
new file mode 100644
index 0000000..e476302
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_scope.stderr
@@ -0,0 +1,11 @@
+cpp_template_scope.i:18: Warning 320: Explicit template instantiation ignored.
+cpp_template_scope.i:24: Warning 320: Explicit template instantiation ignored.
+cpp_template_scope.i:29: Warning 320: Explicit template instantiation ignored.
+cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
+cpp_template_scope.i:35: Warning 320: Explicit template instantiation ignored.
+cpp_template_scope.i:41: Error: 'vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
+cpp_template_scope.i:42: Warning 320: Explicit template instantiation ignored.
+cpp_template_scope.i:48: Error: 'vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated::std' instead of within scope 'std'.
+cpp_template_scope.i:49: Warning 320: Explicit template instantiation ignored.
+cpp_template_scope.i:55: Error: 'std::vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
+cpp_template_scope.i:56: Warning 320: Explicit template instantiation ignored.
diff --git a/Examples/test-suite/ignore_template_constructor.i b/Examples/test-suite/ignore_template_constructor.i
index 31a5505..bdffbec 100644
--- a/Examples/test-suite/ignore_template_constructor.i
+++ b/Examples/test-suite/ignore_template_constructor.i
@@ -1,12 +1,18 @@
 %module ignore_template_constructor
 %include std_vector.i
 
-#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL) || defined(SWIGRUBY) 
+#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL) || defined(SWIGRUBY)
 #define SWIG_GOOD_VECTOR
 %ignore std::vector<Flow>::vector(size_type);
 %ignore std::vector<Flow>::resize(size_type);
 #endif
 
+#if defined(SWIGJAVA)
+#define SWIG_GOOD_VECTOR
+%ignore std::vector<Flow>::vector(jint);
+%ignore std::vector<Flow>::resize(jint);
+#endif
+
 #if defined(SWIGTCL) || defined(SWIGPERL)
 #define SWIG_GOOD_VECTOR
 /* here, for languages with bad declaration */
diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in
index d63a258..5036312 100644
--- a/Examples/test-suite/java/Makefile.in
+++ b/Examples/test-suite/java/Makefile.in
@@ -40,6 +40,7 @@
 	java_throws \
 	java_typemaps_proxy \
 	java_typemaps_typewrapper \
+	li_std_list \
 #	li_boost_intrusive_ptr
 
 CPP11_TEST_CASES = \
diff --git a/Examples/test-suite/java/class_scope_namespace_runme.java b/Examples/test-suite/java/class_scope_namespace_runme.java
new file mode 100644
index 0000000..9d74a6c
--- /dev/null
+++ b/Examples/test-suite/java/class_scope_namespace_runme.java
@@ -0,0 +1,59 @@
+
+import class_scope_namespace.*;
+
+public class class_scope_namespace_runme {
+
+  static {
+    try {
+      System.loadLibrary("class_scope_namespace");
+    } 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[]) 
+  {
+    A a = new A();
+    B b = new B();
+    C c = new C();
+    D d = new D();
+    E e = new E();
+    F f = new F();
+    G g = new G();
+    H.HH h = new H.HH();
+    I.II i = new I.II();
+    J j = new J();
+    K k = new K();
+    L l = new L();
+    M m = new M();
+
+    a.aa(a, a, a);
+    b.bb(b, b);
+    c.cc(c, c);
+    d.dd(d, d, d);
+    e.ee(e, e, e);
+    f.ff(f, f, f, f);
+    g.gg(g, g);
+    h.hh(h);
+    i.ii(i, i);
+    j.jj(j, j, j);
+    k.kk(k, k, k);
+    l.ll(l, l, l);
+    m.mm(m, m, m);
+
+    class_scope_namespace.aaa(a, a, a);
+    class_scope_namespace.bbb(b, b);
+    class_scope_namespace.ccc(c, c);
+    class_scope_namespace.ddd(d, d, d);
+    class_scope_namespace.eee(e, e, e);
+    class_scope_namespace.fff(f, f, f, f);
+    class_scope_namespace.ggg(g, g);
+    class_scope_namespace.hhh(h);
+    class_scope_namespace.iii(i, i);
+    class_scope_namespace.jjj(j, j, j);
+    class_scope_namespace.kkk(k, k, k);
+    class_scope_namespace.lll(l, l, l);
+    class_scope_namespace.mmm(m, m, m);
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_ref_qualifiers_runme.java b/Examples/test-suite/java/cpp11_ref_qualifiers_runme.java
new file mode 100644
index 0000000..4755f8d
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_ref_qualifiers_runme.java
@@ -0,0 +1,56 @@
+
+import cpp11_ref_qualifiers.*;
+
+public class cpp11_ref_qualifiers_runme {
+
+  static {
+    try {
+      System.loadLibrary("cpp11_ref_qualifiers");
+    } 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[]) {
+    Host h = new Host();
+
+    // Basic testing
+    h.h1();
+    h.h2();
+    h.h6();
+    h.h7();
+
+    h.h();
+
+    // %feature testing
+    Features f = new Features();
+    if (!f.F1().equals("F1")) throw new RuntimeException("Fail");
+    if (!f.F2().equals("F2")) throw new RuntimeException("Fail");
+    if (!f.F3().equals("F3")) throw new RuntimeException("Fail");
+
+    if (!f.C1(0).equals("C1")) throw new RuntimeException("Fail");
+    if (!f.C2(0).equals("C2")) throw new RuntimeException("Fail");
+    if (!f.C3(0).equals("C3")) throw new RuntimeException("Fail");
+
+    // %rename testing
+    Renames r = new Renames();
+    r.RR1();
+    r.RR2();
+    r.RR3();
+
+    r.SS1(0);
+    r.SS2(0);
+    r.SS3(0);
+
+    // Conversion operators
+    String s = null;
+    ConversionOperators co = new ConversionOperators();
+    s = co.StringConvertCopy();
+    s = co.StringConvertMove();
+
+    ConversionOperators2 co2 = new ConversionOperators2();
+    s = co2.StringConvertMove();
+  }
+}
+
diff --git a/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java b/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java
new file mode 100644
index 0000000..bbbe6f7
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java
@@ -0,0 +1,20 @@
+
+import cpp11_ref_qualifiers_rvalue_unignore.*;
+
+public class cpp11_ref_qualifiers_rvalue_unignore_runme {
+
+  static {
+    try {
+      System.loadLibrary("cpp11_ref_qualifiers_rvalue_unignore");
+    } 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 RefQualifier().m1();
+    new RefQualifier().m2();
+  }
+}
+
diff --git a/Examples/test-suite/java/cpp11_ref_qualifiers_typemaps_runme.java b/Examples/test-suite/java/cpp11_ref_qualifiers_typemaps_runme.java
new file mode 100644
index 0000000..8c6a21b
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_ref_qualifiers_typemaps_runme.java
@@ -0,0 +1,39 @@
+import cpp11_ref_qualifiers_typemaps.*;
+
+public class cpp11_ref_qualifiers_typemaps_runme {
+  static {
+    try {
+      System.loadLibrary("cpp11_ref_qualifiers_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[]) 
+  {
+    {
+      TypemapsNamedParms tm = new TypemapsNamedParms();
+      if (tm.fff(cpp11_ref_qualifiers_typemaps.FF1_MFP) != 2)
+        throw new RuntimeException("failed");
+      if (tm.ccc(cpp11_ref_qualifiers_typemaps.CC4_MFP) != 5)
+        throw new RuntimeException("failed");
+      if (tm.ggg(cpp11_ref_qualifiers_typemaps.GG7_MFP) != 8)
+        throw new RuntimeException("failed");
+      if (tm.hhh(cpp11_ref_qualifiers_typemaps.HH10_MFP) != 11)
+        throw new RuntimeException("failed");
+    }
+    {
+      TypemapsUnnamedParms tm = new TypemapsUnnamedParms();
+      if (tm.fff(cpp11_ref_qualifiers_typemaps.FF1_MFP) != 3)
+        throw new RuntimeException("failed");
+      if (tm.ccc(cpp11_ref_qualifiers_typemaps.CC4_MFP) != 6)
+        throw new RuntimeException("failed");
+      if (tm.ggg(cpp11_ref_qualifiers_typemaps.GG7_MFP) != 9)
+        throw new RuntimeException("failed");
+      if (tm.hhh(cpp11_ref_qualifiers_typemaps.HH10_MFP) != 12)
+        throw new RuntimeException("failed");
+    }
+  }
+}
+
diff --git a/Examples/test-suite/java/cpp11_template_typedefs_runme.java b/Examples/test-suite/java/cpp11_template_typedefs_runme.java
new file mode 100644
index 0000000..473e7cf
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_template_typedefs_runme.java
@@ -0,0 +1,19 @@
+import cpp11_template_typedefs.*;
+
+public class cpp11_template_typedefs_runme {
+
+  static {
+    try {
+      System.loadLibrary("cpp11_template_typedefs");
+    } 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 alloc1 = cpp11_template_typedefs.get_bucket_allocator1();
+    int alloc2 = cpp11_template_typedefs.get_bucket_allocator2();
+  }
+}
+
diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java
new file mode 100644
index 0000000..e45b896
--- /dev/null
+++ b/Examples/test-suite/java/li_std_list_runme.java
@@ -0,0 +1,180 @@
+import li_std_list.*;
+
+public class li_std_list_runme {
+
+  static {
+    try {
+        System.loadLibrary("li_std_list");
+    } 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
+  {
+    IntList v1 = new IntList();
+    DoubleList v2 = new DoubleList();
+
+    if (!v1.isEmpty()) throw new RuntimeException("v1 test (1) failed");
+    if (v1.size() != 0) throw new RuntimeException("v1 test (2) failed");
+    if (!v1.add(123)) throw new RuntimeException("v1 test (3) failed");
+    if (v1.size() != 1) throw new RuntimeException("v1 test (4) failed");
+    if (v1.isEmpty()) throw new RuntimeException("v1 test (5) failed");
+
+    int sum = 0;
+    for (int n : v1) {
+      if (n != 123) throw new RuntimeException("v1 loop test failed");
+      sum += n;
+    }
+    if (sum != 123) throw new RuntimeException("v1 sum test failed");
+    if (v1.get(0) != 123) throw new RuntimeException("v1 test failed");
+    v1.clear();
+    if (!v1.isEmpty()) throw new RuntimeException("v1 test clear failed");
+    v1.add(123);
+
+    if (v1.set(0, 456) != 123) throw new RuntimeException("v1 test (6) failed");
+    if (v1.size() != 1) throw new RuntimeException("v1 test (7) failed");
+    if (v1.get(0) != 456) throw new RuntimeException("v1 test (8) failed");
+
+    java.util.Iterator<Integer> v1_iterator = v1.iterator();
+    if (!v1_iterator.hasNext()) throw new RuntimeException("v1 test (9) failed");
+    if (v1_iterator.next() != 456) throw new RuntimeException("v1 test (10) failed");
+    if (v1_iterator.hasNext()) throw new RuntimeException("v1 test (11) failed");
+    try {
+      v1_iterator.next();
+      throw new RuntimeException("v1 test (12) failed");
+    } catch (java.util.NoSuchElementException e) {
+    }
+
+    if (v1.remove(new Integer(123))) throw new RuntimeException("v1 test (13) failed");
+    if (!v1.remove(new Integer(456))) throw new RuntimeException("v1 test (14) failed");
+    if (!v1.isEmpty()) throw new RuntimeException("v1 test (15) failed");
+    if (v1.size() != 0) throw new RuntimeException("v1 test (16) failed");
+    if (v1.remove(new Integer(456))) throw new RuntimeException("v1 test (17) failed");
+
+    if (new IntList(3).size() != 3) throw new RuntimeException("constructor initial size test failed");
+    for (int n : new IntList(10, 999))
+      if (n != 999) throw new RuntimeException("constructor initialization with value failed");
+    for (int n : new IntList(new IntList(10, 999)))
+      if (n != 999) throw new RuntimeException("copy constructor initialization with value failed");
+
+    StructList v4 = new StructList();
+    StructPtrList v5 = new StructPtrList();
+    StructConstPtrList v6 = new StructConstPtrList();
+
+    v4.add(new Struct(12));
+    v5.add(new Struct(34));
+    v6.add(new Struct(56));
+
+    if (v4.get(0).getNum() != 12) throw new RuntimeException("v4 test failed");
+    if (v5.get(0).getNum() != 34) throw new RuntimeException("v5 test failed");
+    if (v6.get(0).getNum() != 56) throw new RuntimeException("v6 test failed");
+
+    for (Struct s : v4) {
+      if (s.getNum() != 12) throw new RuntimeException("v4 loop test failed");
+    }
+    for (Struct s : v5) {
+      if (s.getNum() != 34) throw new RuntimeException("v5 loop test failed");
+    }
+    for (Struct s : v6) {
+      if (s.getNum() != 56) throw new RuntimeException("v6 loop test failed");
+    }
+
+    StructList v7 = li_std_list.CopyContainerStruct(new StructList());
+    v7.add(new Struct(1));
+    v7.add(new Struct(23));
+    v7.add(new Struct(456));
+    v7.add(new Struct(7890));
+    if (v7.size() != 4) throw new RuntimeException("v7 test (1) failed");
+    {
+      double[] a7 = {1, 23, 456, 7890};
+      int i7 = 0;
+      for (Struct s7 : v7) {
+        if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (2) failed");
+        i7++;
+      }
+      if (i7 != a7.length) throw new RuntimeException("v7 test (3) failed");
+    }
+    if (v7.remove(2).getNum() != 456) throw new RuntimeException("v7 test (4) failed");
+    {
+      double[] a7 = {1, 23, 7890};
+      int i7 = 0;
+      for (Struct s7 : v7) {
+        if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (5) failed");
+        i7++;
+      }
+      if (i7 != a7.length) throw new RuntimeException("v7 test (6) failed");
+    }
+    v7.add(1, new Struct(123));
+    {
+      double[] a7 = {1, 123, 23, 7890};
+      int i7 = 0;
+      for (Struct s7 : v7) {
+        if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (7) failed");
+        i7++;
+      }
+      if (i7 != a7.length) throw new RuntimeException("v7 test (8) failed");
+    }
+
+    BoolList v8 = new BoolList();
+    if (!v8.add(true)) throw new RuntimeException("v8 test (1) failed");;
+    if (v8.get(0) != true) throw new RuntimeException("v8 test (2) failed");;
+    if (v8.set(0, false) != true) throw new RuntimeException("v8 test (3) failed");;
+    if (v8.set(0, false) != false) throw new RuntimeException("v8 test (4) failed");;
+    if (v8.size() != 1) throw new RuntimeException("v8 test (5) failed");;
+
+    java.util.ArrayList<Boolean> bl = new java.util.ArrayList<Boolean>(java.util.Arrays.asList(true, false, true, false));
+    BoolList bv = new BoolList(java.util.Arrays.asList(true, false, true, false));
+    BoolList bv2 = new BoolList(bl);
+    java.util.ArrayList<Boolean> bl2 = new java.util.ArrayList<Boolean>(bv);
+    boolean bbb1 = bv.get(0);
+    Boolean bbb2 = bv.get(0);
+
+    IntList v9 = new IntList(java.util.Arrays.asList(10, 20, 30, 40));
+    v9.add(50);
+    v9.add(60);
+    v9.add(70);
+    if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed");
+    if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed");
+    if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed");
+    v9.addFirst(-10);
+    v9.addLast(80);
+    if (v9.size() != 8) throw new RuntimeException("v9 test (4) failed");
+    if (v9.get(0) != -10) throw new RuntimeException("v9 test (5) failed");;
+    if (v9.get(v9.size()-1) != 80) throw new RuntimeException("v9 test (6) failed");;
+    v9.removeFirst();
+    if (v9.get(0) != 10) throw new RuntimeException("v9 test (7) failed");;
+    v9.removeLast();
+    if (v9.size() != 6) throw new RuntimeException("v9 test (8) failed");
+    if (v9.get(v9.size()-1) != 70) throw new RuntimeException("v9 test (9) failed");;
+
+    IntList v10 = new IntList(java.util.Arrays.asList(10, 20, 30, 40, 50));
+    v10.subList(1, 4).clear(); // Recommended way to call protected method removeRange(1,3)
+    if (v10.size() != 2) throw new RuntimeException("v10 test (1) failed");
+    if (v10.get(0) != 10) throw new RuntimeException("v10 test (2) failed");
+    if (v10.get(1) != 50) throw new RuntimeException("v10 test (3) failed");
+    v10.addAll(1, java.util.Arrays.asList(22, 33));
+    if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed");
+    if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed");
+    if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed");
+
+    v10.add(v10.size(), 55);
+    if (v10.size() != 5) throw new RuntimeException("v10 test (7) failed");
+    if (v10.get(4) != 55) throw new RuntimeException("v10 test (8) failed");
+
+    IntList v11 = new IntList(java.util.Arrays.asList(11, 22, 33, 44));
+    v11.listIterator(0);
+    v11.listIterator(v11.size());
+    try {
+      v11.listIterator(v11.size() + 1);
+      throw new RuntimeException("v11 test (1) failed");
+    } catch (IndexOutOfBoundsException e) {
+    }
+    try {
+      v11.listIterator(-1);
+      throw new RuntimeException("v11 test (2) failed");
+    } catch (IndexOutOfBoundsException e) {
+    }
+  }
+}
diff --git a/Examples/test-suite/java/li_std_vector_runme.java b/Examples/test-suite/java/li_std_vector_runme.java
index 60776bb..d23bbe7 100644
--- a/Examples/test-suite/java/li_std_vector_runme.java
+++ b/Examples/test-suite/java/li_std_vector_runme.java
@@ -17,15 +17,23 @@
     IntPtrVector v2 = li_std_vector.vecintptr(new IntPtrVector());
     IntConstPtrVector v3 = li_std_vector.vecintconstptr(new IntConstPtrVector());
 
-    for (int n : v1) {
-        if (n != 123) throw new RuntimeException("v1 loop test failed");
-    }
-
     if (!v1.isEmpty()) throw new RuntimeException("v1 test (1) failed");
     if (v1.size() != 0) throw new RuntimeException("v1 test (2) failed");
     if (!v1.add(123)) throw new RuntimeException("v1 test (3) failed");
     if (v1.size() != 1) throw new RuntimeException("v1 test (4) failed");
     if (v1.isEmpty()) throw new RuntimeException("v1 test (5) failed");
+
+    int sum = 0;
+    for (int n : v1) {
+      if (n != 123) throw new RuntimeException("v1 loop test failed");
+      sum += n;
+    }
+    if (sum != 123) throw new RuntimeException("v1 sum test failed");
+    if (v1.get(0) != 123) throw new RuntimeException("v1 test failed");
+    v1.clear();
+    if (!v1.isEmpty()) throw new RuntimeException("v1 test clear failed");
+    v1.add(123);
+
     if (v1.set(0, 456) != 123) throw new RuntimeException("v1 test (6) failed");
     if (v1.size() != 1) throw new RuntimeException("v1 test (7) failed");
     if (v1.get(0) != 456) throw new RuntimeException("v1 test (8) failed");
@@ -46,6 +54,12 @@
     if (v1.size() != 0) throw new RuntimeException("v1 test (16) failed");
     if (v1.remove(new Integer(456))) throw new RuntimeException("v1 test (17) failed");
 
+    if (new IntVector(3).size() != 3) throw new RuntimeException("constructor initial size test failed");
+    for (int n : new IntVector(10, 999))
+      if (n != 999) throw new RuntimeException("constructor initialization with value failed");
+    for (int n : new IntVector(new IntVector(10, 999)))
+      if (n != 999) throw new RuntimeException("copy constructor initialization with value failed");
+
     StructVector v4 = li_std_vector.vecstruct(new StructVector());
     StructPtrVector v5 = li_std_vector.vecstructptr(new StructPtrVector());
     StructConstPtrVector v6 = li_std_vector.vecstructconstptr(new StructConstPtrVector());
@@ -59,13 +73,13 @@
     if (v6.get(0).getNum() != 56) throw new RuntimeException("v6 test failed");
 
     for (Struct s : v4) {
-        if (s.getNum() != 12) throw new RuntimeException("v4 loop test failed");
+      if (s.getNum() != 12) throw new RuntimeException("v4 loop test failed");
     }
     for (Struct s : v5) {
-        if (s.getNum() != 34) throw new RuntimeException("v5 loop test failed");
+      if (s.getNum() != 34) throw new RuntimeException("v5 loop test failed");
     }
     for (Struct s : v6) {
-        if (s.getNum() != 56) throw new RuntimeException("v6 loop test failed");
+      if (s.getNum() != 56) throw new RuntimeException("v6 loop test failed");
     }
 
     StructVector v7 = li_std_vector.vecstruct(new StructVector());
@@ -117,5 +131,41 @@
     java.util.ArrayList<Boolean> bl2 = new java.util.ArrayList<Boolean>(bv);
     boolean bbb1 = bv.get(0);
     Boolean bbb2 = bv.get(0);
+
+    IntVector v9 = new IntVector(java.util.Arrays.asList(10, 20, 30, 40));
+    v9.add(50);
+    v9.add(60);
+    v9.add(70);
+    if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed");
+    if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed");
+    if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed");
+
+    IntVector v10 = new IntVector(java.util.Arrays.asList(10, 20, 30, 40, 50));
+    v10.subList(1, 4).clear(); // Recommended way to call protected method removeRange(1,3)
+    if (v10.size() != 2) throw new RuntimeException("v10 test (1) failed");
+    if (v10.get(0) != 10) throw new RuntimeException("v10 test (2) failed");
+    if (v10.get(1) != 50) throw new RuntimeException("v10 test (3) failed");
+    v10.addAll(1, java.util.Arrays.asList(22, 33));
+    if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed");
+    if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed");
+    if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed");
+
+    v10.add(v10.size(), 55);
+    if (v10.size() != 5) throw new RuntimeException("v10 test (7) failed");
+    if (v10.get(4) != 55) throw new RuntimeException("v10 test (8) failed");
+
+    IntVector v11 = new IntVector(java.util.Arrays.asList(11, 22, 33, 44));
+    v11.listIterator(0);
+    v11.listIterator(v11.size());
+    try {
+      v11.listIterator(v11.size() + 1);
+      throw new RuntimeException("v11 test (1) failed");
+    } catch (IndexOutOfBoundsException e) {
+    }
+    try {
+      v11.listIterator(-1);
+      throw new RuntimeException("v11 test (2) failed");
+    } catch (IndexOutOfBoundsException e) {
+    }
   }
 }
diff --git a/Examples/test-suite/java/namespace_chase_runme.java b/Examples/test-suite/java/namespace_chase_runme.java
new file mode 100644
index 0000000..9b4898b
--- /dev/null
+++ b/Examples/test-suite/java/namespace_chase_runme.java
@@ -0,0 +1,26 @@
+
+import namespace_chase.*;
+
+public class namespace_chase_runme {
+
+  static {
+    try {
+      System.loadLibrary("namespace_chase");
+    } 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[]) 
+  {
+    Struct1A s1a = new Struct1A();
+    Struct1B s1b = new Struct1B();
+    Struct1C s1c = new Struct1C();
+
+    namespace_chase.sss3a(s1a, s1b, s1c);
+    namespace_chase.sss3b(s1a, s1b, s1c);
+    // needs fixing
+//    namespace_chase.sss3c(s1a, s1b, s1c);
+  }
+}
diff --git a/Examples/test-suite/java/namespace_template_runme.java b/Examples/test-suite/java/namespace_template_runme.java
new file mode 100644
index 0000000..c0c7ba1
--- /dev/null
+++ b/Examples/test-suite/java/namespace_template_runme.java
@@ -0,0 +1,32 @@
+
+import namespace_template.*;
+
+public class namespace_template_runme {
+
+  static {
+    try {
+      System.loadLibrary("namespace_template");
+    } 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[]) {
+    vectorchar vc = new vectorchar();
+    vectorshort vs = new vectorshort();
+    vectorint vi = new vectorint();
+    vectorlong vl = new vectorlong();
+
+    vc.blah((char)10);
+    vs.blah((short)10);
+    vi.blah(10);
+    vl.blah(10);
+
+    vc.vectoruse(vc, vc);
+    vs.vectoruse(vs, vs);
+    vi.vectoruse(vi, vi);
+    vl.vectoruse(vl, vl);
+  }
+}
+
diff --git a/Examples/test-suite/java/template_parameters_global_scope_runme.java b/Examples/test-suite/java/template_parameters_global_scope_runme.java
new file mode 100644
index 0000000..a536fe4
--- /dev/null
+++ b/Examples/test-suite/java/template_parameters_global_scope_runme.java
@@ -0,0 +1,75 @@
+import template_parameters_global_scope.*;
+
+public class template_parameters_global_scope_runme {
+
+  static {
+    try {
+      System.loadLibrary("template_parameters_global_scope");
+    } 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 alloc = 0;
+
+    // Check 1
+    alloc = template_parameters_global_scope.Bucket1();
+    alloc = template_parameters_global_scope.Bucket2();
+    alloc = template_parameters_global_scope.Bucket3();
+    alloc = template_parameters_global_scope.Bucket4();
+    alloc = template_parameters_global_scope.Bucket5();
+    alloc = template_parameters_global_scope.Bucket6();
+
+    // Check 2
+    alloc = template_parameters_global_scope.Spade1();
+    alloc = template_parameters_global_scope.Spade2();
+    alloc = template_parameters_global_scope.Spade3();
+    alloc = template_parameters_global_scope.Spade4();
+    alloc = template_parameters_global_scope.Spade5();
+    alloc = template_parameters_global_scope.Spade6();
+
+    // Check 3
+    alloc = template_parameters_global_scope.Ball1();
+    alloc = template_parameters_global_scope.Ball2();
+    alloc = template_parameters_global_scope.Ball3();
+    alloc = template_parameters_global_scope.Ball4();
+    alloc = template_parameters_global_scope.Ball5();
+    alloc = template_parameters_global_scope.Ball6();
+
+    // Check 4
+    alloc = template_parameters_global_scope.Bat1();
+    alloc = template_parameters_global_scope.Bat2();
+    alloc = template_parameters_global_scope.Bat3();
+    alloc = template_parameters_global_scope.Bat4();
+    alloc = template_parameters_global_scope.Bat5();
+    alloc = template_parameters_global_scope.Bat6();
+
+    // Check 5
+    alloc = template_parameters_global_scope.Chair1();
+    alloc = template_parameters_global_scope.Chair2();
+    alloc = template_parameters_global_scope.Chair3();
+    alloc = template_parameters_global_scope.Chair4();
+    alloc = template_parameters_global_scope.Chair5();
+    alloc = template_parameters_global_scope.Chair6();
+
+    // Check 6
+    alloc = template_parameters_global_scope.Table1();
+    alloc = template_parameters_global_scope.Table2();
+    alloc = template_parameters_global_scope.Table3();
+    alloc = template_parameters_global_scope.Table4();
+    alloc = template_parameters_global_scope.Table5();
+    alloc = template_parameters_global_scope.Table6();
+
+    /*
+    alloc = template_parameters_global_scope.rejig1();
+    alloc = template_parameters_global_scope.rejig2();
+    alloc = template_parameters_global_scope.rejig3();
+    alloc = template_parameters_global_scope.rejig4();
+    alloc = template_parameters_global_scope.rejig5();
+    alloc = template_parameters_global_scope.rejig6();
+    */
+  }
+}
diff --git a/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java b/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java
index 080945e..3aab5fa 100644
--- a/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java
+++ b/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java
@@ -19,32 +19,32 @@
     template_using_directive_and_declaration_forward.useit1b(new Thing1Int());
     template_using_directive_and_declaration_forward.useit1c(new Thing1Int());
 
-//BROKEN    template_using_directive_and_declaration_forward.useit2(new Thing2Int());
+    template_using_directive_and_declaration_forward.useit2(new Thing2Int());
     template_using_directive_and_declaration_forward.useit2a(new Thing2Int());
     template_using_directive_and_declaration_forward.useit2b(new Thing2Int());
     template_using_directive_and_declaration_forward.useit2c(new Thing2Int());
     template_using_directive_and_declaration_forward.useit2d(new Thing2Int());
 
-//BROKEN    template_using_directive_and_declaration_forward.useit3(new Thing3Int());
+    template_using_directive_and_declaration_forward.useit3(new Thing3Int());
     template_using_directive_and_declaration_forward.useit3a(new Thing3Int());
     template_using_directive_and_declaration_forward.useit3b(new Thing3Int());
     template_using_directive_and_declaration_forward.useit3c(new Thing3Int());
     template_using_directive_and_declaration_forward.useit3d(new Thing3Int());
 
-//BROKEN    template_using_directive_and_declaration_forward.useit4(new Thing4Int());
+    template_using_directive_and_declaration_forward.useit4(new Thing4Int());
     template_using_directive_and_declaration_forward.useit4a(new Thing4Int());
     template_using_directive_and_declaration_forward.useit4b(new Thing4Int());
     template_using_directive_and_declaration_forward.useit4c(new Thing4Int());
     template_using_directive_and_declaration_forward.useit4d(new Thing4Int());
 
-//BROKEN    template_using_directive_and_declaration_forward.useit5(new Thing5Int());
+    template_using_directive_and_declaration_forward.useit5(new Thing5Int());
     template_using_directive_and_declaration_forward.useit5a(new Thing5Int());
     template_using_directive_and_declaration_forward.useit5b(new Thing5Int());
     template_using_directive_and_declaration_forward.useit5c(new Thing5Int());
     template_using_directive_and_declaration_forward.useit5d(new Thing5Int());
 
 
-//BROKEN    template_using_directive_and_declaration_forward.useit7(new Thing7Int());
+    template_using_directive_and_declaration_forward.useit7(new Thing7Int());
     template_using_directive_and_declaration_forward.useit7a(new Thing7Int());
     template_using_directive_and_declaration_forward.useit7b(new Thing7Int());
     template_using_directive_and_declaration_forward.useit7c(new Thing7Int());
diff --git a/Examples/test-suite/java/template_using_directive_typedef_runme.java b/Examples/test-suite/java/template_using_directive_typedef_runme.java
new file mode 100644
index 0000000..bec0773
--- /dev/null
+++ b/Examples/test-suite/java/template_using_directive_typedef_runme.java
@@ -0,0 +1,31 @@
+
+import template_using_directive_typedef.*;
+
+public class template_using_directive_typedef_runme {
+
+  static {
+    try {
+      System.loadLibrary("template_using_directive_typedef");
+    } 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[]) {
+    Vector_Obj vo = new Vector_Obj();
+
+    Holder h = new 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/li_std_list.i b/Examples/test-suite/li_std_list.i
index bae475e..d1ec4e7 100644
--- a/Examples/test-suite/li_std_list.i
+++ b/Examples/test-suite/li_std_list.i
@@ -1,6 +1,7 @@
 %module li_std_list
 
 %include "std_list.i"
+%include "std_string.i"
 
 %{
 #include <algorithm>
@@ -8,19 +9,18 @@
 #include <numeric>
 %}
 
-namespace std {
-    %template(IntList) list<int>;
-}
-
+%template(BoolList) std::list<bool>;
+%template(CharList) std::list<char>;
+%template(ShortList) std::list<short>;
+%template(IntList) std::list<int>;
+%template(LongList) std::list<long>;
+%template(UCharList) std::list<unsigned char>;
+%template(UIntList) std::list<unsigned int>;
+%template(UShortList) std::list<unsigned short>;
+%template(ULongList) std::list<unsigned long>;
+%template(FloatList) std::list<float>;
 %template(DoubleList) std::list<double>;
-
-%inline %{
-typedef float Real;
-%}
-
-namespace std {
-    %template(RealList) list<Real>;
-}
+%template(StringList) std::list<std::string>;
 
 %inline %{
 
@@ -40,7 +40,21 @@
   Struct(double d) : num(d) {}
 //  bool operator==(const Struct &other) { return (num == other.num); }
 };
+
+const std::list<Struct> & CopyContainerStruct(const std::list<Struct> & container) { return container; }
+const std::list<Struct *> & CopyContainerStructPtr(const std::list<Struct *> & container) { return container; }
+const std::list<const Struct *> & CopyContainerStructConstPtr(const std::list<const Struct *> & container) { return container; }
+
+enum Fruit {
+  APPLE,
+  BANANNA,
+  PEAR,
+  KIWI,
+};
 %}
 
+%template(StructList) std::list<Struct>;
+%template(StructPtrList) std::list<Struct*>;
+%template(StructConstPtrList) std::list<const Struct *>;
 
-
+%template(FruitList) std::list<enum Fruit>;
diff --git a/Examples/test-suite/li_std_wstring.i b/Examples/test-suite/li_std_wstring.i
index 3c2d6f1..fe1166b 100644
--- a/Examples/test-suite/li_std_wstring.i
+++ b/Examples/test-suite/li_std_wstring.i
@@ -78,6 +78,10 @@
    return x;
 }
 
+bool test_equal_abc(const std::wstring &s) {
+  return L"abc" == s;
+}
+
 #if defined(_MSC_VER)
   #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
 #endif
diff --git a/Examples/test-suite/member_funcptr_galore.i b/Examples/test-suite/member_funcptr_galore.i
index 27d7a38..27c2f02 100644
--- a/Examples/test-suite/member_funcptr_galore.i
+++ b/Examples/test-suite/member_funcptr_galore.i
@@ -6,6 +6,12 @@
 %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) pp3;
 %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) pp5;
 
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra2;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra3;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc2;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc3;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc5;
+
 %{
 #if defined(__SUNPRO_CC)
 #pragma error_messages (off, badargtype2w) /* Formal argument ... is being passed extern "C" ... */
@@ -155,7 +161,7 @@
     int qqq7(short (Funcs::* const& qq7)(bool)) const;
 };
 
-    // member const function pointers, unnamed parameters
+// member const function pointers, unnamed parameters
 int MemberFuncPtrs::aaa1(short (Funcs::* )(bool) const) const { return 0; }
 int MemberFuncPtrs::aaa2(short (Funcs::* const *&)(bool) const) const { return 0; }
 int MemberFuncPtrs::aaa3(short (Funcs::* *& )(bool) const) const { return 0; }
@@ -191,7 +197,7 @@
 int MemberFuncPtrs::qqq6(short (Funcs::* const qq6)(bool)) const { return 0; }
 int MemberFuncPtrs::qqq7(short (Funcs::* const& qq7)(bool)) const { return 0; }
 
-// member function pointer variables
+// member non-const function pointer variables
 short (Funcs::* pp1)(bool) = &Funcs::FF;
 
 short (Funcs::* const * extra2)(bool) = &pp1;
@@ -204,4 +210,18 @@
 short (Funcs::* & pp5)(bool) = pp1;
 short (Funcs::* const pp6)(bool) = &Funcs::FF;
 short (Funcs::* const& pp7)(bool) = pp1;
+
+// member const function pointer variables
+short (Funcs::* cc1)(bool) const = &Funcs::CC;
+
+short (Funcs::* const * ccextra2)(bool) const = &cc1;
+short (Funcs::* * ccextra3)(bool) const = &cc1;
+short (Funcs::* *const ccextra4)(bool) const = &cc1;
+
+short (Funcs::* const *& cc2)(bool) const = ccextra2;
+short (Funcs::* *& cc3)(bool) const = ccextra3;
+short (Funcs::* *const& cc4)(bool) const = ccextra4;
+short (Funcs::* & cc5)(bool) const = cc1;
+short (Funcs::* const cc6)(bool) const = &Funcs::CC;
+short (Funcs::* const& cc7)(bool) const = cc1;
 %}
diff --git a/Examples/test-suite/namespace_chase.i b/Examples/test-suite/namespace_chase.i
new file mode 100644
index 0000000..5e3921d
--- /dev/null
+++ b/Examples/test-suite/namespace_chase.i
@@ -0,0 +1,36 @@
+%module namespace_chase
+
+%inline %{
+  namespace Space1A {
+    struct Struct1A {};
+    namespace Space1B {
+      struct Struct1B {};
+      namespace Space1C {
+        struct Struct1C {};
+      }
+    }
+  }
+  namespace Space2A {
+    using namespace Space1A;
+    namespace Space2B {
+      using namespace Space1B;
+      namespace Space2C {
+        using namespace Space1C;
+      }
+    }
+  }
+  namespace Space3 {
+    using namespace Space2A;
+    void sss3a(Space1A::Struct1A, Space1A::Space1B::Struct1B, Space1A::Space1B::Space1C::Struct1C) {}
+    void sss3b(Struct1A, Space1B::Struct1B, Space1B::Space1C::Struct1C) {}
+    // To fix: the last two parameters below fail and result in SWIGTYPE_ types instead of proxy classes
+    void sss3c(Space2A::Struct1A, Space2A::Space1B::Struct1B, Space2A::Space1B::Space1C::Struct1C) {}
+  }
+  namespace Space4 {
+    using namespace Space2A;
+    using namespace Space2A::Space2B;
+    using namespace Space2A::Space2B::Space2C;
+    void sss4a(Struct1A, Struct1B, Space2C::Struct1C) {}
+    void sss4b(Struct1A, Struct1B, Struct1C) {}
+  }
+%}
diff --git a/Examples/test-suite/namespace_template.i b/Examples/test-suite/namespace_template.i
index a36abb1..8a4b6dc 100644
--- a/Examples/test-suite/namespace_template.i
+++ b/Examples/test-suite/namespace_template.i
@@ -2,10 +2,10 @@
 
 %module namespace_template
 
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) vector<int>;            /* Ruby, wrong class name */
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test2::vector<short>;   /* Ruby, wrong class name */
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test3::vector<long>;    /* Ruby, wrong class name */
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) vector<test4::Integer>; /* Ruby, wrong class name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector<int>;        /* Ruby, wrong class name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector<short>;      /* Ruby, wrong class name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector<long>;       /* Ruby, wrong class name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector<test::Char>; /* Ruby, wrong class name */
 
 %{
 #ifdef max
@@ -23,20 +23,9 @@
            char * blah(T x) {
               return (char *) "vector::blah";
            }
+           void vectoruse(vector<T> a, test::vector<T> b) {}
    }; 
 }
-
-namespace test2 {
-   using namespace test;
-}
-
-namespace test3 {
-   using test::max;
-   using test::vector;
-}
-
-using namespace test2;
-namespace T4 = test;
 %}
 
 namespace test {
@@ -48,6 +37,7 @@
            char * blah(T x) {
               return (char *) "vector::blah";
            }
+           void vectoruse(vector<T> a, test::vector<T> b) {}
    }; 
 }
 
@@ -55,30 +45,26 @@
 %template(maxint) max<int>;
 %template(vectorint) vector<int>;
 
-namespace test2 {
-   using namespace test;
+namespace test {
    %template(maxshort) max<short>;
    %template(vectorshort) vector<short>;
 }
 
-namespace test3 {
-   using test::max;
-   using test::vector;
+namespace test {
    %template(maxlong) max<long>;
    %template(vectorlong) vector<long>;
 }
 
 %inline %{
 
-namespace test4 {
-   using namespace test;
-   typedef int Integer;
+namespace test {
+   typedef char Char;
 }
 
 %}
 
-namespace test4 {
-   %template(maxInteger) max<Integer>;
-   %template(vectorInteger) vector<Integer>;
+namespace test {
+   %template(maxchar) max<Char>;
+   %template(vectorchar) vector<Char>;
 }
 
diff --git a/Examples/test-suite/perl5/README b/Examples/test-suite/perl5/README
index 804dec8..f15c078 100644
--- a/Examples/test-suite/perl5/README
+++ b/Examples/test-suite/perl5/README
@@ -6,7 +6,7 @@
 ==
 
 Test::More is a standard perl test harness tool.
-Support was added for for using Test::More in 1.3.28.
+Support was added for using Test::More in 1.3.28.
 If adding a new test to this suite, please use Test::More.
 
 There are a few legacy test cases which do not use Test::More and these ought to be converted:
diff --git a/Examples/test-suite/php/preproc_constants_c_runme.php b/Examples/test-suite/php/preproc_constants_c_runme.php
index af9b76e..20868dc 100644
--- a/Examples/test-suite/php/preproc_constants_c_runme.php
+++ b/Examples/test-suite/php/preproc_constants_c_runme.php
@@ -62,5 +62,8 @@
 check::equal(gettype(preproc_constants_c::EXPR_LAND), "integer", "preproc_constants.EXPR_LAND has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_LOR), "integer", "preproc_constants.EXPR_LOR has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type");
+check::equal(gettype(preproc_constants_c::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type");
+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");
 
 ?>
diff --git a/Examples/test-suite/php/preproc_constants_runme.php b/Examples/test-suite/php/preproc_constants_runme.php
index 5c9119b..bd216c2 100644
--- a/Examples/test-suite/php/preproc_constants_runme.php
+++ b/Examples/test-suite/php/preproc_constants_runme.php
@@ -61,5 +61,8 @@
 check::equal(gettype(preproc_constants::EXPR_LAND), "boolean", "preproc_constants.EXPR_LAND has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_LOR), "boolean", "preproc_constants.EXPR_LOR has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type");
+check::equal(gettype(preproc_constants::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type");
+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");
 
 ?>
diff --git a/Examples/test-suite/php5/php_pragma_runme.php b/Examples/test-suite/php5/php_pragma_runme.php
index ae92f68..c76cfc9 100644
--- a/Examples/test-suite/php5/php_pragma_runme.php
+++ b/Examples/test-suite/php5/php_pragma_runme.php
@@ -9,4 +9,3 @@
 check::done();
 
 ?>
-
diff --git a/Examples/test-suite/php5/preproc_constants_c_runme.php b/Examples/test-suite/php5/preproc_constants_c_runme.php
index 1ea0195..d55d423 100644
--- a/Examples/test-suite/php5/preproc_constants_c_runme.php
+++ b/Examples/test-suite/php5/preproc_constants_c_runme.php
@@ -62,5 +62,8 @@
 check::equal(gettype(preproc_constants_c::EXPR_LAND), "integer", "preproc_constants.EXPR_LAND has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_LOR), "integer", "preproc_constants.EXPR_LOR has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type");
+check::equal(gettype(preproc_constants_c::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type");
+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");
 
 ?>
diff --git a/Examples/test-suite/php5/preproc_constants_runme.php b/Examples/test-suite/php5/preproc_constants_runme.php
index fb9ee4f..01137b0 100644
--- a/Examples/test-suite/php5/preproc_constants_runme.php
+++ b/Examples/test-suite/php5/preproc_constants_runme.php
@@ -70,5 +70,8 @@
 check::equal(gettype(preproc_constants::EXPR_LOR), "integer", "preproc_constants.EXPR_LOR has unexpected type");
 
 check::equal(gettype(preproc_constants::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type");
+check::equal(gettype(preproc_constants::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type");
+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");
 
 ?>
diff --git a/Examples/test-suite/preproc.i b/Examples/test-suite/preproc.i
index 8ed8c1a..8d9c517 100644
--- a/Examples/test-suite/preproc.i
+++ b/Examples/test-suite/preproc.i
@@ -372,8 +372,9 @@
 
 // Comma in macro - Github issue #974
 %inline %{
-#define __attribute__(x)
-#define TCX_PACKED(d) d __attribute__ ((__packed__))
+#define swig__attribute__(x)
+#define TCX_PACKED(d) d swig__attribute__ ((__packed__))
+
 
 TCX_PACKED (typedef struct tcxMessageTestImpl
 {
diff --git a/Examples/test-suite/preproc_constants.i b/Examples/test-suite/preproc_constants.i
index 3a999ad..628cae1 100644
--- a/Examples/test-suite/preproc_constants.i
+++ b/Examples/test-suite/preproc_constants.i
@@ -86,6 +86,10 @@
 #define EXPR_LAND        0xFF && 1
 #define EXPR_LOR         0xFF || 1
 #define EXPR_CONDITIONAL true ? 2 : 2.2
+#define EXPR_MIXED1      (0x80 + 11.1) - 1
+
+#define EXPR_WCHAR_MAX   (0x7fffffff + L'\0')
+#define EXPR_WCHAR_MIN   (-EXPR_WCHAR_MAX - 1)
 
 #define EXPR_CHAR_COMPOUND_ADD 'A' + 12
 #define EXPR_CHAR_COMPOUND_LSHIFT 'B' << 6
diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py
index af04c8c..bf2fa62 100644
--- a/Examples/test-suite/python/autodoc_runme.py
+++ b/Examples/test-suite/python/autodoc_runme.py
@@ -365,3 +365,9 @@
 check(func_inout.__doc__, "func_inout(int * INOUT) -> int")
 check(func_cb.__doc__, "func_cb(int c, int d) -> int")
 check(banana.__doc__, "banana(S a, S b, int c, Integer d)")
+
+check(TInteger.__doc__, "Proxy of C++ T< int > class.", "::T< int >")
+check(TInteger.__init__.__doc__, "__init__(TInteger self) -> TInteger", None, skip)
+check(TInteger.inout.__doc__,
+      "inout(TInteger self, TInteger t) -> TInteger",
+      "inout(TInteger t) -> TInteger")
diff --git a/Examples/test-suite/python/cpp11_hash_tables_runme.py b/Examples/test-suite/python/cpp11_hash_tables_runme.py
index 39388fd..d8c6320 100644
--- a/Examples/test-suite/python/cpp11_hash_tables_runme.py
+++ b/Examples/test-suite/python/cpp11_hash_tables_runme.py
@@ -6,8 +6,10 @@
 
 for x in [cpp11_hash_tables.MapIntInt({1:7}),
 		  cpp11_hash_tables.MultiMapIntInt({1:7}),
-		  cpp11_hash_tables.UnorderedMapIntInt({1:7}),
-		  cpp11_hash_tables.UnorderedMultiMapIntInt({1:7})]:
+# TODO: fix for -builtin
+#		  cpp11_hash_tables.UnorderedMapIntInt({1:7}),
+#		  cpp11_hash_tables.UnorderedMultiMapIntInt({1:7})
+         ]:
 
 	swig_assert_equal([(k, v) for k, v in x.iteritems()], [(1, 7)])
 
@@ -25,7 +27,8 @@
 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])
+# TODO: fix for -builtin
+#	swig_assert_equal(sorted([v for k, v in x.iteritems()]), [7, 9])
 # Is this broken?...
 #	swig_assert_equal(sorted([v for v in x[1]]), [7, 9])
 
diff --git a/Examples/test-suite/python/cpp11_ref_qualifiers_runme.py b/Examples/test-suite/python/cpp11_ref_qualifiers_runme.py
new file mode 100644
index 0000000..d3aa98c
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_ref_qualifiers_runme.py
@@ -0,0 +1,45 @@
+import cpp11_ref_qualifiers
+
+h = cpp11_ref_qualifiers.Host()
+
+# Basic testing
+h.h1()
+h.h2()
+h.h6()
+h.h7()
+
+h.h()
+
+# %feature testing
+f = cpp11_ref_qualifiers.Features()
+if f.F1() != "F1":
+    raise RuntimeException("Fail")
+if f.F2() != "F2":
+    raise RuntimeException("Fail")
+if f.F3() != "F3":
+    raise RuntimeException("Fail")
+
+if f.C1(0) != "C1":
+    raise RuntimeException("Fail")
+if f.C2(0) != "C2":
+    raise RuntimeException("Fail")
+if f.C3(0) != "C3":
+    raise RuntimeException("Fail")
+
+# %rename testing
+r = cpp11_ref_qualifiers.Renames()
+r.RR1()
+r.RR2()
+r.RR3()
+
+r.SS1(0)
+r.SS2(0)
+r.SS3(0)
+
+# Conversion operators
+co = cpp11_ref_qualifiers.ConversionOperators()
+s = co.StringConvertCopy()
+s = co.StringConvertMove()
+
+co2 = cpp11_ref_qualifiers.ConversionOperators2()
+s = co2.StringConvertMove()
diff --git a/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py b/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py
new file mode 100644
index 0000000..6352c79
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py
@@ -0,0 +1,4 @@
+import cpp11_ref_qualifiers_rvalue_unignore
+
+cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m1()
+cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m2()
diff --git a/Examples/test-suite/python/default_args_runme.py b/Examples/test-suite/python/default_args_runme.py
index b7c4cb5..ddaf2cd 100644
--- a/Examples/test-suite/python/default_args_runme.py
+++ b/Examples/test-suite/python/default_args_runme.py
@@ -115,15 +115,39 @@
     if Klass_inc().val != 0:
         raise RuntimeError("Klass::inc failed")
 
-    default_args.trickyvalue1(10)
-    default_args.trickyvalue1(10, 10)
-    default_args.trickyvalue2(10)
-    default_args.trickyvalue2(10, 10)
-    default_args.trickyvalue3(10)
-    default_args.trickyvalue3(10, 10)
+    tricky_failure = False
+    tricky = default_args.TrickyInPython()
+    if tricky.value_m1(10) != -1:
+        print "trickyvalue_m1 failed"
+        tricky_failure = True
+    if tricky.value_m1(10, 10) != 10:
+        print "trickyvalue_m1 failed"
+        tricky_failure = True
+    if tricky.value_0xabcdef(10) != 0xabcdef:
+        print "trickyvalue_0xabcdef failed"
+        tricky_failure = True
+    if tricky.value_0644(10) != 420:
+        print "trickyvalue_0644 failed"
+        tricky_failure = True
+    if tricky.value_perm(10) != 420:
+        print "trickyvalue_perm failed"
+        tricky_failure = True
+    if tricky.value_m01(10) != -1:
+        print "trickyvalue_m01 failed"
+        tricky_failure = True
+    if not tricky.booltest2():
+        print "booltest2 failed"
+        tricky_failure = True
+
+    if tricky_failure:
+        raise RuntimeError
+
     default_args.seek()
     default_args.seek(10)
 
+    if not default_args.booltest():
+        raise RuntimeError("booltest failed")
+
     if default_args.slightly_off_square(10) != 102:
         raise RuntimeError
 
diff --git a/Examples/test-suite/python/python_richcompare_runme.py b/Examples/test-suite/python/python_richcompare_runme.py
index a68da2f..2476603 100644
--- a/Examples/test-suite/python/python_richcompare_runme.py
+++ b/Examples/test-suite/python/python_richcompare_runme.py
@@ -1,4 +1,13 @@
 import python_richcompare
+import sys
+
+def check_unorderable_types(exception):
+#    if str(exception).find("unorderable types") == -1:
+#        raise RuntimeError("A TypeError 'unorderable types' exception was expected"), None, sys.exc_info()[2]
+    pass # Exception message seems to vary from one version of Python to another
+
+def is_new_style_class(cls):
+    return hasattr(cls, "__class__")
 
 base1 = python_richcompare.BaseClass(1)
 base2 = python_richcompare.BaseClass(2)
@@ -65,6 +74,18 @@
     raise RuntimeError(
         "Comparing equivalent instances of different subclasses, == returned True")
 
+# Check comparison to other objects
+#-------------------------------------------------------------------------------
+if (base1 == 42) :
+    raise RuntimeError("Comparing class to incompatible type, == returned True")
+if not (base1 != 42) :
+    raise RuntimeError("Comparing class to incompatible type, != returned False")
+
+if (a1 == 42) :
+    raise RuntimeError("Comparing class (with overloaded operator ==) to incompatible type, == returned True")
+if not (a1 != 42) :
+    raise RuntimeError("Comparing class (with overloaded operator ==) to incompatible type, != returned False")
+
 # Check inequalities
 #-------------------------------------------------------------------------
 
@@ -80,6 +101,42 @@
 if not (a2 <= b2):
     raise RuntimeError("operator<= failed")
 
+# Check inequalities to other objects
+#-------------------------------------------------------------------------------
+if is_new_style_class(python_richcompare.BaseClass):
+    # Skip testing -classic option
+    if sys.version_info[0:2] < (3, 0):
+        if (base1 < 42):
+            raise RuntimeError("Comparing class to incompatible type, < returned True")
+        if (base1 <= 42):
+            raise RuntimeError("Comparing class to incompatible type, <= returned True")
+        if not (base1 > 42):
+            raise RuntimeError("Comparing class to incompatible type, > returned False")
+        if not (base1 >= 42):
+            raise RuntimeError("Comparing class to incompatible type, >= returned False")
+    else:
+        # Python 3 throws: TypeError: unorderable types
+        try:
+            res = base1 < 42
+            raise RuntimeError("Failed to throw")
+        except TypeError,e:
+            check_unorderable_types(e)
+        try:
+            res = base1 <= 42
+            raise RuntimeError("Failed to throw")
+        except TypeError,e:
+            check_unorderable_types(e)
+        try:
+            res = base1 > 42
+            raise RuntimeError("Failed to throw")
+        except TypeError,e:
+            check_unorderable_types(e)
+        try:
+            res = base1 >= 42
+            raise RuntimeError("Failed to throw")
+        except TypeError,e:
+            check_unorderable_types(e)
+
 # Check inequalities used for ordering
 #-------------------------------------------------------------------------
 
diff --git a/Examples/test-suite/python/template_using_directive_typedef_runme.py b/Examples/test-suite/python/template_using_directive_typedef_runme.py
new file mode 100644
index 0000000..363a3b7
--- /dev/null
+++ b/Examples/test-suite/python/template_using_directive_typedef_runme.py
@@ -0,0 +1,15 @@
+import template_using_directive_typedef
+
+vo = template_using_directive_typedef.Vector_Obj();
+
+h = 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/python/typemap_template_typedef_runme.py b/Examples/test-suite/python/typemap_template_typedef_runme.py
new file mode 100644
index 0000000..a245836
--- /dev/null
+++ b/Examples/test-suite/python/typemap_template_typedef_runme.py
@@ -0,0 +1,32 @@
+from typemap_template_typedef import *
+
+def check(got, expected):
+    if got != expected:
+        raise RuntimeError("got: " + str(got) + " expected: " + str(expected))
+
+x = XXXInt()
+
+check(x.aa1(0), 0)
+check(x.aa2(0), 55)
+check(x.aa3(0), 0)
+check(aa1(0), 0)
+check(aa2(0), 0)
+
+check(x.bb1(0), 0)
+check(x.bb2(0), 66)
+check(x.bb3(0), 0)
+check(bb1(0), 0)
+check(bb2(0), 0)
+
+check(x.cc1(0), 0)
+check(x.cc2(0), 77)
+check(x.cc3(0), 77)
+check(cc1(0), 0)
+check(cc2(0), 0)
+
+check(x.dd1(0), 0)
+check(x.dd2(0), 88)
+check(x.dd3(0), 0)
+check(dd1(0), 0)
+check(dd2(0), 0)
+
diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in
index a34e55f..ee9d390 100644
--- a/Examples/test-suite/ruby/Makefile.in
+++ b/Examples/test-suite/ruby/Makefile.in
@@ -21,6 +21,7 @@
 	li_std_queue \
 	li_std_set \
 	li_std_stack \
+	li_std_wstring \
 	primitive_types \
 	ruby_keywords \
 	ruby_minherit_shared_ptr \
diff --git a/Examples/test-suite/ruby/li_std_wstring_runme.rb b/Examples/test-suite/ruby/li_std_wstring_runme.rb
new file mode 100644
index 0000000..0cf38ae
--- /dev/null
+++ b/Examples/test-suite/ruby/li_std_wstring_runme.rb
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+require 'swig_assert'
+require 'li_std_wstring'
+
+x = "abc"
+swig_assert_equal("Li_std_wstring.test_wchar_overload(x)", "x", binding)
+swig_assert_equal("Li_std_wstring.test_ccvalue(x)", "x", binding)
+swig_assert_equal("Li_std_wstring.test_value(Li_std_wstring::Wstring.new(x))", "x", binding)
+
+swig_assert_equal("Li_std_wstring.test_wchar_overload()", "nil", binding)
+
+swig_assert_equal("Li_std_wstring.test_pointer(Li_std_wstring::Wstring.new(x))", "nil", binding)
+swig_assert_equal("Li_std_wstring.test_const_pointer(Li_std_wstring::Wstring.new(x))", "nil", binding)
+swig_assert_equal("Li_std_wstring.test_const_pointer(Li_std_wstring::Wstring.new(x))", "nil", binding)
+swig_assert_equal("Li_std_wstring.test_reference(Li_std_wstring::Wstring.new(x))", "nil", binding)
+
+x = "y"
+swig_assert_equal("Li_std_wstring.test_value(x)", "x", binding)
+a = Li_std_wstring::A.new(x)
+swig_assert_equal("Li_std_wstring.test_value(a)", "x", binding)
+
+x = "hello"
+swig_assert_equal("Li_std_wstring.test_const_reference(x)", "x", binding)
+
+
+swig_assert_equal("Li_std_wstring.test_pointer_out", "'x'", binding)
+swig_assert_equal("Li_std_wstring.test_const_pointer_out", "'x'", binding)
+swig_assert_equal("Li_std_wstring.test_reference_out()", "'x'", binding)
+
+s = "abc"
+swig_assert("Li_std_wstring.test_equal_abc(s)", binding)
+
+begin
+  Li_std_wstring.test_throw
+rescue RuntimeError => e
+  swig_assert_equal("e.message", "'x'", binding)
+end
+
+x = "abc\0def"
+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)
diff --git a/Examples/test-suite/smart_pointer_namespace2.i b/Examples/test-suite/smart_pointer_namespace2.i
index 8827998..e78364c 100644
--- a/Examples/test-suite/smart_pointer_namespace2.i
+++ b/Examples/test-suite/smart_pointer_namespace2.i
@@ -49,11 +49,6 @@
     };
 }
 
-%define PTR_DEF(o)
-typedef one::Ptr<o> o ## _ptr;
-%template(o ## _ptr) one::Ptr<o>;
-%enddef
-
 namespace one
 {
     class Obj1
@@ -63,7 +58,8 @@
         void donothing() {}
     };
 
-    PTR_DEF(Obj1)
+    typedef one::Ptr<Obj1> Obj1_ptr;
+    %template(Obj1_ptr) one::Ptr<Obj1>;
 }
 
 namespace two
@@ -75,6 +71,9 @@
         void donothing() {}
     };
 
-    PTR_DEF(Obj2)
+    typedef one::Ptr<Obj2> Obj2_ptr;
 }
 
+using two::Obj2;
+%template(Obj2_ptr) one::Ptr<Obj2>;
+
diff --git a/Examples/test-suite/template_empty_inherit.i b/Examples/test-suite/template_empty_inherit.i
new file mode 100644
index 0000000..5677b8b
--- /dev/null
+++ b/Examples/test-suite/template_empty_inherit.i
@@ -0,0 +1,34 @@
+%module template_empty_inherit
+
+%rename(FunctorOperator) operator();
+
+%inline %{
+template<class Arg, typename Result> struct Functor {
+  virtual Result operator()(Arg x) const = 0;
+  virtual ~Functor() {}
+};
+%}
+
+// Bug fix - %ignore was resulting in this warning:
+// Warning 401: Base class 'Functor< int,int >' has no name as it is an empty template instantiated with '%template()'. Ignored.
+%ignore Functor<int, int>;
+%template() Functor<int, int>;
+
+%inline %{
+#include <algorithm>
+#include <iterator>
+struct SquareFunctor : Functor<int, int> {
+  int operator()(int v) const { return v*v; }
+};
+%}
+
+%include <std_vector.i>
+%template(VectorInt) std::vector<int>;
+
+%inline %{
+std::vector<int> squares(const std::vector<int>& vi) {
+  std::vector<int> result;
+  std::transform(vi.begin(), vi.end(), std::back_inserter(result), SquareFunctor());
+  return result;
+}
+%}
diff --git a/Examples/test-suite/template_nested_typemaps.i b/Examples/test-suite/template_nested_typemaps.i
index 54f5bc5..577a88e 100644
--- a/Examples/test-suite/template_nested_typemaps.i
+++ b/Examples/test-suite/template_nested_typemaps.i
@@ -1,25 +1,30 @@
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_TEMPLATE
-
 %module template_nested_typemaps
 
-// Testing that the typemaps invoked within a class via %template are picked up by appropriate methods
+#pragma SWIG nowarn=SWIGWARN_PARSE_NAMED_NESTED_CLASS
 
-template <typename T> struct Typemap {
-  %typemap(in) T {
-    $1 = -99;
-  }
-};
-template <> struct Typemap<short> { // Note explicit specialization
-  %typemap(in) short {
-    $1 = -77;
-  }
-};
+// Testing that the typemaps invoked within a class via %template are picked up by appropriate methods
+// Only for languages that support nested classes
 
 %inline %{
 int globalInt1(int s) { return s; }
 short globalShort1(short s) { return s; }
 
 template <typename T> struct Breeze {
+  template <typename TMT> struct Typemap {
+#ifdef SWIG
+    %typemap(in) TMT {
+      $1 = -99;
+    }
+#endif
+  };
+  template <typename TMT> struct TypemapShort {
+#ifdef SWIG
+    %typemap(in) short {
+      $1 = -77;
+    }
+#endif
+  };
+
   int methodInt1(int s) { return s; }
 #if defined(SWIG)
   %template() Typemap<int>;
@@ -29,7 +34,7 @@
 
   short methodShort1(short s) { return s; }
 #if defined(SWIG)
-  %template(TypemapShort) Typemap<short>; // should issue warning SWIGWARN_PARSE_NESTED_TEMPLATE
+  %template() TypemapShort<short>;
 #endif
   short methodShort2(short s) { return s; } // should pick up the typemap within Typemap<short>
 };
diff --git a/Examples/test-suite/template_parameters_global_scope.i b/Examples/test-suite/template_parameters_global_scope.i
new file mode 100644
index 0000000..a828187
--- /dev/null
+++ b/Examples/test-suite/template_parameters_global_scope.i
@@ -0,0 +1,133 @@
+%module template_parameters_global_scope
+
+%inline %{
+namespace Alloc {
+  template<typename T> struct Rebind {
+    typedef int Integer;
+  };
+}
+%}
+
+%inline %{
+struct Bucket_ {};
+typedef Bucket_ TDBucket;
+typedef ::Bucket_ TDGlobalBucket;
+%}
+
+// Check 1: %template no unary scope operator
+%template(RebindBucket) Alloc::Rebind< Bucket_ >;
+
+%inline %{
+Alloc::Rebind< Bucket_ >::Integer Bucket1() { return 1; }
+Alloc::Rebind< ::Bucket_ >::Integer Bucket2() { return 2; }
+Alloc::Rebind< TDBucket >::Integer Bucket3() { return 3; }
+Alloc::Rebind< ::TDBucket >::Integer Bucket4() { return 4; }
+Alloc::Rebind< TDGlobalBucket >::Integer Bucket5() { return 5; }
+Alloc::Rebind< ::TDGlobalBucket >::Integer Bucket6() { return 6; }
+%}
+
+// Check 2: %template with unary scope operator
+%inline %{
+struct Spade {};
+typedef Spade TDSpade;
+typedef ::Spade TDGlobalSpade;
+%}
+%template(RebindSpade) Alloc::Rebind< ::Spade >;
+
+%inline %{
+Alloc::Rebind< Spade >::Integer Spade1() { return 1; }
+Alloc::Rebind< ::Spade >::Integer Spade2() { return 2; }
+Alloc::Rebind< TDSpade >::Integer Spade3() { return 3; }
+Alloc::Rebind< ::TDSpade >::Integer Spade4() { return 4; }
+Alloc::Rebind< TDGlobalSpade >::Integer Spade5() { return 5; }
+Alloc::Rebind< ::TDGlobalSpade >::Integer Spade6() { return 6; }
+%}
+
+// Check 3: %template typedef no unary scope operator
+%inline %{
+struct Ball {};
+typedef Ball TDBall;
+typedef ::Ball TDGlobalBall;
+%}
+%template(RebindBall) Alloc::Rebind< TDBall >;
+
+%inline %{
+Alloc::Rebind< Ball >::Integer Ball1() { return 1; }
+Alloc::Rebind< ::Ball >::Integer Ball2() { return 2; }
+Alloc::Rebind< TDBall >::Integer Ball3() { return 3; }
+Alloc::Rebind< ::TDBall >::Integer Ball4() { return 4; }
+Alloc::Rebind< TDGlobalBall >::Integer Ball5() { return 5; }
+Alloc::Rebind< ::TDGlobalBall >::Integer Ball6() { return 6; }
+%}
+
+// Check 4: %template typedef with unary scope operator
+%inline %{
+struct Bat {};
+typedef Bat TDBat;
+typedef ::Bat TDGlobalBat;
+%}
+%template(RebindBat) Alloc::Rebind< ::TDBat >;
+
+%inline %{
+Alloc::Rebind< Bat >::Integer Bat1() { return 1; }
+Alloc::Rebind< ::Bat >::Integer Bat2() { return 2; }
+Alloc::Rebind< TDBat >::Integer Bat3() { return 3; }
+Alloc::Rebind< ::TDBat >::Integer Bat4() { return 4; }
+Alloc::Rebind< TDGlobalBat >::Integer Bat5() { return 5; }
+Alloc::Rebind< ::TDGlobalBat >::Integer Bat6() { return 6; }
+%}
+
+// Check 5: %template double typedef no unary scope operator
+%inline %{
+struct Chair {};
+typedef Chair TDChair;
+typedef ::Chair TDGlobalChair;
+%}
+%template(RebindChair) Alloc::Rebind< TDGlobalChair >;
+
+%inline %{
+Alloc::Rebind< Chair >::Integer Chair1() { return 1; }
+Alloc::Rebind< ::Chair >::Integer Chair2() { return 2; }
+Alloc::Rebind< TDChair >::Integer Chair3() { return 3; }
+Alloc::Rebind< ::TDChair >::Integer Chair4() { return 4; }
+Alloc::Rebind< TDGlobalChair >::Integer Chair5() { return 5; }
+Alloc::Rebind< ::TDGlobalChair >::Integer Chair6() { return 6; }
+%}
+
+// Check 6: %template double typedef with unary scope operator
+%inline %{
+struct Table {};
+typedef Table TDTable;
+typedef ::Table TDGlobalTable;
+%}
+%template(RebindTable) Alloc::Rebind< ::TDGlobalTable >;
+
+%inline %{
+Alloc::Rebind< Table >::Integer Table1() { return 1; }
+Alloc::Rebind< ::Table >::Integer Table2() { return 2; }
+Alloc::Rebind< TDTable >::Integer Table3() { return 3; }
+Alloc::Rebind< ::TDTable >::Integer Table4() { return 4; }
+Alloc::Rebind< TDGlobalTable >::Integer Table5() { return 5; }
+Alloc::Rebind< ::TDGlobalTable >::Integer Table6() { return 6; }
+%}
+
+#if 0
+%inline %{
+namespace Alloc {
+  template<typename T=::Spade/*, typename T2=TDSpade, typename T3=::TDSpade, typename T4=TDGlobalSpade, typename T5=::TDGlobalSpade*/> struct Rejig {
+    typedef int Integer;
+  };
+}
+%}
+
+%template(RejigSpade) Alloc::Rejig<::Spade>;
+
+%inline %{
+Alloc::Rejig<>::Integer rejig1() { return 1; }
+Alloc::Rejig< ::Spade >::Integer rejig2() { return 2; }
+Alloc::Rejig< ::TDSpade >::Integer rejig3() { return 3; }
+Alloc::Rejig< ::TDSpade >::Integer rejig4() { return 4; }
+Alloc::Rejig< TDGlobalSpade >::Integer rejig5() { return 5; }
+Alloc::Rejig< ::TDGlobalSpade >::Integer rejig6() { return 6; }
+%}
+#endif
diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i
index 8781fbb..a7afd30 100644
--- a/Examples/test-suite/template_partial_specialization.i
+++ b/Examples/test-suite/template_partial_specialization.i
@@ -32,7 +32,7 @@
 %template(H) One::OneParm<int **>;
 
 // %template scope explicit specializations
-namespace ONE {
+namespace One {
   %template(I) One::OneParm<float>;
   %template(J) ::One::OneParm<float *>;
 }
@@ -42,7 +42,7 @@
 }
 
 // %template scope partial specializations
-namespace ONE {
+namespace One {
   %template(BB) One::OneParm<bool *>;
   %template(BBB) ::One::OneParm<char *>;
 }
diff --git a/Examples/test-suite/template_partial_specialization_typedef.i b/Examples/test-suite/template_partial_specialization_typedef.i
index 6fdbf99..9c00efc 100644
--- a/Examples/test-suite/template_partial_specialization_typedef.i
+++ b/Examples/test-suite/template_partial_specialization_typedef.i
@@ -59,7 +59,7 @@
 %template(H) One::OneParm<TypeDef::IntPtrPtr>;
 
 // %template scope explicit specializations
-namespace ONE {
+namespace One {
   %template(I) One::OneParm<TypeDef::Float>;
   %template(J) ::One::OneParm<TypeDef::FloatPtr>;
 }
@@ -69,7 +69,7 @@
 }
 
 // %template scope partial specializations
-namespace ONE {
+namespace One {
   %template(BB) One::OneParm<TypeDef::BoolPtr>;
   %template(BBB) ::One::OneParm<TypeDef::CharPtr>;
 }
diff --git a/Examples/test-suite/template_using_directive_typedef.i b/Examples/test-suite/template_using_directive_typedef.i
new file mode 100644
index 0000000..1c8bcb9
--- /dev/null
+++ b/Examples/test-suite/template_using_directive_typedef.i
@@ -0,0 +1,44 @@
+%module template_using_directive_typedef
+
+%inline %{
+namespace space {
+  template<typename T> class Vector {};
+  class VectorClass {};
+}
+struct Obj {};
+%}
+
+%template(Vector_Obj) space::Vector<Obj>;
+
+%inline %{
+namespace tns {
+  using space::Vector; // template using directives were not being added into the typedef table
+  using space::VectorClass;
+  typedef Vector<Obj> NSVec;
+}
+%}
+
+%inline %{
+namespace tns {
+  struct Holder {
+//	using Vec = Vector<Obj>;
+    typedef Vector<Obj> Vec;
+    typedef VectorClass VecClass;
+	Vec items;
+    void holder_use1(space::Vector<Obj>, tns::NSVec, tns::Vector<Obj>) {}
+    void holder_use2(space::Vector<Obj>, NSVec, Vector<Obj>) {}
+    void holder_use3(tns::Holder::Vec, Holder::Vec, Vec) {}
+  };
+  void tns_holder_use(tns::Holder::Vec, Holder::Vec) {}
+  void tns_use(space::Vector<Obj>, NSVec, tns::NSVec) {}
+}
+void global_holder_use(tns::Holder::Vec) {}
+void global_use(space::Vector<Obj>, tns::NSVec, tns::Vector<Obj>) {}
+namespace ns1 {
+  void ns1_holder_use(tns::Holder::Vec) {}
+}
+namespace ns2 {
+  using namespace tns;
+  void ns2_holder_use(tns::Holder::Vec, Holder::Vec, NSVec, Vector<Obj>) {}
+}
+%}
diff --git a/Examples/test-suite/typemap_template_typedef.i b/Examples/test-suite/typemap_template_typedef.i
new file mode 100644
index 0000000..c84416e
--- /dev/null
+++ b/Examples/test-suite/typemap_template_typedef.i
@@ -0,0 +1,66 @@
+%module typemap_template_typedef
+//%module("templatereduce") typemap_template_typedef
+
+%typemap(in) int TMAP55 %{ $1 = 55; /* int TMAP55 typemap */ %}
+%typemap(in) int TMAP66 %{ $1 = 66; /* int TMAP66 typemap */ %}
+%typemap(in) int TMAP77 %{ $1 = 77; /* int TMAP77 typemap */ %}
+%typemap(in) int TMAP88 %{ $1 = 88; /* int TMAP88 typemap */ %}
+
+%apply int TMAP77 { XXX<int>::Long cc }
+
+%inline %{
+typedef int Integer;
+
+template<typename T> struct XXX {
+#ifdef SWIG
+// In swig-3.0.12 'Long aa' was actually stored as 'long aa' in typemap table instead of 'XXX<int>::Long aa'
+%apply int TMAP55 { Long aa }
+%apply int TMAP66 { XXX<int>::Long bb }
+%apply int TMAP88 { XXX<Integer>::Long dd }
+#endif
+  typedef long Long;
+  long aa1(long aa) { return aa; }
+  long aa2(Long aa) { return aa; }
+  long bb1(long bb) { return bb; }
+  long bb2(Long bb) { return bb; }
+  long cc1(long cc) { return cc; }
+  long cc2(Long cc) { return cc; }
+  long dd1(long dd) { return dd; }
+  long dd2(Long dd) { return dd; }
+#ifdef SWIG
+%clear Long aa;
+%clear XXX<int>::Long bb;
+%clear XXX<Integer>::Long dd;
+#endif
+  long aa3(Long aa) { return aa; }
+  long bb3(Long bb) { return bb; }
+  long cc3(Long cc) { return cc; }
+  long dd3(Long dd) { return dd; }
+};
+%}
+
+%template(XXXInt) XXX<Integer>;
+
+%clear XXX<int>::Long cc;
+
+%inline %{
+  long aa1(XXX<int>::Long aa) { return aa; }
+  long aa2(long aa) { return aa; }
+  long bb1(XXX<int>::Long bb) { return bb; }
+  long bb2(long bb) { return bb; }
+  long cc1(XXX<int>::Long cc) { return cc; }
+  long cc2(long cc) { return cc; }
+  long dd1(XXX<Integer>::Long dd) { return dd; }
+  long dd2(long dd) { return dd; }
+%}
+
+%inline %{
+typedef Integer INTEGER;
+template<typename T1, typename T2 = INTEGER> struct YYY {
+  void meff(T1 t1, T2 t2) {}
+};
+%}
+%template(YYYIntInt) YYY<INTEGER>;
+%inline %{
+  void whyohwhy(YYY<INTEGER> yy) {}
+%}
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index f91d6df..5043741 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -162,7 +162,7 @@
   return ret;
 }
 
-// Treat references to arrays like like references to a single element.
+// Treat references to arrays like references to a single element.
 %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
 
 
diff --git a/Lib/java/std_array.i b/Lib/java/std_array.i
index f75857e..0944d93 100644
--- a/Lib/java/std_array.i
+++ b/Lib/java/std_array.i
@@ -8,13 +8,13 @@
 
   template<class T, size_t N> class array {
   public:
-    typedef T& reference;
-    typedef const T& const_reference;
     typedef size_t size_type;
     typedef ptrdiff_t difference_type;
     typedef T value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
+    typedef T &reference;
+    typedef const T &const_reference;
+    typedef T *pointer;
+    typedef const T *const_pointer;
     array();
     array(const array& other);
     size_type size() const;
diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i
new file mode 100644
index 0000000..595db89
--- /dev/null
+++ b/Lib/java/std_list.i
@@ -0,0 +1,225 @@
+/* -----------------------------------------------------------------------------
+ * std_list.i
+ *
+ * SWIG typemaps for std::list.
+ * The Java proxy class extends java.util.AbstractSequentialList. The std::list
+ * container looks and feels much like a java.util.LinkedList from Java.
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+
+%{
+#include <list>
+#include <stdexcept>
+%}
+
+%fragment("SWIG_ListSize", "header", fragment="SWIG_JavaIntFromSize_t") {
+SWIGINTERN jint SWIG_ListSize(size_t size) {
+  jint sz = SWIG_JavaIntFromSize_t(size);
+  if (sz == -1)
+    throw std::out_of_range("list size is too large to fit into a Java int");
+  return sz;
+}
+}
+
+%javamethodmodifiers std::list::begin "private";
+%javamethodmodifiers std::list::insert "private";
+%javamethodmodifiers std::list::doSize "private";
+%javamethodmodifiers std::list::doPreviousIndex "private";
+%javamethodmodifiers std::list::doNextIndex "private";
+%javamethodmodifiers std::list::doHasNext "private";
+
+// Match Java style better:
+%rename(Iterator) std::list::iterator;
+
+%nodefaultctor std::list::iterator;
+
+namespace std {
+  template <typename T> class list {
+
+%typemap(javabase) std::list<T> "java.util.AbstractSequentialList<$typemap(jboxtype, T)>"
+%proxycode %{
+  public $javaclassname(java.util.Collection c) {
+    this();
+    java.util.ListIterator<$typemap(jboxtype, T)> it = listIterator(0);
+    // Special case the "copy constructor" here to avoid lots of cross-language calls
+    for (Object o : c) {
+      it.add(($typemap(jboxtype, T))o);
+    }
+  }
+
+  public int size() {
+    return doSize();
+  }
+
+  public boolean add($typemap(jboxtype, T) value) {
+    addLast(value);
+    return true;
+  }
+
+  public java.util.ListIterator<$typemap(jboxtype, T)> listIterator(int index) {
+    return new java.util.ListIterator<$typemap(jboxtype, T)>() {
+      private Iterator pos;
+      private Iterator last;
+
+      private java.util.ListIterator<$typemap(jboxtype, T)> init(int index) {
+        if (index < 0 || index > $javaclassname.this.size())
+          throw new IndexOutOfBoundsException("Index: " + index);
+        pos = $javaclassname.this.begin();
+	pos = pos.advance_unchecked(index);
+        return this;
+      }
+
+      public void add($typemap(jboxtype, T) v) {
+        // Technically we can invalidate last here, but this makes more sense
+        last = $javaclassname.this.insert(pos, v);
+      }
+
+      public void set($typemap(jboxtype, T) v) {
+        if (null == last) {
+          throw new IllegalStateException();
+        }
+        last.set_unchecked(v);
+      }
+
+      public void remove() {
+        if (null == last) {
+          throw new IllegalStateException();
+        }
+        $javaclassname.this.remove(last);
+        last = null;
+      }
+
+      public int previousIndex() {
+        return $javaclassname.this.doPreviousIndex(pos);
+      }
+
+      public int nextIndex() {
+        return $javaclassname.this.doNextIndex(pos);
+      }
+
+      public $typemap(jboxtype, T) previous() {
+        if (previousIndex() < 0) {
+          throw new java.util.NoSuchElementException();
+        }
+        last = pos;
+        pos = pos.previous_unchecked();
+        return last.deref_unchecked();
+      }
+
+      public $typemap(jboxtype, T) next() {
+        if (!hasNext()) {
+          throw new java.util.NoSuchElementException();
+        }
+        last = pos;
+        pos = pos.next_unchecked();
+        return last.deref_unchecked();
+      }
+
+      public boolean hasPrevious() {
+        // This call to previousIndex() will be much slower than the hasNext() implementation, but it's simpler like this with C++ forward iterators
+        return previousIndex() != -1;
+      }
+
+      public boolean hasNext() {
+        return $javaclassname.this.doHasNext(pos);
+      }
+    }.init(index);
+  }
+%}
+
+  public:
+    typedef size_t size_type;
+    typedef T value_type;
+    typedef T &reference;
+
+    /*
+     * We'd actually be better off having the nested class *not* be static in the wrapper
+     * output, but this doesn't actually remove the $static from the nested class still.
+     * (This would allow us to somewhat simplify the implementation of the ListIterator
+     * interface and give "natural" semantics to Java users of the C++ iterator)
+     */
+    //%typemap(javaclassmodifiers) iterator "public class"
+    //%typemap(javainterfaces) iterator "java.util.ListIterator<$typemap(jboxtype, T)>"
+
+    struct iterator {
+      %extend {
+	void set_unchecked(const T &v) {
+	  **$self = v;
+	}
+
+	iterator next_unchecked() const {
+	  std::list<T>::iterator ret = *$self;
+	  ++ret;
+	  return ret;
+	}
+
+	iterator previous_unchecked() const {
+	  std::list<T>::iterator ret = *$self;
+	  --ret;
+	  return ret;
+	}
+
+	T deref_unchecked() const {
+	  return **$self;
+	}
+
+	iterator advance_unchecked(size_type index) const {
+	  std::list<T>::iterator ret = *$self;
+	  std::advance(ret, index);
+	  return ret;
+	}
+      }
+    };
+
+    list();
+    list(const list &other);
+    %rename(isEmpty) empty;
+    bool empty() const;
+    void clear();
+    %rename(remove) erase;
+    iterator erase(iterator pos);
+    %rename(removeLast) pop_back;
+    void pop_back();
+    %rename(removeFirst) pop_front;
+    void pop_front();
+    %rename(addLast) push_back;
+    void push_back(const T &value);
+    %rename(addFirst) push_front;
+    void push_front(const T &value);
+    iterator begin();
+    iterator end();
+    iterator insert(iterator pos, const T &value);
+
+    %extend {
+      %fragment("SWIG_ListSize");
+      list(jint count) throw (std::out_of_range) {
+        if (count < 0)
+          throw std::out_of_range("list count must be positive");
+        return new std::list<T>(static_cast<std::list<T>::size_type>(count));
+      }
+
+      list(jint count, const T &value) throw (std::out_of_range) {
+        if (count < 0)
+          throw std::out_of_range("list count must be positive");
+        return new std::list<T>(static_cast<std::list<T>::size_type>(count), value);
+      }
+
+      jint doSize() const throw (std::out_of_range) {
+        return SWIG_ListSize(self->size());
+      }
+
+      jint doPreviousIndex(const iterator &pos) const throw (std::out_of_range) {
+        return pos == self->begin() ? -1 : SWIG_ListSize(std::distance(self->begin(), static_cast<std::list<T>::const_iterator>(pos)));
+      }
+
+      jint doNextIndex(const iterator &pos) const throw (std::out_of_range) {
+        return pos == self->end() ? SWIG_ListSize(self->size()) : SWIG_ListSize(std::distance(self->begin(), static_cast<std::list<T>::const_iterator>(pos)));
+      }
+
+      bool doHasNext(const iterator &pos) const {
+        return pos != $self->end();
+      }
+    }
+  };
+}
diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i
index 4f5afe6..57368c8 100644
--- a/Lib/java/std_vector.i
+++ b/Lib/java/std_vector.i
@@ -1,5 +1,10 @@
 /* -----------------------------------------------------------------------------
  * std_vector.i
+ *
+ * SWIG typemaps for std::vector.
+ * The Java proxy class extends java.util.AbstractList and implements
+ * java.util.RandomAccess. The std::vector container looks and feels much like a
+ * java.util.ArrayList from Java.
  * ----------------------------------------------------------------------------- */
 
 %include <std_common.i>
@@ -72,17 +77,34 @@
 
   public:
     typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
     typedef CTYPE value_type;
+    typedef CTYPE &reference;
     typedef CREF_TYPE const_reference;
+    typedef CTYPE *pointer;
+    typedef CTYPE const *const_pointer;
+
     vector();
-    vector(size_type n);
+    vector(const vector &other);
     size_type capacity() const;
-    void reserve(size_type n);
+    void reserve(size_type n) throw (std::length_error);
     %rename(isEmpty) empty;
     bool empty() const;
     void clear();
     %extend {
       %fragment("SWIG_VectorSize");
+      vector(jint count) throw (std::out_of_range) {
+        if (count < 0)
+          throw std::out_of_range("vector count must be positive");
+        return new std::vector< CTYPE >(static_cast<std::vector< CTYPE >::size_type>(count));
+      }
+
+      vector(jint count, const CTYPE &value) throw (std::out_of_range) {
+        if (count < 0)
+          throw std::out_of_range("vector count must be positive");
+        return new std::vector< CTYPE >(static_cast<std::vector< CTYPE >::size_type>(count), value);
+      }
+
       jint doSize() const throw (std::out_of_range) {
         return SWIG_VectorSize(self->size());
       }
@@ -92,7 +114,7 @@
       }
 
       void doAdd(jint index, const value_type& value) throw (std::out_of_range) {
-        const jint size = SWIG_VectorSize(self->size());
+        const jint size = static_cast<std::vector< CTYPE >::size_type>(self->size());
         if (0 <= index && index <= size) {
           self->insert(self->begin() + index, value);
         } else {
@@ -101,7 +123,7 @@
       }
 
       value_type doRemove(jint index) throw (std::out_of_range) {
-        const jint size = SWIG_VectorSize(self->size());
+        const jint size = static_cast<std::vector< CTYPE >::size_type>(self->size());
         if (0 <= index && index < size) {
           CTYPE const old_value = (*self)[index];
           self->erase(self->begin() + index);
@@ -112,7 +134,7 @@
       }
 
       CREF_TYPE doGet(jint index) throw (std::out_of_range) {
-        const jint size = SWIG_VectorSize(self->size());
+        const jint size = static_cast<std::vector< CTYPE >::size_type>(self->size());
         if (index >= 0 && index < size)
           return (*self)[index];
         else
@@ -120,7 +142,7 @@
       }
 
       value_type doSet(jint index, const value_type& value) throw (std::out_of_range) {
-        const jint size = SWIG_VectorSize(self->size());
+        const jint size = static_cast<std::vector< CTYPE >::size_type>(self->size());
         if (index >= 0 && index < size) {
           CTYPE const old_value = (*self)[index];
           (*self)[index] = value;
@@ -131,7 +153,7 @@
       }
 
       void doRemoveRange(jint fromIndex, jint toIndex) throw (std::out_of_range) {
-        const jint size = SWIG_VectorSize(self->size());
+        const jint size = static_cast<std::vector< CTYPE >::size_type>(self->size());
         if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) {
           self->erase(self->begin() + fromIndex, self->begin() + toIndex);
         } else {
diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg
index 3510d04..5143360 100644
--- a/Lib/lua/luarun.swg
+++ b/Lib/lua/luarun.swg
@@ -180,7 +180,7 @@
  * -------------------------------------------------------------------------- */
 
 /* Push the string STR on the Lua stack, like lua_pushstring, but
-   prefixed with the the location of the innermost Lua call-point
+   prefixed with the location of the innermost Lua call-point
    (as formated by luaL_where).  */
 SWIGRUNTIME void
 SWIG_Lua_pusherrstring (lua_State *L, const char *str)
@@ -191,7 +191,7 @@
 }
 
 /* Push a formatted string generated from FMT and following args on
-   the Lua stack, like lua_pushfstring, but prefixed with the the
+   the Lua stack, like lua_pushfstring, but prefixed with the
    location of the innermost Lua call-point (as formated by luaL_where).  */
 SWIGRUNTIME void
 SWIG_Lua_pushferrstring (lua_State *L, const char *fmt, ...)
diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg
index 771edbd..9b65207 100644
--- a/Lib/octave/octcontainer.swg
+++ b/Lib/octave/octcontainer.swg
@@ -202,8 +202,8 @@
       //      swig::SwigVar_PyObject item = OctSequence_GetItem(_seq, _index);
       octave_value item; // * todo
       try {
-	return swig::as<T>(item, true);
-      } catch (std::exception& e) {
+	return swig::as<T>(item);
+      } catch (const std::exception& e) {
 	char msg[1024];
 	sprintf(msg, "in sequence element %d ", _index);
 	if (!Octave_Error_Occurred()) {
diff --git a/Lib/octave/octstdcommon.swg b/Lib/octave/octstdcommon.swg
index b3b3d00..80b2154 100644
--- a/Lib/octave/octstdcommon.swg
+++ b/Lib/octave/octstdcommon.swg
@@ -103,14 +103,14 @@
 
   template <class Type> 
   struct traits_as<Type, value_category> {
-    static Type as(const octave_value& obj, bool throw_error) {
+    static Type as(const octave_value& obj) {
       Type v;
       int res = asval(obj, &v);
       if (!obj.is_defined() || !SWIG_IsOK(res)) {
 	if (!Octave_Error_Occurred()) {
 	  %type_error(swig::type_name<Type>());
 	}
-	if (throw_error) throw std::invalid_argument("bad type");
+	throw std::invalid_argument("bad type");
       }
       return v;
     }
@@ -118,7 +118,7 @@
 
   template <class Type> 
   struct traits_as<Type, pointer_category> {
-    static Type as(const octave_value& obj, bool throw_error) {
+    static Type as(const octave_value& obj) {
       Type *v = 0;      
       int res = traits_asptr<Type>::asptr(obj, &v);
       if (SWIG_IsOK(res) && v) {
@@ -130,21 +130,17 @@
 	  return *v;
 	}
       } else {
-	// Uninitialized return value, no Type() constructor required.
-	static Type *v_def = (Type*) malloc(sizeof(Type));
 	if (!Octave_Error_Occurred()) {
 	  %type_error(swig::type_name<Type>());
 	}
-	if (throw_error) throw std::invalid_argument("bad type");
-	memset(v_def,0,sizeof(Type));
-	return *v_def;
+	throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type> 
   struct traits_as<Type*, pointer_category> {
-    static Type* as(const octave_value& obj, bool throw_error) {
+    static Type* as(const octave_value& obj) {
       Type *v = 0;      
       int res = traits_asptr<Type>::asptr(obj, &v);
       if (SWIG_IsOK(res)) {
@@ -153,15 +149,14 @@
 	if (!Octave_Error_Occurred()) {
 	  %type_error(swig::type_name<Type>());
 	}
-	if (throw_error) throw std::invalid_argument("bad type");
-	return 0;
+	throw std::invalid_argument("bad type");
       }
     }
   };
     
   template <class Type>
-  inline Type as(const octave_value& obj, bool te = false) {
-    return traits_as<Type, typename traits<Type>::category>::as(obj, te);
+  inline Type as(const octave_value& obj) {
+    return traits_as<Type, typename traits<Type>::category>::as(obj);
   }
 
   template <class Type> 
diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg
index d1865de..cc4ba44 100644
--- a/Lib/perl5/perlrun.swg
+++ b/Lib/perl5/perlrun.swg
@@ -392,7 +392,7 @@
   return result;
 }
 
-/* Convert a packed value value */
+/* Convert a packed pointer value */
 SWIGRUNTIME int
 SWIG_Perl_ConvertPacked(SWIG_MAYBE_PERL_OBJECT SV *obj, void *ptr, int sz, swig_type_info *ty) {
   swig_cast_info *tc;
diff --git a/Lib/php/php.swg b/Lib/php/php.swg
index 0ac46e0..83f7621 100644
--- a/Lib/php/php.swg
+++ b/Lib/php/php.swg
@@ -134,7 +134,7 @@
 %typemap(in) SWIGTYPE *DISOWN
 %{
   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");
+    SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
   }
 %}
 
diff --git a/Lib/php5/php.swg b/Lib/php5/php.swg
index 40854ea..6f8470f 100644
--- a/Lib/php5/php.swg
+++ b/Lib/php5/php.swg
@@ -134,7 +134,7 @@
 %typemap(in) SWIGTYPE *DISOWN
 {
   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");
+    SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
   }
 }
 
diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg
index 4fd1947..99903a9 100644
--- a/Lib/python/builtin.swg
+++ b/Lib/python/builtin.swg
@@ -393,10 +393,10 @@
 
 SWIGINTERN void
 SwigPyBuiltin_InitBases (PyTypeObject *type, PyTypeObject **bases) {
-  int base_count = 0;
+  Py_ssize_t base_count = 0;
   PyTypeObject **b;
   PyObject *tuple;
-  int i;
+  Py_ssize_t i;
 
   if (!bases[0]) {
     bases[0] = SwigPyObject_type();
diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg
index 1687aca..36557d7 100644
--- a/Lib/python/pycontainer.swg
+++ b/Lib/python/pycontainer.swg
@@ -434,8 +434,8 @@
     {
       swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index);
       try {
-	return swig::as<T>(item, true);
-      } catch (std::exception& e) {
+	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()) {
diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg
index 939a692..efc4766 100644
--- a/Lib/python/pyrun.swg
+++ b/Lib/python/pyrun.swg
@@ -538,7 +538,7 @@
       PyObject *res;
 
       /* PyObject_CallFunction() has the potential to silently drop
-         the active active exception.  In cases of unnamed temporary
+         the active exception.  In cases of unnamed temporary
          variable or where we just finished iterating over a generator
          StopIteration will be active right now, and this needs to
          remain true upon return from SwigPyObject_dealloc.  So save
@@ -1308,7 +1308,7 @@
   }
 }
 
-/* Convert a packed value value */
+/* Convert a packed pointer value */
 
 SWIGRUNTIME int
 SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg
index fad97be..26d3081 100644
--- a/Lib/python/pyruntime.swg
+++ b/Lib/python/pyruntime.swg
@@ -3,7 +3,7 @@
 /* Use debug wrappers with the Python release dll */
 # undef _DEBUG
 # include <Python.h>
-# define _DEBUG
+# define _DEBUG 1
 #else
 # include <Python.h>
 #endif
diff --git a/Lib/python/pystdcommon.swg b/Lib/python/pystdcommon.swg
index 93ee34b..0242e4d 100644
--- a/Lib/python/pystdcommon.swg
+++ b/Lib/python/pystdcommon.swg
@@ -107,14 +107,14 @@
 
   template <class Type> 
   struct traits_as<Type, value_category> {
-    static Type as(PyObject *obj, bool throw_error) {
+    static Type as(PyObject *obj) {
       Type v;
       int res = asval(obj, &v);
       if (!obj || !SWIG_IsOK(res)) {
 	if (!PyErr_Occurred()) {
 	  ::%type_error(swig::type_name<Type>());
 	}
-	if (throw_error) throw std::invalid_argument("bad type");
+	throw std::invalid_argument("bad type");
       }
       return v;
     }
@@ -122,7 +122,7 @@
 
   template <class Type> 
   struct traits_as<Type, pointer_category> {
-    static Type as(PyObject *obj, bool throw_error) {
+    static Type as(PyObject *obj) {
       Type *v = 0;      
       int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
       if (SWIG_IsOK(res) && v) {
@@ -134,21 +134,17 @@
 	  return *v;
 	}
       } else {
-	// Uninitialized return value, no Type() constructor required.
-	static Type *v_def = (Type*) malloc(sizeof(Type));
 	if (!PyErr_Occurred()) {
 	  %type_error(swig::type_name<Type>());
 	}
-	if (throw_error) throw std::invalid_argument("bad type");
-	memset(v_def,0,sizeof(Type));
-	return *v_def;
+	throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type> 
   struct traits_as<Type*, pointer_category> {
-    static Type* as(PyObject *obj, bool throw_error) {
+    static Type* as(PyObject *obj) {
       Type *v = 0;      
       int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
       if (SWIG_IsOK(res)) {
@@ -157,15 +153,14 @@
 	if (!PyErr_Occurred()) {
 	  %type_error(swig::type_name<Type>());
 	}
-	if (throw_error) throw std::invalid_argument("bad type");
-	return 0;
+	throw std::invalid_argument("bad type");
       }
     }
   };
     
   template <class Type>
-  inline Type as(PyObject *obj, bool te = false) {
-    return traits_as<Type, typename traits<Type>::category>::as(obj, te);
+  inline Type as(PyObject *obj) {
+    return traits_as<Type, typename traits<Type>::category>::as(obj);
   }
 
   template <class Type> 
diff --git a/Lib/python/std_multimap.i b/Lib/python/std_multimap.i
index 3209fb0..f78a527 100644
--- a/Lib/python/std_multimap.i
+++ b/Lib/python/std_multimap.i
@@ -23,7 +23,11 @@
 	int res = SWIG_ERROR;
 	if (PyDict_Check(obj)) {
 	  SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL);
-	  return traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
+%#if PY_VERSION_HEX >= 0x03000000
+          /* In Python 3.x the ".items()" method returns a dict_items object */
+          items = PySequence_Fast(items, ".items() didn't return a sequence!");
+%#endif
+	  res = traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
 	} else {
 	  multimap_type *p;
 	  swig_type_info *descriptor = swig::type_info<multimap_type>();
@@ -68,7 +72,17 @@
 
 %define %swig_multimap_methods(Type...) 
   %swig_map_common(Type);
+
+#if defined(SWIGPYTHON_BUILTIN)
+  %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__;
+#endif
+
   %extend {
+    // This will be called through the mp_ass_subscript slot to delete an entry.
+    void __setitem__(const key_type& key) {
+      self->erase(key);
+    }
+
     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
       self->insert(Type::value_type(key,x));
     }
diff --git a/Lib/python/std_unordered_map.i b/Lib/python/std_unordered_map.i
index 8ab4b14..53f6aa2 100644
--- a/Lib/python/std_unordered_map.i
+++ b/Lib/python/std_unordered_map.i
@@ -53,7 +53,7 @@
       static PyObject *from(const unordered_map_type& unordered_map) {
 	swig_type_info *desc = swig::type_info<unordered_map_type>();
 	if (desc && desc->clientdata) {
-	  return SWIG_NewPointerObj(new unordered_map_type(unordered_map), desc, SWIG_POINTER_OWN);
+	  return SWIG_InternalNewPointerObj(new unordered_map_type(unordered_map), desc, SWIG_POINTER_OWN);
 	} else {
 	  size_type size = unordered_map.size();
 	  Py_ssize_t pysize = (size <= (size_type) INT_MAX) ? (Py_ssize_t) size : -1;
@@ -226,7 +226,17 @@
 
 %define %swig_unordered_map_methods(Map...)
   %swig_unordered_map_common(Map)
+
+#if defined(SWIGPYTHON_BUILTIN)
+  %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__;
+#endif
+
   %extend {
+    // This will be called through the mp_ass_subscript slot to delete an entry.
+    void __setitem__(const key_type& key) {
+      self->erase(key);
+    }
+
     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
       (*self)[key] = x;
     }
diff --git a/Lib/python/std_unordered_multimap.i b/Lib/python/std_unordered_multimap.i
index f46a94b..6d7def9 100644
--- a/Lib/python/std_unordered_multimap.i
+++ b/Lib/python/std_unordered_multimap.i
@@ -30,7 +30,11 @@
 	int res = SWIG_ERROR;
 	if (PyDict_Check(obj)) {
 	  SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL);
-	  return traits_asptr_stdseq<std::unordered_multimap<K,T>, std::pair<K, T> >::asptr(items, val);
+%#if PY_VERSION_HEX >= 0x03000000
+          /* In Python 3.x the ".items()" method returns a dict_items object */
+          items = PySequence_Fast(items, ".items() didn't return a sequence!");
+%#endif
+	  res = traits_asptr_stdseq<std::unordered_multimap<K,T>, std::pair<K, T> >::asptr(items, val);
 	} else {
 	  unordered_multimap_type *p;
 	  swig_type_info *descriptor = swig::type_info<unordered_multimap_type>();
@@ -50,7 +54,7 @@
       static PyObject *from(const unordered_multimap_type& unordered_multimap) {
 	swig_type_info *desc = swig::type_info<unordered_multimap_type>();
 	if (desc && desc->clientdata) {
-	  return SWIG_NewPointerObj(new unordered_multimap_type(unordered_multimap), desc, SWIG_POINTER_OWN);
+	  return SWIG_InternalNewPointerObj(new unordered_multimap_type(unordered_multimap), desc, SWIG_POINTER_OWN);
 	} else {
 	  size_type size = unordered_multimap.size();
 	  Py_ssize_t pysize = (size <= (size_type) INT_MAX) ? (Py_ssize_t) size : -1;
@@ -75,7 +79,17 @@
 
 %define %swig_unordered_multimap_methods(Type...) 
   %swig_unordered_map_common(Type);
+
+#if defined(SWIGPYTHON_BUILTIN)
+  %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__;
+#endif
+
   %extend {
+    // This will be called through the mp_ass_subscript slot to delete an entry.
+    void __setitem__(const key_type& key) {
+      self->erase(key);
+    }
+
     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
       self->insert(Type::value_type(key,x));
     }
diff --git a/Lib/r/rrun.swg b/Lib/r/rrun.swg
index 81f6461..63b7ecc 100644
--- a/Lib/r/rrun.swg
+++ b/Lib/r/rrun.swg
@@ -350,7 +350,7 @@
   return ptr ? RSwigPacked_New((void *) ptr, sz, type) : R_NilValue;
 }
 
-/* Convert a packed value value */
+/* Convert a packed pointer value */
 
 SWIGRUNTIME int
 SWIG_R_ConvertPacked(SEXP obj, void *ptr, size_t sz, swig_type_info *ty) {
diff --git a/Lib/r/rstdcommon.swg b/Lib/r/rstdcommon.swg
index 557dac7..5f41fd1 100644
--- a/Lib/r/rstdcommon.swg
+++ b/Lib/r/rstdcommon.swg
@@ -101,12 +101,11 @@
 
   template <class Type> 
   struct traits_as<Type, value_category> {
-    static Type as(SWIG_Object obj, bool throw_error) {
+    static Type as(SWIG_Object obj) {
       Type v;
       int res = asval(obj, &v);
       if (!obj || !SWIG_IsOK(res)) {
-	if (throw_error)
-          throw std::invalid_argument("bad type");
+        throw std::invalid_argument("bad type");
       }
       return v;
     }
@@ -114,7 +113,7 @@
 
   template <class Type> 
   struct traits_as<Type, pointer_category> {
-    static Type as(SWIG_Object obj, bool throw_error) {
+    static Type as(SWIG_Object obj) {
       Type *v = 0;      
       int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
       if (SWIG_IsOK(res) && v) {
@@ -126,12 +125,7 @@
 	  return *v;
 	}
       } else {
-	// Uninitialized return value, no Type() constructor required.
-	static Type *v_def = (Type*) malloc(sizeof(Type));
-	if (throw_error)
           throw std::invalid_argument("bad type");
-	memset(v_def,0,sizeof(Type));
-	return *v_def;
       }
     }
   };
@@ -152,8 +146,8 @@
   };
     
   template <class Type>
-  inline Type as(SWIG_Object obj, bool te = false) {
-    return traits_as<Type, typename traits<Type>::category>::as(obj, te);
+  inline Type as(SWIG_Object obj) {
+    return traits_as<Type, typename traits<Type>::category>::as(obj);
   }
 
   template <class Type> 
diff --git a/Lib/r/srun.swg b/Lib/r/srun.swg
index 2045ab9..d07218a 100644
--- a/Lib/r/srun.swg
+++ b/Lib/r/srun.swg
@@ -7,7 +7,7 @@
 
 
 # This could be provided as a separate run-time library but this
-# approach allows the code to to be included directly into the
+# approach allows the code to be included directly into the
 # generated bindings and so removes the need to have and install an
 # additional library.  We may however end up with multiple copies of
 # this and some confusion at run-time as to which class to use. This
diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg
index 4f1c6f5..4d0163f 100644
--- a/Lib/ruby/rubycontainer.swg
+++ b/Lib/ruby/rubycontainer.swg
@@ -183,8 +183,8 @@
     {
       VALUE item = rb_ary_entry(_seq, _index );
       try {
-	return swig::as<T>(item, true);
-      } catch (std::exception& e) {
+	return swig::as<T>(item);
+      } catch (const std::invalid_argument& e) {
 	char msg[1024];
 	sprintf(msg, "in sequence element %d ", _index);
 	VALUE lastErr = rb_gv_get("$!");
@@ -926,7 +926,7 @@
       VALUE elem = argv[0];
       int idx = 0;
       try {
-	Sequence::value_type val = swig::as<Sequence::value_type>( elem, true );
+	Sequence::value_type val = swig::as<Sequence::value_type>( elem );
 	if ( i >= len ) {
 	  $self->resize(i-1, val);
 	  return $self;
@@ -943,7 +943,7 @@
 	  }
 
       } 
-      catch( std::invalid_argument )
+      catch( const std::invalid_argument & )
 	{
 	  rb_raise( rb_eArgError, "%s",
 		    Ruby_Format_TypeError( "", 
@@ -967,10 +967,10 @@
 	  Sequence::iterator start = $self->begin();
 	  VALUE elem = argv[idx];
 	  try {
-	    Sequence::value_type val = swig::as<Sequence::value_type>( elem, true );
+	    Sequence::value_type val = swig::as<Sequence::value_type>( elem );
 	    $self->insert( start, val );
 	  }
-	  catch( std::invalid_argument )
+	  catch( const std::invalid_argument & )
 	    {
 	      rb_raise( rb_eArgError, "%s",
 			Ruby_Format_TypeError( "", 
diff --git a/Lib/ruby/rubyrun.swg b/Lib/ruby/rubyrun.swg
index 4628aed..1afc5c1 100644
--- a/Lib/ruby/rubyrun.swg
+++ b/Lib/ruby/rubyrun.swg
@@ -363,7 +363,7 @@
   return rb_str_new2(result);
 }
 
-/* Convert a packed value value */
+/* Convert a packed pointer value */
 SWIGRUNTIME int
 SWIG_Ruby_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty) {
   swig_cast_info *tc;
diff --git a/Lib/ruby/rubystdcommon.swg b/Lib/ruby/rubystdcommon.swg
index c34dace..99dd7f8 100644
--- a/Lib/ruby/rubystdcommon.swg
+++ b/Lib/ruby/rubystdcommon.swg
@@ -115,15 +115,15 @@
 
   template <class Type> 
   struct traits_as<Type, value_category> {
-    static Type as(VALUE obj, bool throw_error) {
+    static Type as(VALUE obj) {
       Type v;
       int res = asval(obj, &v);
       if (!SWIG_IsOK(res)) {
-	if (throw_error) throw std::invalid_argument("bad type");
 	VALUE lastErr = rb_gv_get("$!");
 	if (lastErr == Qnil) {
 	  %type_error(swig::type_name<Type>());
 	}
+        throw std::invalid_argument("bad type");
       }
       return v;
     }
@@ -131,7 +131,7 @@
 
   template <class Type> 
   struct traits_as<Type, pointer_category> {
-    static Type as(VALUE obj, bool throw_error) {
+    static Type as(VALUE obj) {
       Type *v = 0;      
       int res = traits_asptr<Type>::asptr(obj, &v);
       if (SWIG_IsOK(res) && v) {
@@ -143,40 +143,35 @@
 	  return *v;
 	}
       } else {
-	// Uninitialized return value, no Type() constructor required.
-	if (throw_error) throw std::invalid_argument("bad type");
 	VALUE lastErr = rb_gv_get("$!");
 	if (lastErr == Qnil) {
 	  %type_error(swig::type_name<Type>());
 	}
-	static Type *v_def = (Type*) malloc(sizeof(Type));
-	memset(v_def,0,sizeof(Type));
-	return *v_def;
+        throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type> 
   struct traits_as<Type*, pointer_category> {
-    static Type* as(VALUE obj, bool throw_error) {
+    static Type* as(VALUE obj) {
       Type *v = 0;      
       int res = traits_asptr<Type>::asptr(obj, &v);
       if (SWIG_IsOK(res)) {
 	return v;
       } else {
-	if (throw_error) throw std::invalid_argument("bad type");
 	VALUE lastErr = rb_gv_get("$!");
 	if (lastErr == Qnil) {
 	  %type_error(swig::type_name<Type>());
 	}
-	return 0;
+        throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type>
-  inline Type as(VALUE obj, bool te = false) {
-    return traits_as< Type, typename traits< Type >::category >::as(obj, te);
+  inline Type as(VALUE obj) {
+    return traits_as< Type, typename traits< Type >::category >::as(obj);
   }
 
   template <class Type> 
diff --git a/Lib/ruby/rubywstrings.swg b/Lib/ruby/rubywstrings.swg
index b6dd937..7da6f4b 100644
--- a/Lib/ruby/rubywstrings.swg
+++ b/Lib/ruby/rubywstrings.swg
@@ -1,71 +1,57 @@
 /* -----------------------------------------------------------------------------
  * rubywstrings.swg
  *
- * Currently, Ruby does not support Unicode or WChar properly, so these
- * are still treated as char arrays for now.
- * There are other libraries available that add support to this in
- * ruby including WString, FXString, etc.
- * ----------------------------------------------------------------------------- */
-
-/* ------------------------------------------------------------
  *  utility methods for wchar_t strings 
  * ------------------------------------------------------------ */
 
-%fragment("SWIG_AsWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_AsCharPtrAndSize") {
+%fragment("SWIG_AsWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_AsCharPtrAndSize",fragment="SWIG_ruby_wstring_encoding_init") {
 SWIGINTERN int
 SWIG_AsWCharPtrAndSize(VALUE obj, wchar_t **cptr, size_t *psize, int *alloc)
 {
-  return SWIG_AsCharPtrAndSize( obj, (char**)cptr, psize, alloc);
-//   VALUE tmp = 0;
-//   bool ok = false;
-//   if ( TYPE(obj) == T_STRING ) {
-//     if (cptr) {
-//       obj = tmp = SWIG_Unicode_FromObject(obj);
-//       ok = true;
-//     }
-//   }
-//   if (ok) {
-//     Py_ssize_t len = PyUnicode_GetSize(obj);
-//     rb_notimplement();
-//     if (cptr) {
-//       *cptr = %new_array(len + 1, wchar_t);
-//       SWIG_Unicode_AsWideChar((PyUnicodeObject *)obj, *cptr, len);
-//       (*cptr)[len] = 0;
-//     }
-//     if (psize) *psize = (size_t) len + 1;
-//     if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0;
-//     return SWIG_OK;
-//   } else {
-//     swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor();
-//     if (pwchar_descriptor) {
-//       void * vptr = 0;
-//       if (SWIG_ConvertPtr(obj, &vptr, pwchar_descriptor, 0) == SWIG_OK) {
-// 	if (cptr) *cptr = (wchar_t *)vptr;
-// 	if (psize) *psize = vptr ? (wcslen((wchar_t *)vptr) + 1) : 0;
-// 	return SWIG_OK;
-//       }
-//     }
-//   }
-//   return SWIG_TypeError;
+  rb_encoding* wstr_enc = swig_ruby_wstring_encoding;
+
+  if (TYPE(obj) == T_STRING) {
+    VALUE rstr = rb_str_conv_enc(obj, rb_enc_get(obj), wstr_enc);
+    wchar_t* cstr = (wchar_t*) StringValuePtr(rstr);
+    size_t   size = RSTRING_LEN(rstr) / sizeof(wchar_t) + 1;
+
+    if ( RSTRING_LEN(rstr) % sizeof(wchar_t) != 0 ) {
+        rb_raise(rb_eRuntimeError,
+                 "The length of the byte sequence of converted string is not a multiplier of sizeof(wchar_t). Invalid byte sequence is given. Or invalid SWIG_RUBY_WSTRING_ENCODING is given when compiling this binding.");
+    }
+    if (cptr && alloc)  {
+      *alloc = SWIG_NEWOBJ;
+      *cptr = %new_array(size, wchar_t);
+      memmove(*cptr, cstr, RSTRING_LEN(rstr));
+    }
+    if (psize) *psize = size;
+
+    return SWIG_OK;
+  } else {
+    return SWIG_TypeError;
+  }
 }
 }
 
-%fragment("SWIG_FromWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_FromCharPtrAndSize") {
+%fragment("SWIG_FromWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_FromCharPtrAndSize",fragment="SWIG_ruby_wstring_encoding_init") {
 SWIGINTERNINLINE VALUE 
 SWIG_FromWCharPtrAndSize(const wchar_t * carray, size_t size)
 {
-  return SWIG_FromCharPtrAndSize( (const char*)carray, size);
-//   if (carray) {
-//     if (size > INT_MAX) {
-//       swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor();
-//       return pwchar_descriptor ? 
-// 	SWIG_NewPointerObj(%const_cast(carray,wchar_t *), pwchar_descriptor, 0) : Qnil;
-//     } else {
-//       return SWIG_Unicode_FromWideChar(carray, %numeric_cast(size,int));
-//     }
-//   } else {
-//     return Qnil;
-//   }
+  rb_encoding* wstr_enc = swig_ruby_wstring_encoding;
+  rb_encoding* rb_enc   = swig_ruby_internal_encoding;
+
+  if (carray && size <= LONG_MAX/sizeof(wchar_t)) {
+    VALUE rstr = rb_str_new( (const char*)carray, %numeric_cast(size*sizeof(wchar_t),long) );
+    rb_encoding* new_enc = rb_default_internal_encoding();
+
+    rb_enc_associate(rstr, wstr_enc);
+    if ( !new_enc ) {
+      new_enc = rb_enc;
+    }
+    return rb_str_conv_enc(rstr, wstr_enc, new_enc);
+  } else {
+    return Qnil;
+  }
 }
 }
 
diff --git a/Lib/ruby/std_basic_string.i b/Lib/ruby/std_basic_string.i
index 1351177..a513337 100644
--- a/Lib/ruby/std_basic_string.i
+++ b/Lib/ruby/std_basic_string.i
@@ -55,6 +55,10 @@
 
 #if !defined(SWIG_STD_WSTRING)
 
+%traits_swigtype(std::basic_string<wchar_t>);
+%fragment(SWIG_Traits_frag(std::basic_string<wchar_t>));
+
+
 %fragment(SWIG_AsPtr_frag(std::basic_string<wchar_t>),"header",
 	  fragment="SWIG_AsWCharPtrAndSize") {
 SWIGINTERN int
diff --git a/Lib/ruby/std_shared_ptr.i b/Lib/ruby/std_shared_ptr.i
index f2b05ef..9742230 100644
--- a/Lib/ruby/std_shared_ptr.i
+++ b/Lib/ruby/std_shared_ptr.i
@@ -80,35 +80,35 @@
 
   template <class Type>
   struct traits_as<std::shared_ptr<Type>, pointer_category> {
-    static std::shared_ptr<Type> as(VALUE obj, bool throw_error) {
+    static std::shared_ptr<Type> as(VALUE obj) {
       std::shared_ptr<Type> ret;
       std::shared_ptr<Type> *v = &ret;
       int res = traits_asptr<std::shared_ptr<Type> >::asptr(obj, &v);
       if (SWIG_IsOK(res)) {
 	return ret;
       } else {
-	if (throw_error) throw std::invalid_argument("bad type");
+	
 	VALUE lastErr = rb_gv_get("$!");
 	if (lastErr == Qnil)
 	  SWIG_Error(SWIG_TypeError,  swig::type_name<std::shared_ptr<Type> >());
-	return std::shared_ptr<Type>();
+        throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type>
   struct traits_as<std::shared_ptr<Type> *, pointer_category> {
-    static std::shared_ptr<Type> * as(VALUE obj, bool throw_error) {
+    static std::shared_ptr<Type> * as(VALUE obj) {
       std::shared_ptr<Type> *p = 0;
       int res = traits_asptr<std::shared_ptr<Type> >::asptr(obj, &p);
       if (SWIG_IsOK(res)) {
 	return p;
       } else {
-	if (throw_error) throw std::invalid_argument("bad type");
+	
 	VALUE lastErr = rb_gv_get("$!");
 	if (lastErr == Qnil)
 	  SWIG_Error(SWIG_TypeError,  swig::type_name<std::shared_ptr<Type> *>());
-	return 0;
+        throw std::invalid_argument("bad type");
       }
     }
   };
diff --git a/Lib/ruby/std_wstring.i b/Lib/ruby/std_wstring.i
index 5ca77c0..f248707 100644
--- a/Lib/ruby/std_wstring.i
+++ b/Lib/ruby/std_wstring.i
@@ -1,3 +1,50 @@
+%{
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RUBY_ENCODING_H
+#include "ruby/encoding.h"
+#endif
+
+/**
+ *  The internal encoding of std::wstring is defined based on
+ *  the size of wchar_t. If it is not appropriate for your library,
+ *  SWIG_RUBY_WSTRING_ENCODING must be given when compiling.
+ */
+#ifndef SWIG_RUBY_WSTRING_ENCODING
+
+#if WCHAR_MAX == 0x7fff || WCHAR_MAX == 0xffff
+#define SWIG_RUBY_WSTRING_ENCODING "UTF-16LE"
+#elif WCHAR_MAX == 0x7fffffff || WCHAR_MAX == 0xffffffff
+#define SWIG_RUBY_WSTRING_ENCODING "UTF-32LE"
+#else
+#error unsupported wchar_t size. SWIG_RUBY_WSTRING_ENCODING must be given.
+#endif
+
+#endif
+
+/**
+ *  If Encoding.default_internal is nil, this encoding will be used
+ *  when converting from std::wstring to String object in Ruby.
+ */
+#ifndef SWIG_RUBY_INTERNAL_ENCODING
+#define SWIG_RUBY_INTERNAL_ENCODING "UTF-8"
+#endif
+
+static rb_encoding *swig_ruby_wstring_encoding;
+static rb_encoding *swig_ruby_internal_encoding;
+
+#ifdef __cplusplus
+}
+#endif
+%}
+
+%fragment("SWIG_ruby_wstring_encoding_init", "init") {
+  swig_ruby_wstring_encoding  = rb_enc_find( SWIG_RUBY_WSTRING_ENCODING );
+  swig_ruby_internal_encoding = rb_enc_find( SWIG_RUBY_INTERNAL_ENCODING );
+}
+
 %include <rubywstrings.swg>
 %include <typemaps/std_wstring.swg>
 
diff --git a/Lib/scilab/scistdcommon.swg b/Lib/scilab/scistdcommon.swg
index 975e93a..b08fc03 100644
--- a/Lib/scilab/scistdcommon.swg
+++ b/Lib/scilab/scistdcommon.swg
@@ -104,23 +104,21 @@
 
   template <class Type>
   struct traits_as<Type, value_category> {
-    static Type as(const SwigSciObject& obj, bool throw_error) {
+    static Type as(const SwigSciObject& obj) {
       Type v;
       int res = asval(obj, &v);
       if (SWIG_IsOK(res)) {
         return v;
       } else {
-	      %type_error(swig::type_name<Type>());
-	      if (throw_error)
-          throw std::invalid_argument("bad type");
-        return res;
+        %type_error(swig::type_name<Type>());
+        throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type>
   struct traits_as<Type, pointer_category> {
-    static Type as(const SwigSciObject& obj, bool throw_error) {
+    static Type as(const SwigSciObject& obj) {
       Type *v = 0;
       int res = traits_asptr<Type>::asptr(obj, &v);
       if (SWIG_IsOK(res) && v) {
@@ -132,36 +130,29 @@
 	  return *v;
 	}
       } else {
-	// Uninitialized return value, no Type() constructor required.
-	static Type *v_def = (Type*) malloc(sizeof(Type));
-  %type_error(swig::type_name<Type>());
-	if (throw_error)
-    throw std::invalid_argument("bad type");
-	memset(v_def,0,sizeof(Type));
-	return *v_def;
+        %type_error(swig::type_name<Type>());
+        throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type>
   struct traits_as<Type*, pointer_category> {
-    static Type* as(const SwigSciObject& obj, bool throw_error) {
+    static Type* as(const SwigSciObject& obj) {
       Type *v = 0;
       int res = traits_asptr<Type>::asptr(obj, &v);
       if (SWIG_IsOK(res)) {
 	return v;
       } else {
-  %type_error(swig::type_name<Type>());
-	if (throw_error)
-    throw std::invalid_argument("bad type");
-	return SWIG_OK;
+        %type_error(swig::type_name<Type>());
+        throw std::invalid_argument("bad type");
       }
     }
   };
 
   template <class Type>
-  inline Type as(const SwigSciObject& obj, bool te = false) {
-    return traits_as<Type, typename traits<Type>::category>::as(obj, te);
+  inline Type as(const SwigSciObject& obj) {
+    return traits_as<Type, typename traits<Type>::category>::as(obj);
   }
 
   template <class Type>
diff --git a/Lib/scilab/scitypemaps.swg b/Lib/scilab/scitypemaps.swg
index 4cf0da3..682d18c 100644
--- a/Lib/scilab/scitypemaps.swg
+++ b/Lib/scilab/scitypemaps.swg
@@ -7,7 +7,7 @@
 #define SWIG_Object int
 
 #define %append_output(obj)         if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR
-#define %set_constant(name, obj)    if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR // Name is managed by the the function name
+#define %set_constant(name, obj)    if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR // Name is managed by the function name
 #define %raise(obj, type, desc)     SWIG_Scilab_Raise(obj, type, desc)
 #define %set_output(obj)            if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR
 #define %set_varoutput(obj)         if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 6f48f0d..6dc215d 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -309,11 +309,13 @@
 
 %define %$classname      %$ismember,"match$parentNode$name"  %enddef
 %define %$isnested       "match$nested"="1"  %enddef
+
 /* -----------------------------------------------------------------------------
- * Include all the warnings labels and macros 
+ * Common includes for warning labels, macros, fragments etc
  * ----------------------------------------------------------------------------- */
 
 %include <swigwarnings.swg>
+%include <swigfragments.swg>
 
 /* -----------------------------------------------------------------------------
  * Overloading support
diff --git a/Lib/swigfragments.swg b/Lib/swigfragments.swg
new file mode 100644
index 0000000..63bb6c8
--- /dev/null
+++ b/Lib/swigfragments.swg
@@ -0,0 +1,86 @@
+/* -----------------------------------------------------------------------------
+ * swigfragments.swg
+ *
+ * Common fragments
+ * ----------------------------------------------------------------------------- */
+
+/* -----------------------------------------------------------------------------
+ * Fragments for C header files
+ * ----------------------------------------------------------------------------- */
+
+%fragment("<float.h>", "header") %{
+#include <float.h>
+%}
+
+/* Default compiler options for gcc allow long_long but not LLONG_MAX. 
+ * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */
+%fragment("<limits.h>", "header") %{
+#include <limits.h>
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+#   define LLONG_MAX __LONG_LONG_MAX__
+#   define LLONG_MIN (-LLONG_MAX - 1LL)
+#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
+#endif
+%}
+
+%fragment("<math.h>", "header") %{
+#include <math.h>
+%}
+
+%fragment("<stddef.h>", "header") %{
+#include <stddef.h>
+%}
+
+%fragment("<stdio.h>", "header") %{
+#include <stdio.h>
+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
+# ifndef snprintf
+#  define snprintf _snprintf
+# endif
+#endif
+%}
+
+%fragment("<stdlib.h>", "header") %{
+#include <stdlib.h>
+#ifdef _MSC_VER
+# ifndef strtoull
+#  define strtoull _strtoui64
+# endif
+# ifndef strtoll
+#  define strtoll _strtoi64
+# endif
+#endif
+%}
+
+%fragment("<wchar.h>", "header") %{
+#include <wchar.h>
+#include <limits.h>
+#ifndef WCHAR_MIN
+#  define WCHAR_MIN 0
+#endif
+#ifndef WCHAR_MAX
+#  define WCHAR_MAX 65535
+#endif
+%}
+
+/* -----------------------------------------------------------------------------
+ * Fragments for C++ header files
+ * ----------------------------------------------------------------------------- */
+
+%fragment("<algorithm>", "header") %{
+#include <algorithm>
+%}
+
+%fragment("<stdexcept>", "header") %{
+#include <stdexcept>
+%}
+
+%fragment("<string>", "header") %{
+#include <string>
+%}
+
+%fragment("<memory>", "header") %{
+#include <memory>
+%}
diff --git a/Lib/tcl/tclrun.swg b/Lib/tcl/tclrun.swg
index f671ba2..408ddac 100644
--- a/Lib/tcl/tclrun.swg
+++ b/Lib/tcl/tclrun.swg
@@ -199,7 +199,7 @@
   return c;
 }
 
-/* Convert a packed value value */
+/* Convert a packed pointer value */
 SWIGRUNTIME int
 SWIG_Tcl_ConvertPacked(Tcl_Interp *SWIGUNUSEDPARM(interp) , Tcl_Obj *obj, void *ptr, int sz, swig_type_info *ty) {
   swig_cast_info *tc;
diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg
index 3f33ca9..aaf948c 100644
--- a/Lib/typemaps/fragments.swg
+++ b/Lib/typemaps/fragments.swg
@@ -96,75 +96,6 @@
  * common fragments 
  * ------------------------------------------------------------ */
 
-/* Default compiler options for gcc allow long_long but not LLONG_MAX. 
- * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */
-%fragment("<limits.h>","header") %{
-#include <limits.h>
-#if !defined(SWIG_NO_LLONG_MAX)
-# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
-#   define LLONG_MAX __LONG_LONG_MAX__
-#   define LLONG_MIN (-LLONG_MAX - 1LL)
-#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
-# endif
-#endif
-%}
-
-%fragment("<math.h>","header") %{
-#include <math.h>
-%}
-
-%fragment("<wchar.h>","header") %{
-#include <wchar.h>
-#include <limits.h>
-#ifndef WCHAR_MIN
-#  define WCHAR_MIN 0
-#endif
-#ifndef WCHAR_MAX
-#  define WCHAR_MAX 65535
-#endif
-%}
-
-%fragment("<float.h>","header") %{
-#include <float.h>
-%}
-
-%fragment("<stdio.h>","header") %{
-#include <stdio.h>
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
-# ifndef snprintf
-#  define snprintf _snprintf
-# endif
-#endif
-%}
-
-%fragment("<stdlib.h>","header") %{
-#include <stdlib.h>
-#ifdef _MSC_VER
-# ifndef strtoull
-#  define strtoull _strtoui64
-# endif
-# ifndef strtoll
-#  define strtoll _strtoi64
-# endif
-#endif
-%}
-
-%fragment("<stddef.h>", "header") %{
-#include <stddef.h>
-%}
-
-%fragment("<string>", "header") %{
-#include <string>
-%}
-
-%fragment("<stdexcept>", "header") %{
-#include <stdexcept>
-%}
-
-%fragment("<algorithm>", "header") %{
-#include <algorithm>
-%}
-
 %fragment("SWIG_isfinite","header",fragment="<math.h>,<float.h>") %{
 /* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */
 #ifndef SWIG_isfinite
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 69dce55..3df9896 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -194,7 +194,7 @@
  * ----------------------------------------------------------------------------- */
 
 static int promote_type(int t) {
-  if (t <= T_UCHAR || t == T_CHAR) return T_INT;
+  if (t <= T_UCHAR || t == T_CHAR || t == T_WCHAR) return T_INT;
   return t;
 }
 
@@ -209,7 +209,7 @@
 
 /* Forward renaming operator */
 
-static String *resolve_create_node_scope(String *cname);
+static String *resolve_create_node_scope(String *cname, int is_class_definition);
 
 
 Hash *Swig_cparse_features(void) {
@@ -485,8 +485,19 @@
         SetFlag(n,"deleted");
         SetFlag(n,"feature:ignore");
       }
+      if (SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) {
+	/* Ignore rvalue ref-qualifiers by default
+	 * 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);
+	  Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n),
+	      "Method with rvalue ref-qualifier %s ignored.\n", Swig_name_decl(n));
+	  SWIG_WARN_NODE_END(n);
+	  SetFlag(n, "feature:ignore");
+	}
+      }
     }
-    if (only_csymbol || GetFlag(n,"feature:ignore") || strncmp(Char(symname),"$ignore",7) == 0) {
+    if (only_csymbol || GetFlag(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0) {
       /* Only add to C symbol table and continue */
       Swig_symbol_add(0, n);
       if (!only_csymbol && !GetFlag(n, "feature:ignore")) {
@@ -815,32 +826,53 @@
   return modified_code;
 }
 
-
+/*
+#define RESOLVE_DEBUG 1
+*/
 static Node *nscope = 0;
 static Node *nscope_inner = 0;
 
 /* Remove the scope prefix from cname and return the base name without the prefix.
  * 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. If cname is found to already exist as a weak symbol
- * (forward reference) then the scope might be changed to match, such as when a symbol match 
- * is made via a using reference. */
-static String *resolve_create_node_scope(String *cname) {
+ * namespace BB in the current scope. */
+static String *resolve_create_node_scope(String *cname, int is_class_definition) {
   Symtab *gscope = 0;
   Node *cname_node = 0;
-  int skip_lookup = 0;
+  String *last = Swig_scopename_last(cname);
   nscope = 0;
   nscope_inner = 0;  
 
-  if (Strncmp(cname,"::",2) == 0)
-    skip_lookup = 1;
-
-  cname_node = skip_lookup ? 0 : Swig_symbol_clookup_no_inherit(cname, 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);
+    }
+  }
+#if RESOLVE_DEBUG
+  if (!cname_node)
+    Printf(stdout, "symbol does not yet exist (%d): [%s]\n", is_class_definition, cname);
+  else
+    Printf(stdout, "symbol does exist (%d): [%s]\n", is_class_definition, cname);
+#endif
 
   if (cname_node) {
     /* The symbol has been defined already or is in another scope.
-       If it is a weak symbol, it needs replacing and if it was brought into the current scope
-       via a using declaration, the scope needs adjusting appropriately for the new symbol.
+       If it is a weak symbol, it needs replacing and if it was brought into the current scope,
+       the scope needs adjusting appropriately for the new symbol.
        Similarly for defined templates. */
     Symtab *symtab = Getattr(cname_node, "sym:symtab");
     Node *sym_weak = Getattr(cname_node, "sym:weak");
@@ -848,48 +880,92 @@
       /* Check if the scope is the current scope */
       String *current_scopename = Swig_symbol_qualifiedscopename(0);
       String *found_scopename = Swig_symbol_qualifiedscopename(symtab);
-      int len;
       if (!current_scopename)
 	current_scopename = NewString("");
       if (!found_scopename)
 	found_scopename = NewString("");
-      len = Len(current_scopename);
-      if ((len > 0) && (Strncmp(current_scopename, found_scopename, len) == 0)) {
-	if (Len(found_scopename) > len + 2) {
-	  /* A matching weak symbol was found in non-global scope, some scope adjustment may be required */
-	  String *new_cname = NewString(Char(found_scopename) + len + 2); /* skip over "::" prefix */
-	  String *base = Swig_scopename_last(cname);
-	  Printf(new_cname, "::%s", base);
-	  cname = new_cname;
-	  Delete(base);
-	} else {
-	  /* A matching weak symbol was found in the same non-global local scope, no scope adjustment required */
-	  assert(len == Len(found_scopename));
+
+      {
+	int fail = 1;
+	List *current_scopes = Swig_scopename_tolist(current_scopename);
+	List *found_scopes = Swig_scopename_tolist(found_scopename);
+        Iterator cit = First(current_scopes);
+	Iterator fit = First(found_scopes);
+#if RESOLVE_DEBUG
+Printf(stdout, "comparing current: [%s] found: [%s]\n", current_scopename, found_scopename);
+#endif
+	for (; fit.item && cit.item; fit = Next(fit), cit = Next(cit)) {
+	  String *current = cit.item;
+	  String *found = fit.item;
+#if RESOLVE_DEBUG
+	  Printf(stdout, "  looping %s %s\n", current, found);
+#endif
+	  if (Strcmp(current, found) != 0)
+	    break;
 	}
-      } else {
-	String *base = Swig_scopename_last(cname);
-	if (Len(found_scopename) > 0) {
-	  /* A matching weak symbol was found in a different scope to the local scope - probably via a using declaration */
-	  cname = NewStringf("%s::%s", found_scopename, base);
+
+	if (!cit.item) {
+	  String *subscope = NewString("");
+	  for (; fit.item; fit = Next(fit)) {
+	    if (Len(subscope) > 0)
+	      Append(subscope, "::");
+	    Append(subscope, fit.item);
+	  }
+	  if (Len(subscope) > 0)
+	    cname = NewStringf("%s::%s", subscope, last);
+	  else
+	    cname = Copy(last);
+#if RESOLVE_DEBUG
+	  Printf(stdout, "subscope to create: [%s] cname: [%s]\n", subscope, cname);
+#endif
+	  fail = 0;
+	  Delete(subscope);
 	} else {
-	  /* Either:
-	      1) A matching weak symbol was found in a different scope to the local scope - this is actually a
-	      symbol with the same name in a different scope which we don't want, so no adjustment required.
-	      2) A matching weak symbol was found in the global scope - no adjustment required.
-	  */
-	  cname = Copy(base);
+	  if (is_class_definition) {
+	    if (!fit.item) {
+	      /* It is valid to define a new class with the same name as one forward declared in a parent scope */
+	      fail = 0;
+	    } else if (Swig_scopename_check(cname)) {
+	      /* Classes defined with scope qualifiers must have a matching forward declaration in matching scope */
+	      fail = 1;
+	    } else {
+	      /* This may let through some invalid cases */
+	      fail = 0;
+	    }
+#if RESOLVE_DEBUG
+	    Printf(stdout, "scope for class definition, fail: %d\n", fail);
+#endif
+	  } else {
+#if RESOLVE_DEBUG
+	    Printf(stdout, "no matching base scope for template\n");
+#endif
+	    fail = 1;
+	  }
 	}
-	Delete(base);
+
+	Delete(found_scopes);
+	Delete(current_scopes);
+
+	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);
+	  Delete(cname_resolved);
+	}
       }
+
       Delete(current_scopename);
       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);
+     */
   }
 
   if (Swig_scopename_check(cname)) {
     Node   *ns;
     String *prefix = Swig_scopename_prefix(cname);
-    String *base = Swig_scopename_last(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 */
@@ -899,6 +975,7 @@
       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.  */
       if (!gscope) gscope = set_scope_to_global();
       /* note that this namespace is not the "unnamed" one,
@@ -907,6 +984,7 @@
       nscope = new_node("namespace");
       Setattr(nscope,"symtab", gscope);;
       nscope_inner = nscope;
+      Delete(last);
       return base;
     }
     /* Try to locate the scope */
@@ -924,7 +1002,7 @@
 	String *nname = Swig_symbol_qualifiedscopename(nstab);
 	if (tname && (Strcmp(tname,nname) == 0)) {
 	  ns = 0;
-	  cname = base;
+	  cname = Copy(last);
 	}
 	Delete(tname);
 	Delete(nname);
@@ -932,19 +1010,10 @@
       if (ns) {
 	/* we will try to create a new node using the namespaces we
 	   can find in the scope name */
-	List *scopes;
+	List *scopes = Swig_scopename_tolist(prefix);
 	String *sname;
 	Iterator si;
-	String *name = NewString(prefix);
-	scopes = NewList();
-	while (name) {
-	  String *base = Swig_scopename_last(name);
-	  String *tprefix = Swig_scopename_prefix(name);
-	  Insert(scopes,0,base);
-	  Delete(base);
-	  Delete(name);
-	  name = tprefix;
-	}
+
 	for (si = First(scopes); si.item; si = Next(si)) {
 	  Node *ns1,*ns2;
 	  sname = si.item;
@@ -990,12 +1059,13 @@
 	  nscope_inner = ns2;
 	  if (!nscope) nscope = ns2;
 	}
-	cname = base;
+	cname = Copy(last);
 	Delete(scopes);
       }
     }
     Delete(prefix);
   }
+  Delete(last);
 
   return cname;
 }
@@ -1352,10 +1422,12 @@
 }
 
 /* -----------------------------------------------------------------------------
- * add_qualifier_to_declarator
+ * add_qualifier_to_declarator()
  *
+ * Normally the qualifier is pushed on to the front of the type.
  * Adding a qualifier to a pointer to member function is a special case.
  * For example       : typedef double (Cls::*pmf)(void) const;
+ * The qualifier is  : q(const).
  * The declarator is : m(Cls).f(void).
  * We need           : m(Cls).q(const).f(void).
  * ----------------------------------------------------------------------------- */
@@ -1363,22 +1435,39 @@
 static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) {
   int is_pointer_to_member_function = 0;
   String *decl = Copy(type);
+  String *poppedtype = NewString("");
   assert(qualifier);
-  if (SwigType_ismemberpointer(decl)) {
-    String *memberptr = SwigType_pop(decl);
-    if (SwigType_isfunction(decl)) {
-      assert(!SwigType_isqualifier(decl));
-      SwigType_push(decl, qualifier);
-      SwigType_push(decl, memberptr);
-      is_pointer_to_member_function = 1;
+
+  while (decl) {
+    if (SwigType_ismemberpointer(decl)) {
+      String *memberptr = SwigType_pop(decl);
+      if (SwigType_isfunction(decl)) {
+	is_pointer_to_member_function = 1;
+	SwigType_push(decl, qualifier);
+	SwigType_push(decl, memberptr);
+	Insert(decl, 0, poppedtype);
+	Delete(memberptr);
+	break;
+      } else {
+	Append(poppedtype, memberptr);
+      }
+      Delete(memberptr);
     } else {
-      Delete(decl);
-      decl = Copy(type);
+      String *popped = SwigType_pop(decl);
+      if (!popped)
+	break;
+      Append(poppedtype, popped);
+      Delete(popped);
     }
-    Delete(memberptr);
   }
-  if (!is_pointer_to_member_function)
+
+  if (!is_pointer_to_member_function) {
+    Delete(decl);
+    decl = Copy(type);
     SwigType_push(decl, qualifier);
+  }
+
+  Delete(poppedtype);
   return decl;
 }
 
@@ -1392,6 +1481,7 @@
     String *rawval;
     int     type;
     String *qualifier;
+    String *refqualifier;
     String *bitfield;
     Parm   *throws;
     String *throwf;
@@ -1501,7 +1591,7 @@
 
 /* Misc */
 %type <id>       identifier;
-%type <dtype>    initializer cpp_const exception_specification;
+%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;
@@ -1517,7 +1607,8 @@
 %type <dtype>    expr exprnum exprcompound valexpr;
 %type <id>       ename ;
 %type <id>       less_valparms_greater;
-%type <str>      type_qualifier ;
+%type <str>      type_qualifier;
+%type <str>      ref_qualifier;
 %type <id>       type_qualifier_raw;
 %type <id>       idstring idstringopt;
 %type <id>       pragma_lang;
@@ -1538,7 +1629,7 @@
 %type <node>     lambda_introducer lambda_body;
 %type <pl>       lambda_tail;
 %type <node>     optional_constant_directive;
-%type <str>      virt_specifier_seq;
+%type <str>      virt_specifier_seq virt_specifier_seq_opt;
 
 %%
 
@@ -1804,12 +1895,12 @@
 		   $$ = 0;
 		 }
                }
-	       /* Member const function pointers . eg.
+	       /* Member function pointers with qualifiers. eg.
 	         %constant short (Funcs::*pmf)(bool) const = &Funcs::F; */
-	       | CONSTANT type direct_declarator LPAREN parms RPAREN CONST_QUAL def_args SEMI {
+	       | 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_add_qualifier($2, "const");
+		   SwigType_push($2, $7.qualifier);
 		   SwigType_push($2, $3.type);
 		   /* Sneaky callback function trick */
 		   if (SwigType_isfunction($2)) {
@@ -2631,9 +2722,8 @@
 		  tscope = Swig_symbol_current();          /* Get the current scope */
 
 		  /* If the class name is qualified, we need to create or lookup namespace entries */
-		  if (!inclass) {
-		    $5 = resolve_create_node_scope($5);
-		  }
+		  $5 = resolve_create_node_scope($5, 0);
+
 		  if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) {
 		    outer_class	= nscope_inner;
 		  }
@@ -2991,42 +3081,46 @@
 		  SetFlag($$,"aliastemplate");
 		  add_symbols($$);
 		}
+                | cpp_static_assert {
+                   $$ = $1;
+                }
                 ;
 
 /* ------------------------------------------------------------
    A C global declaration of some kind (may be variable, function, typedef, etc.)
    ------------------------------------------------------------ */
 
-c_decl  : storage_class type declarator initializer c_decl_tail {
+c_decl  : storage_class type declarator cpp_const initializer c_decl_tail {
 	      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);
-	      Setattr($$,"value",$4.val);
+	      Setattr($$,"value",$5.val);
 	      Setattr($$,"throws",$4.throws);
 	      Setattr($$,"throw",$4.throwf);
 	      Setattr($$,"noexcept",$4.nexcept);
-	      if ($4.val && $4.type) {
+	      if ($5.val && $5.type) {
 		/* store initializer type as it might be different to the declared type */
-		SwigType *valuetype = NewSwigType($4.type);
+		SwigType *valuetype = NewSwigType($5.type);
 		if (Len(valuetype) > 0)
 		  Setattr($$,"valuetype",valuetype);
 		else
 		  Delete(valuetype);
 	      }
-	      if (!$5) {
+	      if (!$6) {
 		if (Len(scanner_ccode)) {
 		  String *code = Copy(scanner_ccode);
 		  Setattr($$,"code",code);
 		  Delete(code);
 		}
 	      } else {
-		Node *n = $5;
+		Node *n = $6;
 		/* Inherit attributes */
 		while (n) {
 		  String *type = Copy($2);
@@ -3036,8 +3130,8 @@
 		  Delete(type);
 		}
 	      }
-	      if ($4.bitfield) {
-		Setattr($$,"bitfield", $4.bitfield);
+	      if ($5.bitfield) {
+		Setattr($$,"bitfield", $5.bitfield);
 	      }
 
 	      if ($3.id) {
@@ -3052,29 +3146,33 @@
 		      String *lstr = Swig_scopename_last($3.id);
 		      Setattr($$, "name", lstr);
 		      Delete(lstr);
-		      set_nextSibling($$, $5);
+		      set_nextSibling($$, $6);
 		    } else {
 		      Delete($$);
-		      $$ = $5;
+		      $$ = $6;
 		    }
 		    Delete(p);
 		  } else {
 		    Delete($$);
-		    $$ = $5;
+		    $$ = $6;
 		  }
 		} else {
-		  set_nextSibling($$, $5);
+		  set_nextSibling($$, $6);
 		}
 	      } else {
 		Swig_error(cparse_file, cparse_line, "Missing symbol name for global declaration\n");
 		$$ = 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 initializer c_decl_tail {
+           | storage_class AUTO declarator cpp_const ARROW cpp_alternate_rettype virt_specifier_seq_opt initializer c_decl_tail {
               $$ = new_node("cdecl");
 	      if ($4.qualifier) SwigType_push($3.type, $4.qualifier);
+	      Setattr($$,"refqualifier",$4.refqualifier);
 	      Setattr($$,"type",$6);
 	      Setattr($$,"storage",$1);
 	      Setattr($$,"name",$3.id);
@@ -3084,14 +3182,14 @@
 	      Setattr($$,"throws",$4.throws);
 	      Setattr($$,"throw",$4.throwf);
 	      Setattr($$,"noexcept",$4.nexcept);
-	      if (!$8) {
+	      if (!$9) {
 		if (Len(scanner_ccode)) {
 		  String *code = Copy(scanner_ccode);
 		  Setattr($$,"code",code);
 		  Delete(code);
 		}
 	      } else {
-		Node *n = $8;
+		Node *n = $9;
 		while (n) {
 		  String *type = Copy($6);
 		  Setattr(n,"type",type);
@@ -3112,19 +3210,22 @@
 		    String *lstr = Swig_scopename_last($3.id);
 		    Setattr($$,"name",lstr);
 		    Delete(lstr);
-		    set_nextSibling($$, $8);
+		    set_nextSibling($$, $9);
 		  } else {
 		    Delete($$);
-		    $$ = $8;
+		    $$ = $9;
 		  }
 		  Delete(p);
 		} else {
 		  Delete($$);
-		  $$ = $8;
+		  $$ = $9;
 		}
 	      } else {
-		set_nextSibling($$, $8);
+		set_nextSibling($$, $9);
 	      }
+
+	      if ($4.qualifier && $1 && Strstr($1, "static"))
+		Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
            }
            ;
 
@@ -3134,27 +3235,28 @@
                    $$ = 0;
                    Clear(scanner_ccode); 
                }
-               | COMMA declarator initializer c_decl_tail {
+               | COMMA declarator cpp_const initializer c_decl_tail {
 		 $$ = new_node("cdecl");
 		 if ($3.qualifier) SwigType_push($2.type,$3.qualifier);
+		 Setattr($$,"refqualifier",$3.refqualifier);
 		 Setattr($$,"name",$2.id);
 		 Setattr($$,"decl",$2.type);
 		 Setattr($$,"parms",$2.parms);
-		 Setattr($$,"value",$3.val);
+		 Setattr($$,"value",$4.val);
 		 Setattr($$,"throws",$3.throws);
 		 Setattr($$,"throw",$3.throwf);
 		 Setattr($$,"noexcept",$3.nexcept);
-		 if ($3.bitfield) {
-		   Setattr($$,"bitfield", $3.bitfield);
+		 if ($4.bitfield) {
+		   Setattr($$,"bitfield", $4.bitfield);
 		 }
-		 if (!$4) {
+		 if (!$5) {
 		   if (Len(scanner_ccode)) {
 		     String *code = Copy(scanner_ccode);
 		     Setattr($$,"code",code);
 		     Delete(code);
 		   }
 		 } else {
-		   set_nextSibling($$,$4);
+		   set_nextSibling($$, $5);
 		 }
 	       }
                | LBRACE { 
@@ -3172,33 +3274,8 @@
                }
               ;
 
-initializer   : def_args { 
-                   $$ = $1; 
-                   $$.qualifier = 0;
-		   $$.throws = 0;
-		   $$.throwf = 0;
-		   $$.nexcept = 0;
-              }
-              | type_qualifier def_args { 
-                   $$ = $2; 
-		   $$.qualifier = $1;
-		   $$.throws = 0;
-		   $$.throwf = 0;
-		   $$.nexcept = 0;
-	      }
-              | exception_specification def_args { 
-		   $$ = $2; 
-                   $$.qualifier = 0;
-		   $$.throws = $1.throws;
-		   $$.throwf = $1.throwf;
-		   $$.nexcept = $1.nexcept;
-              }
-              | type_qualifier exception_specification def_args { 
-                   $$ = $3; 
-                   $$.qualifier = $1;
-		   $$.throws = $2.throws;
-		   $$.throwf = $2.throwf;
-		   $$.nexcept = $2.nexcept;
+initializer   : def_args {
+                   $$ = $1;
               }
               ;
 
@@ -3341,7 +3418,7 @@
 		    Namespaceprefix = Swig_symbol_qualifiedscopename(0);
 		  }
                }
-	       | storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE declarator initializer c_decl_tail {
+	       | storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE declarator cpp_const initializer c_decl_tail {
 		 Node *n;
 		 SwigType *ty = 0;
 		 String   *unnamed = 0;
@@ -3388,8 +3465,8 @@
 		   SetFlag(n,"unnamedinstance");
 		   Delete(cty);
                  }
-		 if ($10) {
-		   Node *p = $10;
+		 if ($11) {
+		   Node *p = $11;
 		   set_nextSibling(n,p);
 		   while (p) {
 		     SwigType *cty = Copy(ty);
@@ -3520,7 +3597,7 @@
 		   Setattr($<node>$,"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);
+		   scope = resolve_create_node_scope($3, 1);
 		   /* save nscope_inner to the class - it may be overwritten in nested classes*/
 		   Setattr($<node>$, "nested:innerscope", nscope_inner);
 		   Setattr($<node>$, "nested:nscope", nscope);
@@ -3897,12 +3974,12 @@
              ;
 
 cpp_opt_declarators :  SEMI { $$ = 0; }
-                    |  declarator initializer c_decl_tail {
+                    |  declarator cpp_const initializer c_decl_tail {
                         $$ = new_node("cdecl");
                         Setattr($$,"name",$1.id);
                         Setattr($$,"decl",$1.type);
                         Setattr($$,"parms",$1.parms);
-			set_nextSibling($$,$3);
+			set_nextSibling($$, $4);
                     }
                     ;
 /* ------------------------------------------------------------
@@ -4209,9 +4286,6 @@
                 | cpp_constructor_decl {
                    $$ = $1;
                 }
-                | cpp_static_assert {
-                   $$ = $1;
-                }
                 | cpp_template_decl {
 		  $$ = 0;
                 }
@@ -4469,7 +4543,6 @@
                  default_arguments($$);
              }
              | cpp_destructor_decl { $$ = $1; }
-             | cpp_static_assert { $$ = $1; }
              | cpp_protection_decl { $$ = $1; }
              | cpp_swig_directive { $$ = $1; }
              | cpp_conversion_operator { $$ = $1; }
@@ -4543,6 +4616,8 @@
 	       Setattr($$,"noexcept",$6.nexcept);
 	       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));
 	       add_symbols($$);
 	      }
 
@@ -4572,7 +4647,8 @@
 		  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($$);
 	      }
               ;
@@ -4589,6 +4665,7 @@
 		 if ($8.qualifier) {
 		   SwigType_push($4,$8.qualifier);
 		 }
+		 Setattr($$,"refqualifier",$8.refqualifier);
 		 Setattr($$,"decl",$4);
 		 Setattr($$,"parms",$6);
 		 Setattr($$,"conversion_operator","1");
@@ -4606,6 +4683,7 @@
 		 if ($8.qualifier) {
 		   SwigType_push(decl,$8.qualifier);
 		 }
+		 Setattr($$,"refqualifier",$8.refqualifier);
 		 Setattr($$,"decl",decl);
 		 Setattr($$,"parms",$6);
 		 Setattr($$,"conversion_operator","1");
@@ -4623,6 +4701,7 @@
 		 if ($8.qualifier) {
 		   SwigType_push(decl,$8.qualifier);
 		 }
+		 Setattr($$,"refqualifier",$8.refqualifier);
 		 Setattr($$,"decl",decl);
 		 Setattr($$,"parms",$6);
 		 Setattr($$,"conversion_operator","1");
@@ -4642,6 +4721,7 @@
 		 if ($9.qualifier) {
 		   SwigType_push(decl,$9.qualifier);
 		 }
+		 Setattr($$,"refqualifier",$9.refqualifier);
 		 Setattr($$,"decl",decl);
 		 Setattr($$,"parms",$7);
 		 Setattr($$,"conversion_operator","1");
@@ -4658,6 +4738,7 @@
 		if ($7.qualifier) {
 		  SwigType_push(t,$7.qualifier);
 		}
+		 Setattr($$,"refqualifier",$7.refqualifier);
 		Setattr($$,"decl",t);
 		Setattr($$,"parms",$5);
 		Setattr($$,"conversion_operator","1");
@@ -4673,7 +4754,8 @@
                }
                ;
 
-/* static_assert(bool, const char*); */
+/* static_assert(bool, const char*); (C++11)
+ * static_assert(bool); (C++17) */
 cpp_static_assert : STATIC_ASSERT LPAREN {
                 skip_balanced('(',')');
                 $$ = 0;
@@ -4727,6 +4809,9 @@
 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;
@@ -4734,6 +4819,9 @@
                | 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;
@@ -4741,6 +4829,9 @@
                | cpp_const LBRACE { 
 		    skip_balanced('{','}'); 
 		    $$.val = 0;
+		    $$.qualifier = $1.qualifier;
+		    $$.refqualifier = $1.refqualifier;
+		    $$.bitfield = 0;
 		    $$.throws = $1.throws;
 		    $$.throwf = $1.throwf;
 		    $$.nexcept = $1.nexcept;
@@ -4751,6 +4842,7 @@
                      Clear(scanner_ccode);
                      $$.val = 0;
                      $$.qualifier = $1.qualifier;
+                     $$.refqualifier = $1.refqualifier;
                      $$.bitfield = 0;
                      $$.throws = $1.throws;
                      $$.throwf = $1.throwf;
@@ -4760,6 +4852,7 @@
                      Clear(scanner_ccode);
                      $$.val = $3.val;
                      $$.qualifier = $1.qualifier;
+                     $$.refqualifier = $1.refqualifier;
                      $$.bitfield = 0;
                      $$.throws = $1.throws; 
                      $$.throwf = $1.throwf; 
@@ -4769,6 +4862,7 @@
                      skip_balanced('{','}');
                      $$.val = 0;
                      $$.qualifier = $1.qualifier;
+                     $$.refqualifier = $1.refqualifier;
                      $$.bitfield = 0;
                      $$.throws = $1.throws; 
                      $$.throwf = $1.throwf; 
@@ -5022,14 +5116,15 @@
               $$.id = 0;
 	      $$.defarg = $1.rawval ? $1.rawval : $1.val;
             }
-	    /* Member const function pointer parameters. eg.
+	    /* Member function pointers with qualifiers. eg.
 	      int f(short (Funcs::*parm)(bool) const); */
-	    | direct_declarator LPAREN parms RPAREN CONST_QUAL {
+	    | direct_declarator LPAREN parms RPAREN cv_ref_qualifier {
 	      SwigType *t;
 	      $$ = $1;
 	      t = NewStringEmpty();
 	      SwigType_add_function(t,$3);
-	      SwigType_add_qualifier(t, "const");
+	      if ($5.qualifier)
+	        SwigType_push(t, $5.qualifier);
 	      if (!$$.have_parms) {
 		$$.parms = $3;
 		$$.have_parms = 1;
@@ -5079,6 +5174,27 @@
 		$$.parms = 0;
 	      }
             }
+	    /* Member function pointers with qualifiers. eg.
+	      int f(short (Funcs::*parm)(bool) const) */
+	    | direct_declarator LPAREN parms RPAREN cv_ref_qualifier {
+	      SwigType *t;
+	      $$ = $1;
+	      t = NewStringEmpty();
+	      SwigType_add_function(t, $3);
+	      if ($5.qualifier)
+	        SwigType_push(t, $5.qualifier);
+	      if (!$$.have_parms) {
+		$$.parms = $3;
+		$$.have_parms = 1;
+	      }
+	      if (!$$.type) {
+		$$.type = t;
+	      } else {
+		SwigType_push(t, $$.type);
+		Delete($$.type);
+		$$.type = t;
+	      }
+	    }
             | empty {
    	      $$.type = 0;
               $$.id = 0;
@@ -5718,12 +5834,12 @@
 		      $$.have_parms = 1;
 		    }
 		  }
-                  | direct_abstract_declarator LPAREN parms RPAREN type_qualifier {
+                  | direct_abstract_declarator LPAREN parms RPAREN cv_ref_qualifier {
 		    SwigType *t;
                     $$ = $1;
 		    t = NewStringEmpty();
                     SwigType_add_function(t,$3);
-		    SwigType_push(t, $5);
+		    SwigType_push(t, $5.qualifier);
 		    if (!$$.type) {
 		      $$.type = t;
 		    } else {
@@ -5770,6 +5886,33 @@
            }
            ;
 
+/* cv-qualifier plus C++11 ref-qualifier for non-static member functions */
+cv_ref_qualifier : type_qualifier {
+		  $$.qualifier = $1;
+		  $$.refqualifier = 0;
+	       }
+	       | type_qualifier ref_qualifier {
+		  $$.qualifier = $1;
+		  $$.refqualifier = $2;
+		  SwigType_push($$.qualifier, $2);
+	       }
+	       | ref_qualifier {
+		  $$.qualifier = NewStringEmpty();
+		  $$.refqualifier = $1;
+		  SwigType_push($$.qualifier, $1);
+	       }
+	       ;
+
+ref_qualifier : AND {
+	          $$ = NewStringEmpty();
+	          SwigType_add_reference($$);
+	       }
+	       | LAND {
+	          $$ = NewStringEmpty();
+	          SwigType_add_rvalue_reference($$);
+	       }
+	       ;
+
 type_qualifier : type_qualifier_raw {
 	          $$ = NewStringEmpty();
 	          if ($1) SwigType_add_qualifier($$,$1);
@@ -5991,6 +6134,7 @@
 		     $$.rawval = NewStringf("%s", $$.val);
 		   }
 		   $$.qualifier = 0;
+		   $$.refqualifier = 0;
 		   $$.bitfield = 0;
 		   $$.throws = 0;
 		   $$.throwf = 0;
@@ -6016,6 +6160,7 @@
 		  $$.rawval = 0;
 		  $$.type = T_STRING;
 		  $$.qualifier = 0;
+		  $$.refqualifier = 0;
 		  $$.bitfield = 0;
 		  $$.throws = 0;
 		  $$.throwf = 0;
@@ -6029,6 +6174,7 @@
 		  $$.rawval = 0;
 		  $$.type = T_STRING;
 		  $$.qualifier = 0;
+		  $$.refqualifier = 0;
 		  $$.bitfield = 0;
 		  $$.throws = 0;
 		  $$.throwf = 0;
@@ -6192,6 +6338,7 @@
 		       break;
 		   }
 		 }
+		 $$.type = promote($2.type, $4.type);
  	       }
                | LPAREN expr pointer RPAREN expr %prec CAST {
                  $$ = $5;
@@ -6526,6 +6673,14 @@
 	       }
                ;
 
+virt_specifier_seq_opt : virt_specifier_seq {
+                   $$ = 0;
+               }
+               | empty {
+                   $$ = 0;
+               }
+               ;
+
 exception_specification : THROW LPAREN parms RPAREN {
                     $$.throws = $3;
                     $$.throwf = NewString("1");
@@ -6558,25 +6713,34 @@
 	       }
 	       ;	
 
-cpp_const      : type_qualifier {
+qualifiers_exception_specification : cv_ref_qualifier {
                     $$.throws = 0;
                     $$.throwf = 0;
                     $$.nexcept = 0;
-                    $$.qualifier = $1;
+                    $$.qualifier = $1.qualifier;
+                    $$.refqualifier = $1.refqualifier;
                }
                | exception_specification {
 		    $$ = $1;
                     $$.qualifier = 0;
+                    $$.refqualifier = 0;
                }
-               | type_qualifier exception_specification {
+               | cv_ref_qualifier exception_specification {
 		    $$ = $2;
-                    $$.qualifier = $1;
+                    $$.qualifier = $1.qualifier;
+                    $$.refqualifier = $1.refqualifier;
+               }
+               ;
+
+cpp_const      : qualifiers_exception_specification {
+                    $$ = $1;
                }
                | empty { 
                     $$.throws = 0;
                     $$.throwf = 0;
                     $$.nexcept = 0;
-                    $$.qualifier = 0; 
+                    $$.qualifier = 0;
+                    $$.refqualifier = 0;
                }
                ;
 
@@ -6587,6 +6751,8 @@
 		    $$.throws = $1.throws;
 		    $$.throwf = $1.throwf;
 		    $$.nexcept = $1.nexcept;
+                    if ($1.qualifier)
+                      Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
                | cpp_const ctor_initializer LBRACE { 
                     skip_balanced('{','}'); 
@@ -6595,6 +6761,8 @@
                     $$.throws = $1.throws;
                     $$.throwf = $1.throwf;
                     $$.nexcept = $1.nexcept;
+                    if ($1.qualifier)
+                      Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
                | LPAREN parms RPAREN SEMI { 
                     Clear(scanner_ccode); 
@@ -6627,6 +6795,8 @@
                     $$.throws = $1.throws;
                     $$.throwf = $1.throwf;
                     $$.nexcept = $1.nexcept;
+                    if ($1.qualifier)
+                      Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
                ;
 
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
index 0b4c7eeb..dd32aef 100644
--- a/Source/Include/swigwarn.h
+++ b/Source/Include/swigwarn.h
@@ -153,6 +153,7 @@
 #define WARN_TYPE_INCOMPLETE          402
 #define WARN_TYPE_ABSTRACT            403
 #define WARN_TYPE_REDEFINED           404
+#define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
 
 #define WARN_TYPEMAP_SOURCETARGET     450
 #define WARN_TYPEMAP_CHARLEAK         451
diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx
index 77f1319..f32d349 100644
--- a/Source/Modules/allegrocl.cxx
+++ b/Source/Modules/allegrocl.cxx
@@ -1685,285 +1685,6 @@
   return SWIG_OK;
 }
 
-/* very shamelessly 'borrowed' from overload.cxx, which
-   keeps the below Swig_overload_rank() code to itself.
-   We don't need a dispatch function in the C++ wrapper
-   code; we want it over on the lisp side. */
-
-#define Swig_overload_rank Allegrocl_swig_overload_rank
-
-#define MAX_OVERLOAD 256
-
-/* Overload "argc" and "argv" */
-// String *argv_template_string;
-// String *argc_template_string;
-
-struct Overloaded {
-  Node *n;			/* Node                               */
-  int argc;			/* Argument count                     */
-  ParmList *parms;		/* Parameters used for overload check */
-  int error;			/* Ambiguity error                    */
-};
-
-/* -----------------------------------------------------------------------------
- * Swig_overload_rank()
- *
- * This function takes an overloaded declaration and creates a list that ranks
- * all overloaded methods in an order that can be used to generate a dispatch 
- * function.
- * Slight difference in the way this function is used by scripting languages and
- * statically typed languages. The script languages call this method via 
- * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated,
- * however sometimes the code can never be executed. The non-scripting languages
- * call this method via Swig_overload_check() for each overloaded method in order
- * to determine whether or not the method should be wrapped. Note the slight
- * difference when overloading methods that differ by const only. The
- * scripting languages will ignore the const method, whereas the non-scripting
- * languages ignore the first method parsed.
- * ----------------------------------------------------------------------------- */
-
-static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
-  Overloaded nodes[MAX_OVERLOAD];
-  int nnodes = 0;
-  Node *o = Getattr(n, "sym:overloaded");
-  Node *c;
-
-  if (!o)
-    return 0;
-
-  c = o;
-  while (c) {
-    if (Getattr(c, "error")) {
-      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 */
-    if (Getattr(c, "wrap:name")) {
-      nodes[nnodes].n = c;
-      nodes[nnodes].parms = Getattr(c, "wrap:parms");
-      nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
-      nodes[nnodes].error = 0;
-      nnodes++;
-    }
-    c = Getattr(c, "sym:nextSibling");
-  }
-
-  /* Sort the declarations by required argument count */
-  {
-    int i, j;
-    for (i = 0; i < nnodes; i++) {
-      for (j = i + 1; j < nnodes; j++) {
-	if (nodes[i].argc > nodes[j].argc) {
-	  Overloaded t = nodes[i];
-	  nodes[i] = nodes[j];
-	  nodes[j] = t;
-	}
-      }
-    }
-  }
-
-  /* Sort the declarations by argument types */
-  {
-    int i, j;
-    for (i = 0; i < nnodes - 1; i++) {
-      if (nodes[i].argc == nodes[i + 1].argc) {
-	for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
-	  Parm *p1 = nodes[i].parms;
-	  Parm *p2 = nodes[j].parms;
-	  int differ = 0;
-	  int num_checked = 0;
-	  while (p1 && p2 && (num_checked < nodes[i].argc)) {
-	    //    Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
-	    if (checkAttribute(p1, "tmap:in:numinputs", "0")) {
-	      p1 = Getattr(p1, "tmap:in:next");
-	      continue;
-	    }
-	    if (checkAttribute(p2, "tmap:in:numinputs", "0")) {
-	      p2 = Getattr(p2, "tmap:in:next");
-	      continue;
-	    }
-	    String *t1 = Getattr(p1, "tmap:typecheck:precedence");
-	    String *t2 = Getattr(p2, "tmap:typecheck:precedence");
-	    if ((!t1) && (!nodes[i].error)) {
-	      Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
-			   "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
-			   Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
-	      nodes[i].error = 1;
-	    } else if ((!t2) && (!nodes[j].error)) {
-	      Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
-			   "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
-			   Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
-	      nodes[j].error = 1;
-	    }
-	    if (t1 && t2) {
-	      int t1v, t2v;
-	      t1v = atoi(Char(t1));
-	      t2v = atoi(Char(t2));
-	      differ = t1v - t2v;
-	    } else if (!t1 && t2)
-	      differ = 1;
-	    else if (t1 && !t2)
-	      differ = -1;
-	    else if (!t1 && !t2)
-	      differ = -1;
-	    num_checked++;
-	    if (differ > 0) {
-	      Overloaded t = nodes[i];
-	      nodes[i] = nodes[j];
-	      nodes[j] = t;
-	      break;
-	    } else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
-	      t1 = Getattr(p1, "ltype");
-	      if (!t1) {
-		t1 = SwigType_ltype(Getattr(p1, "type"));
-		if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
-		  SwigType_add_pointer(t1);
-		}
-		Setattr(p1, "ltype", t1);
-	      }
-	      t2 = Getattr(p2, "ltype");
-	      if (!t2) {
-		t2 = SwigType_ltype(Getattr(p2, "type"));
-		if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
-		  SwigType_add_pointer(t2);
-		}
-		Setattr(p2, "ltype", t2);
-	      }
-
-	      /* Need subtype check here.  If t2 is a subtype of t1, then we need to change the
-	         order */
-
-	      if (SwigType_issubtype(t2, t1)) {
-		Overloaded t = nodes[i];
-		nodes[i] = nodes[j];
-		nodes[j] = t;
-	      }
-
-	      if (Strcmp(t1, t2) != 0) {
-		differ = 1;
-		break;
-	      }
-	    } else if (differ) {
-	      break;
-	    }
-	    if (Getattr(p1, "tmap:in:next")) {
-	      p1 = Getattr(p1, "tmap:in:next");
-	    } else {
-	      p1 = nextSibling(p1);
-	    }
-	    if (Getattr(p2, "tmap:in:next")) {
-	      p2 = Getattr(p2, "tmap:in:next");
-	    } else {
-	      p2 = nextSibling(p2);
-	    }
-	  }
-	  if (!differ) {
-	    /* See if declarations differ by const only */
-	    String *d1 = Getattr(nodes[i].n, "decl");
-	    String *d2 = Getattr(nodes[j].n, "decl");
-	    if (d1 && d2) {
-	      String *dq1 = Copy(d1);
-	      String *dq2 = Copy(d2);
-	      if (SwigType_isconst(d1)) {
-		Delete(SwigType_pop(dq1));
-	      }
-	      if (SwigType_isconst(d2)) {
-		Delete(SwigType_pop(dq2));
-	      }
-	      if (Strcmp(dq1, dq2) == 0) {
-
-		if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
-		  if (script_lang_wrapping) {
-		    // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
-		    Overloaded t = nodes[i];
-		    nodes[i] = nodes[j];
-		    nodes[j] = t;
-		  }
-		  differ = 1;
-		  if (!nodes[j].error) {
-		    if (script_lang_wrapping) {
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
-				   "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
-				   "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
-		    } else {
-		      if (!Getattr(nodes[j].n, "overload:ignore")) {
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
-				     "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
-				     "using %s instead.\n", Swig_name_decl(nodes[i].n));
-		      }
-		    }
-		  }
-		  nodes[j].error = 1;
-		} else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
-		  differ = 1;
-		  if (!nodes[j].error) {
-		    if (script_lang_wrapping) {
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
-				   "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
-				   "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
-		    } else {
-		      if (!Getattr(nodes[j].n, "overload:ignore")) {
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
-				     "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
-				     "using %s instead.\n", Swig_name_decl(nodes[i].n));
-		      }
-		    }
-		  }
-		  nodes[j].error = 1;
-		}
-	      }
-	      Delete(dq1);
-	      Delete(dq2);
-	    }
-	  }
-	  if (!differ) {
-	    if (!nodes[j].error) {
-	      if (script_lang_wrapping) {
-		Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
-			     "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n));
-		Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n),
-			     "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n));
-	      } else {
-		if (!Getattr(nodes[j].n, "overload:ignore")) {
-		  Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
-			       "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-		  Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
-			       "using %s instead.\n", Swig_name_decl(nodes[i].n));
-		}
-	      }
-	      nodes[j].error = 1;
-	    }
-	  }
-	}
-      }
-    }
-  }
-  List *result = NewList();
-  {
-    int i;
-    for (i = 0; i < nnodes; i++) {
-      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;
-}
-
-/* end shameless borrowing */
-
 int any_varargs(ParmList *pl) {
   Parm *p;
 
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
index 7c2607f..813a309 100644
--- a/Source/Modules/emit.cxx
+++ b/Source/Modules/emit.cxx
@@ -454,7 +454,7 @@
   if (catchlist) {
     int unknown_catch = 0;
     int has_varargs = 0;
-    Printf(eaction, "}\n");
+    Printf(eaction, "} ");
     for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) {
       String *em = Swig_typemap_lookup("throws", ep, "_e", 0);
       if (em) {
diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx
index 1512834..9160304 100644
--- a/Source/Modules/go.cxx
+++ b/Source/Modules/go.cxx
@@ -990,7 +990,7 @@
    * overname: The overload string for overloaded function.
    * wname: The SWIG wrapped name--the name of the C function.
    * base: A list of the names of base classes, in the case where this
-   *       is is a vritual method not defined in the current class.
+   *       is a virtual method not defined in the current class.
    * parms: The parameters.
    * result: The result type.
    * is_static: Whether this is a static method or member.
diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx
index f6d4c95..fee6cd7 100644
--- a/Source/Modules/interface.cxx
+++ b/Source/Modules/interface.cxx
@@ -151,12 +151,14 @@
 	for (Node *child = firstChild(n); child; child = nextSibling(child)) {
 	  if (Getattr(child, "interface:owner"))
 	    break; // at the end of the list are newly appended methods
-	  if (checkAttribute(child, "name", name)) {
-	    String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
-	    identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0;
-	    Delete(decl);
-	    if (identically_overloaded_method)
-	      break;
+	  if (Cmp(nodeType(child), "cdecl") == 0) {
+	    if (checkAttribute(child, "name", name)) {
+	      String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
+	      identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0;
+	      Delete(decl);
+	      if (identically_overloaded_method)
+		break;
+	    }
 	  }
 	}
       }
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
index 11874ef..1e4a6bd 100644
--- a/Source/Modules/lang.cxx
+++ b/Source/Modules/lang.cxx
@@ -1949,7 +1949,7 @@
      generation of 'empty' director classes.
 
      But this has to be done outside the previous 'for'
-     an the recursive loop!.
+     and the recursive loop!.
    */
   if (n == parent) {
     int len = Len(vm);
@@ -2078,7 +2078,7 @@
      needed, since there is a public constructor already defined.  
 
      (scottm) This code is needed here to make the director_abstract +
-     test generate compilable code (Example2 in director_abastract.i).
+     test generate compilable code (Example2 in director_abstract.i).
 
      (mmatus) This is very strange, since swig compiled with gcc3.2.3
      doesn't need it here....
@@ -3308,7 +3308,7 @@
     }
     if (n) {
       /* Found a match.  Look at the prefix.  We only allow
-         the cases where where we want a proxy class for the particular type */
+         the cases where we want a proxy class for the particular type */
       bool acceptable_prefix = 
 	(Len(prefix) == 0) ||			      // simple type (pass by value)
 	(Strcmp(prefix, "p.") == 0) ||		      // pointer
diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx
index 80ea47f..08de349 100644
--- a/Source/Modules/lua.cxx
+++ b/Source/Modules/lua.cxx
@@ -1755,7 +1755,7 @@
    *
    * This is to convert the string of Lua code into a proper string, which can then be
    * emitted into the C/C++ code.
-   * Basically is is a lot of search & replacing of odd sequences
+   * Basically it is a lot of search & replacing of odd sequences
    * ---------------------------------------------------------------------------- */
 
   void escapeCode(String *str) {
@@ -1770,7 +1770,7 @@
   /* -----------------------------------------------------------------------------
    * rawGetCArraysHash(String *name)
    *
-   * A small helper to hide impelementation of how CArrays hashes are stored
+   * A small helper to hide implementation of how CArrays hashes are stored
    * ---------------------------------------------------------------------------- */
 
   Hash *rawGetCArraysHash(const_String_or_char_ptr name) {
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index 12b83b2..9822b6a 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -38,14 +38,15 @@
 int SwigRuntime = 0;		// 0 = no option, 1 = -runtime, 2 = -noruntime
 
 /* Suppress warning messages for private inheritance, preprocessor evaluation etc...
-   WARN_PP_EVALUATION            202
-   WARN_PARSE_PRIVATE_INHERIT    309
-   WARN_TYPE_ABSTRACT            403
-   WARN_LANG_OVERLOAD_CONST      512
-   WARN_PARSE_BUILTIN_NAME       321
-   WARN_PARSE_REDUNDANT          322
+   WARN_PP_EVALUATION                           202
+   WARN_PARSE_PRIVATE_INHERIT                   309
+   WARN_PARSE_BUILTIN_NAME                      321
+   WARN_PARSE_REDUNDANT                         322
+   WARN_TYPE_ABSTRACT                           403
+   WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED       405
+   WARN_LANG_OVERLOAD_CONST                     512
  */
-#define EXTRA_WARNINGS "202,309,403,512,321,322"
+#define EXTRA_WARNINGS "202,309,403,405,512,321,322"
 
 extern "C" {
   extern String *ModuleName;
diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx
index 330294e..81d1bb0 100644
--- a/Source/Modules/overload.cxx
+++ b/Source/Modules/overload.cxx
@@ -231,9 +231,21 @@
 	  }
 	  if (!differ) {
 	    /* See if declarations differ by const only */
-	    String *d1 = Getattr(nodes[i].n, "decl");
-	    String *d2 = Getattr(nodes[j].n, "decl");
-	    if (d1 && d2) {
+	    String *decl1 = Getattr(nodes[i].n, "decl");
+	    String *decl2 = Getattr(nodes[j].n, "decl");
+	    if (decl1 && decl2) {
+	      /* Remove ref-qualifiers. Note that rvalue ref-qualifiers are already ignored and 
+	       * it is illegal to overload a function with and without ref-qualifiers. So with
+	       * all the combinations of ref-qualifiers and cv-qualifiers, we just detect 
+	       * the cv-qualifier (const) overloading. */
+	      String *d1 = Copy(decl1);
+	      String *d2 = Copy(decl2);
+	      if (SwigType_isreference(d1) || SwigType_isrvalue_reference(d1)) {
+		Delete(SwigType_pop(d1));
+	      }
+	      if (SwigType_isreference(d2) || SwigType_isrvalue_reference(d2)) {
+		Delete(SwigType_pop(d2));
+	      }
 	      String *dq1 = Copy(d1);
 	      String *dq2 = Copy(d2);
 	      if (SwigType_isconst(d1)) {
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 0ab7928..061dc0c 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -1841,7 +1841,7 @@
 	  Delete(wrapobj);
 	}
       } else {
-	if (non_void_return) {
+	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);
diff --git a/Source/Modules/php5.cxx b/Source/Modules/php5.cxx
index bf5664c..2fa7649 100644
--- a/Source/Modules/php5.cxx
+++ b/Source/Modules/php5.cxx
@@ -1827,7 +1827,7 @@
 	  Delete(wrapobj);
 	}
       } else {
-	if (non_void_return) {
+	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);
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index cf81827..4e90533 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -177,7 +177,7 @@
 
 static void printSlot(File *f, String *slotval, const char *slotname, const char *functype = NULL) {
   String *slotval_override = 0;
-  if (functype)
+  if (functype && Strcmp(slotval, "0") == 0)
     slotval = slotval_override = NewStringf("(%s) %s", functype, slotval);
   int len = Len(slotval);
   int fieldwidth = len > 41 ? (len > 61 ? 0 : 61 - len) : 41 - len;
@@ -1874,6 +1874,7 @@
 	String *new_value = convertValue(value, Getattr(p, "type"));
 	if (new_value)
 	  Printf(doc, "=%s", new_value);
+	Delete(new_value);
       }
       Delete(type_str);
       Delete(made_name);
@@ -1959,9 +1960,9 @@
 		Delete(rname);
 	      } else {
 		if (CPlusPlus) {
-		  Printf(doc, "Proxy of C++ %s class.", real_classname);
+		  Printf(doc, "Proxy of C++ %s class.", SwigType_namestr(real_classname));
 		} else {
-		  Printf(doc, "Proxy of C %s struct.", real_classname);
+		  Printf(doc, "Proxy of C %s struct.", SwigType_namestr(real_classname));
 		}
 	      }
 	    }
@@ -1972,7 +1973,7 @@
 	    String *paramList = make_autodocParmList(n, showTypes);
 	    Printf(doc, "__init__(");
 	    if (showTypes)
-	      Printf(doc, "%s ", getClassName());
+	      Printf(doc, "%s ", class_name);
 	    if (Len(paramList))
 	      Printf(doc, "self, %s) -> %s", paramList, class_name);
 	    else
@@ -1983,7 +1984,7 @@
 
 	case AUTODOC_DTOR:
 	  if (showTypes)
-	    Printf(doc, "__del__(%s self)", getClassName());
+	    Printf(doc, "__del__(%s self)", class_name);
 	  else
 	    Printf(doc, "__del__(self)");
 	  break;
@@ -2031,6 +2032,70 @@
   }
 
   /* ------------------------------------------------------------
+   * convertIntegerValue()
+   *
+   * Check if string v is an integer and can be represented in
+   * Python. If so, return an appropriate Python representation,
+   * otherwise (or if we are unsure), return NIL.
+   * ------------------------------------------------------------ */
+  String *convertIntegerValue(String *v, SwigType *resolved_type) {
+    const char *const s = Char(v);
+    char *end;
+    String *result = NIL;
+
+    // Check if this is an integer number in any base.
+    long value = strtol(s, &end, 0);
+    if (errno == ERANGE || end == s)
+      return NIL;
+    if (*end != '\0') {
+      // If there is a suffix after the number, we can safely ignore "l"
+      // and (provided the number is unsigned) "u", and also combinations of
+      // these, but not anything else.
+      for (char *p = end; *p != '\0'; ++p) {
+        switch (*p) {
+          case 'l':
+          case 'L':
+	    break;
+          case 'u':
+          case 'U':
+	    if (value < 0)
+	      return NIL;
+            break;
+          default:
+            return NIL;
+        }
+      }
+    }
+    // So now we are certain that we are indeed dealing with an integer
+    // that has a representation as long given by value.
+
+    if (Cmp(resolved_type, "bool") == 0)
+      // Allow integers as the default value for a bool parameter.
+      return NewString(value ? "True" : "False");
+
+    if (value == 0)
+      return NewString(SwigType_ispointer(resolved_type) ? "None" : "0");
+
+    // v may still be octal or hexadecimal:
+    const char *p = s;
+    if (*p == '+' || *p == '-')
+      ++p;
+    if (*p == '0' && *(p+1) != 'x' && *(p+1) != 'X') {
+      // This must have been an octal number. This is the only case we
+      // cannot use in Python directly, since Python 2 and 3 use non-
+      // compatible representations.
+      result = NewString(*s == '-' ? "int('-" : "int('");
+      String *octal_string = NewStringWithSize(p, (int) (end - p));
+      Append(result, octal_string);
+      Append(result, "', 8)");
+      Delete(octal_string);
+      return result;
+    }
+    result = *end == '\0' ? Copy(v) : NewStringWithSize(s, (int) (end - s));
+    return result;
+  }
+
+  /* ------------------------------------------------------------
    * convertDoubleValue()
    *
    * Check if the given string looks like a decimal floating point constant
@@ -2068,7 +2133,7 @@
 
       // Avoid unnecessary string allocation in the common case when we don't
       // need to remove any suffix.
-      return *end == '\0' ? v : NewStringWithSize(s, (int)(end - s));
+      return *end == '\0' ? Copy(v) : NewStringWithSize(s, (int)(end - s));
     }
 
     return NIL;
@@ -2078,111 +2143,24 @@
    * convertValue()
    *
    * Check if string v can be a Python value literal or a
-   * constant. Return NIL if it isn't.
+   * constant. Return an equivalent Python representation,
+   * or NIL if it isn't, or we are unsure.
    * ------------------------------------------------------------ */
   String *convertValue(String *v, SwigType *type) {
     const char *const s = Char(v);
-    char *end;
     String *result = NIL;
-    bool fail = false;
-    SwigType *resolved_type = 0;
+    SwigType *resolved_type = SwigType_typedef_resolve_all(type);
 
-    // Check if this is a number in any base.
-    long value = strtol(s, &end, 0);
-    (void) value;
-    if (end != s) {
-      if (errno == ERANGE) {
-	// There was an overflow, we could try representing the value as Python
-	// long integer literal, but for now don't bother with it.
-	fail = true;
-      } else {
-	if (*end != '\0') {
-	  // If there is a suffix after the number, we can safely ignore any
-	  // combination of "l" and "u", but not anything else (again, stuff like
-	  // "LL" could be handled, but we don't bother to do it currently).
-	  bool seen_long = false;
-	  for (char * p = end; *p != '\0'; ++p) {
-	    switch (*p) {
-	      case 'l':
-	      case 'L':
-		// Bail out on "LL".
-		if (seen_long) {
-		  fail = true;
-		  break;
-		}
-		seen_long = true;
-		break;
-
-	      case 'u':
-	      case 'U':
-		if (value < 0)
-		  fail = true;
-		break;
-
-	      default:
-		// Except that our suffix could actually be the fractional part of
-		// a floating point number, so we still have to check for this.
-		result = convertDoubleValue(v);
-	    }
-	  }
-	}
-
-	if (!fail) {
-	  // Allow integers as the default value for a bool parameter.
-	  resolved_type = SwigType_typedef_resolve_all(type);
-	  if (Cmp(resolved_type, "bool") == 0) {
-	    result = NewString(value ? "True" : "False");
-	  } else {
-	    // Deal with the values starting with 0 first as they can be octal or
-	    // hexadecimal numbers or even pointers.
-	    if (s[0] == '0') {
-	      if (Len(v) == 1) {
-		// This is just a lone 0, but it needs to be represented differently
-		// in Python depending on whether it's a zero or a null pointer.
-		if (SwigType_ispointer(resolved_type))
-		  result = NewString("None");
-		else
-		  result = v;
-	      } else if (s[1] == 'x' || s[1] == 'X') {
-		// This must have been a hex number, we can use it directly in Python,
-		// so nothing to do here.
-	      } else {
-		// This must have been an octal number, we have to change its prefix
-		// to be "0o" in Python 3 only (and as long as we still support Python
-		// 2.5, this can't be done unconditionally).
-		if (py3) {
-		  if (end - s > 1) {
-		    result = NewString("0o");
-		    Append(result, NewStringWithSize(s + 1, (int)(end - s - 1)));
-		  }
-		}
-	      }
-	    }
-
-	    // Avoid unnecessary string allocation in the common case when we don't
-	    // need to remove any suffix.
-	    if (!result)
-	      result = *end == '\0' ? v : NewStringWithSize(s, (int)(end - s));
-	  }
-	}
-      }
-    }
-
-    // Check if this is a floating point number (notice that it wasn't
-    // necessarily parsed as a long above, consider e.g. ".123").
-    if (!fail && !result) {
+    result = convertIntegerValue(v, resolved_type);
+    if (!result) {
       result = convertDoubleValue(v);
       if (!result) {
-	if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
+	if (Strcmp(v, "true") == 0)
 	  result = NewString("True");
-	else if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
+	else if (Strcmp(v, "false") == 0)
 	  result = NewString("False");
-	else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) {
-	  if (!resolved_type)
-	    resolved_type = SwigType_typedef_resolve_all(type);
+	else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
 	  result = SwigType_ispointer(resolved_type) ? NewString("None") : NewString("0");
-	}
-
 	// This could also be an enum type, default value of which could be
 	// representable in Python if it doesn't include any scope (which could,
 	// but currently is not, translated).
@@ -2190,7 +2168,7 @@
 	  Node *lookup = Swig_symbol_clookup(v, 0);
 	  if (lookup) {
 	    if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0)
-	      result = Getattr(lookup, "sym:name");
+	      result = Copy(Getattr(lookup, "sym:name"));
 	  }
 	}
       }
@@ -2237,10 +2215,12 @@
       if (Getattr(p, "tmap:default"))
 	return false;
 
-      if (String *value = Getattr(p, "value")) {
-	String *type = Getattr(p, "type");
-	if (!convertValue(value, type))
+      String *value = Getattr(p, "value");
+      if (value) {
+	String *convertedValue = convertValue(value, Getattr(p, "type"));
+	if (!convertedValue)
 	  return false;
+	Delete(convertedValue);
       }
     }
 
@@ -2521,7 +2501,8 @@
 
     String *tmp = NewString("");
     String *dispatch;
-    const char *dispatch_code = funpack ? "return %s(self, argc, argv);" : "return %s(self, args);";
+    const char *dispatch_code = funpack ? "return %s(self, argc, argv);" :
+      (builtin_ctor ? "return %s(self, args, NULL);" : "return %s(self, args);");
 
     if (castmode) {
       dispatch = Swig_overload_dispatch_cast(n, dispatch_code, &maxargs);
@@ -2535,7 +2516,8 @@
     String *symname = Getattr(n, "sym:name");
     String *wname = Swig_name_wrapper(symname);
 
-    Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL);
+    const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
+    Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
 
     Wrapper_add_local(f, "argc", "Py_ssize_t argc");
     Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1);
@@ -2573,8 +2555,8 @@
 
     if (GetFlag(n, "feature:python:maybecall")) {
       Append(f->code, "fail:\n");
-      Append(f->code, "Py_INCREF(Py_NotImplemented);\n");
-      Append(f->code, "return Py_NotImplemented;\n");
+      Append(f->code, "  Py_INCREF(Py_NotImplemented);\n");
+      Append(f->code, "  return Py_NotImplemented;\n");
     } else {
       Node *sibl = n;
       while (Getattr(sibl, "sym:previousSibling"))
@@ -2586,7 +2568,7 @@
 	Delete(fulldecl);
       } while ((sibl = Getattr(sibl, "sym:nextSibling")));
       Append(f->code, "fail:\n");
-      Printf(f->code, "SWIG_SetErrorMsg(PyExc_NotImplementedError,"
+      Printf(f->code, "  SWIG_SetErrorMsg(PyExc_NotImplementedError,"
 	     "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\"  Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes);
       Printf(f->code, "return %s;\n", builtin_ctor ? "-1" : "0");
       Delete(protoTypes);
@@ -2749,9 +2731,10 @@
       Append(wname, overname);
     }
 
+    const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
     if (!allow_kwargs || overname) {
       if (!varargs) {
-	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
+	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
       } else {
 	Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs) {", NIL);
       }
@@ -2947,17 +2930,13 @@
 	Clear(f->def);
 	if (overname) {
 	  if (noargs) {
-	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
+	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
 	  } else {
-	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **swig_obj) {", NIL);
+	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
 	  }
 	  Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments);
 	} else {
-	  if (noargs) {
-	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
-	  } else {
-	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
-	  }
+	  Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
 	  if (onearg && !builtin_ctor) {
 	    Printf(parse_args, "if (!args) SWIG_fail;\n");
 	    Append(parse_args, "swig_obj[0] = args;\n");
@@ -3211,10 +3190,17 @@
     if (need_cleanup) {
       Printv(f->code, cleanup, NIL);
     }
-    if (builtin_ctor)
+    if (builtin_ctor) {
       Printv(f->code, "  return -1;\n", NIL);
-    else
-      Printv(f->code, "  return NULL;\n", NIL);
+    } else {
+      if (GetFlag(n, "feature:python:maybecall")) {
+	Append(f->code, "  PyErr_Clear();\n");
+	Append(f->code, "  Py_INCREF(Py_NotImplemented);\n");
+	Append(f->code, "  return Py_NotImplemented;\n");
+      } else {
+        Printv(f->code, "  return NULL;\n", NIL);
+      }
+    }
 
 
     if (funpack) {
@@ -3251,9 +3237,10 @@
       DelWrapper(f);
       f = NewWrapper();
       if (funpack) {
-	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **swig_obj) {", NIL);
+	// 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);
       } else {
-	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
+	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
       }
       Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj");
       Wrapper_add_local(f, "varargs", "PyObject *varargs");
@@ -3363,7 +3350,7 @@
 	  closure_name = Copy(wrapper_name);
 	}
 	if (func_type) {
-	  String *s = NewStringf("(%s) %s", func_type, closure_name);
+	  String *s = NewStringf("%s", closure_name);
 	  Delete(closure_name);
 	  closure_name = s;
 	}
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index 1c85330..db94ec9 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -290,8 +290,6 @@
   int membervariableHandler(Node *n);
 
   int typedefHandler(Node *n);
-  static List *Swig_overload_rank(Node *n,
-			   bool script_lang_wrapping);
 
   int memberfunctionHandler(Node *n) {
     if (debugMode)
@@ -718,7 +716,7 @@
      function that handles the scoerceout. 
      We need to check if any of the argument types have an entry in
      that map. If none do, the ignore and call the function straight.
-     Otherwise, generate the a marshalling function.
+     Otherwise, generate a marshalling function.
      Need to be able to find it in S. Or use an entirely generic one
      that evaluates the expressions.
      Handle errors in the evaluation of the function by restoring
@@ -1314,260 +1312,6 @@
     Printf(stdout, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
 }
 
-#define MAX_OVERLOAD 256
-
-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) {
-  Overloaded  nodes[MAX_OVERLOAD];
-  int         nnodes = 0;
-  Node *o = Getattr(n,"sym:overloaded");
-
-
-  if (!o) return 0;
-
-  Node *c = o;
-  while (c) {
-    if (Getattr(c,"error")) {
-      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 */
-
-    if (Getattr(c,"wrap:name")) {
-      nodes[nnodes].n = c;
-      nodes[nnodes].parms = Getattr(c,"wrap:parms");
-      nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
-      nodes[nnodes].error = 0;
-      nnodes++;
-    }
-    c = Getattr(c,"sym:nextSibling");
-  }
-  
-  /* Sort the declarations by required argument count */
-  {
-    int i,j;
-    for (i = 0; i < nnodes; i++) {
-      for (j = i+1; j < nnodes; j++) {
-	if (nodes[i].argc > nodes[j].argc) {
-	  Overloaded t = nodes[i];
-	  nodes[i] = nodes[j];
-	  nodes[j] = t;
-	}
-      }
-    }
-  }
-
-  /* Sort the declarations by argument types */
-  {
-    int i,j;
-    for (i = 0; i < nnodes-1; i++) {
-      if (nodes[i].argc == nodes[i+1].argc) {
-	for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
-	  Parm *p1 = nodes[i].parms;
-	  Parm *p2 = nodes[j].parms;
-	  int   differ = 0;
-	  int   num_checked = 0;
-	  while (p1 && p2 && (num_checked < nodes[i].argc)) {
-	    if (debugMode) {
-	      Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
-	    }
-	    if (checkAttribute(p1,"tmap:in:numinputs","0")) {
-	      p1 = Getattr(p1,"tmap:in:next");
-	      continue;
-	    }
-	    if (checkAttribute(p2,"tmap:in:numinputs","0")) {
-	      p2 = Getattr(p2,"tmap:in:next");
-	      continue;
-	    }
-	    String *t1 = Getattr(p1,"tmap:typecheck:precedence");
-	    String *t2 = Getattr(p2,"tmap:typecheck:precedence");
-	    if (debugMode) {
-	      Printf(stdout,"t1 = '%s', t2 = '%s'\n", t1, t2);
-	    }
-	    if ((!t1) && (!nodes[i].error)) {
-	      Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
-			   "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
-			   Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
-	      nodes[i].error = 1;
-	    } else if ((!t2) && (!nodes[j].error)) {
-	      Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
-			   "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
-			   Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
-	      nodes[j].error = 1;
-	    }
-	    if (t1 && t2) {
-	      int t1v, t2v;
-	      t1v = atoi(Char(t1));
-	      t2v = atoi(Char(t2));
-	      differ = t1v-t2v;
-	    }
-	    else if (!t1 && t2) differ = 1;
-	    else if (t1 && !t2) differ = -1;
-	    else if (!t1 && !t2) differ = -1;
-	    num_checked++;
-	    if (differ > 0) {
-	      Overloaded t = nodes[i];
-	      nodes[i] = nodes[j];
-	      nodes[j] = t;
-	      break;
-	    } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) {
-	      t1 = Getattr(p1,"ltype");
-	      if (!t1) {
-		t1 = SwigType_ltype(Getattr(p1,"type"));
-		if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) {
-		  SwigType_add_pointer(t1);
-		}
-		Setattr(p1,"ltype",t1);
-	      }
-	      t2 = Getattr(p2,"ltype");
-	      if (!t2) {
-		t2 = SwigType_ltype(Getattr(p2,"type"));
-		if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) {
-		  SwigType_add_pointer(t2);
-		}
-		Setattr(p2,"ltype",t2);
-	      }
-
-	      /* Need subtype check here.  If t2 is a subtype of t1, then we need to change the
-                 order */
-
-	      if (SwigType_issubtype(t2,t1)) {
-		Overloaded t = nodes[i];
-		nodes[i] = nodes[j];
-		nodes[j] = t;
-	      }
-
-	      if (Strcmp(t1,t2) != 0) {
-		differ = 1;
-		break;
-	      }
-	    } else if (differ) {
-	      break;
-	    }
-	    if (Getattr(p1,"tmap:in:next")) {
-	      p1 = Getattr(p1,"tmap:in:next");
-	    } else {
-	      p1 = nextSibling(p1);
-	    }
-	    if (Getattr(p2,"tmap:in:next")) {
-	      p2 = Getattr(p2,"tmap:in:next");
-	    } else {
-	      p2 = nextSibling(p2);
-	    }
-	  }
-	  if (!differ) {
-	    /* See if declarations differ by const only */
-	    String *d1 = Getattr(nodes[i].n, "decl");
-	    String *d2 = Getattr(nodes[j].n, "decl");
-	    if (d1 && d2) {
-	      String *dq1 = Copy(d1);
-	      String *dq2 = Copy(d2);
-	      if (SwigType_isconst(d1)) {
-		Delete(SwigType_pop(dq1));
-	      }
-	      if (SwigType_isconst(d2)) {
-		Delete(SwigType_pop(dq2));
-	      }
-	      if (Strcmp(dq1, dq2) == 0) {
-
-		if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
-		  if (script_lang_wrapping) {
-		    // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
-		    Overloaded t = nodes[i];
-		    nodes[i] = nodes[j];
-		    nodes[j] = t;
-		  }
-		  differ = 1;
-		  if (!nodes[j].error) {
-		    if (script_lang_wrapping) {
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
-				   "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
-				   "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
-		    } else {
-		      if (!Getattr(nodes[j].n, "overload:ignore")) {
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
-				     "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
-				     "using %s instead.\n", Swig_name_decl(nodes[i].n));
-		      }
-		    }
-		  }
-		  nodes[j].error = 1;
-		} else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
-		  differ = 1;
-		  if (!nodes[j].error) {
-		    if (script_lang_wrapping) {
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
-				   "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-		      Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
-				   "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
-		    } else {
-		      if (!Getattr(nodes[j].n, "overload:ignore")) {
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
-				     "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-			Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
-				     "using %s instead.\n", Swig_name_decl(nodes[i].n));
-		      }
-		    }
-		  }
-		  nodes[j].error = 1;
-		}
-	      }
-	      Delete(dq1);
-	      Delete(dq2);
-	    }
-	  }
-	  if (!differ) {
-	    if (!nodes[j].error) {
-	      if (script_lang_wrapping) {
-		Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
-			     "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n));
-		Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n),
-			     "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n));
-	      } else {
-		if (!Getattr(nodes[j].n, "overload:ignore")) {
-		  Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
-			       "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
-		  Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
-			       "using %s instead.\n", Swig_name_decl(nodes[i].n));
-		}
-	      }
-	      nodes[j].error = 1;
-	    }
-	  }
-	}
-      }
-    }
-  }
-  List *result = NewList();
-  {
-    int i;
-    for (i = 0; i < nnodes; i++) {
-      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;
-}
-
 void R::dispatchFunction(Node *n) {
   Wrapper *f = NewWrapper();
   String *symname = Getattr(n, "sym:name");
diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx
index bf8028c..57125fc 100644
--- a/Source/Modules/typepass.cxx
+++ b/Source/Modules/typepass.cxx
@@ -187,8 +187,10 @@
 			ilist = alist = NewList();
 		      Append(ilist, bcls);
 		    } else {
-		      Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
-		      Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
+		      if (!GetFlag(bcls, "feature:ignore")) {
+			Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
+			Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
+		      }
 		    }
 		  }
 		  break;
@@ -209,8 +211,10 @@
 		      ilist = alist = NewList();
 		    Append(ilist, bcls);
 		  } else {
-		    Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
-		    Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
+		    if (!GetFlag(bcls, "feature:ignore")) {
+		      Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
+		      Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
+		    }
 		  }
 		} else {
 		  Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname));
@@ -1199,10 +1203,7 @@
 	} else if (Strcmp(ntype, "enum") == 0) {
 	  SwigType_typedef_using(Getattr(n, "uname"));
 	} else if (Strcmp(ntype, "template") == 0) {
-	  /*
-	  Printf(stdout, "usingDeclaration template %s --- %s\n", Getattr(n, "name"), Getattr(n, "uname"));
 	  SwigType_typedef_using(Getattr(n, "uname"));
-	  */
 	}
       }
     }
diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx
index a91ebe0..2964ed3 100644
--- a/Source/Modules/utils.cxx
+++ b/Source/Modules/utils.cxx
@@ -59,7 +59,7 @@
     // When vtable is empty, the director class does not get emitted, so a check for an empty vtable should be done.
     // However, vtable is set in Language and so is not yet set when methods in Typepass call clean_overloaded()
     // which calls is_non_virtual_protected_access. So commented out below.
-    // Moving the director vtable creation into into Typepass should solve this problem.
+    // Moving the director vtable creation into Typepass should solve this problem.
     if (is_member_director_helper(parentNode, n) /* && Getattr(parentNode, "vtable")*/)
       result = 1;
   }
diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c
index 9da4e08..d6e5e0c 100644
--- a/Source/Swig/cwrap.c
+++ b/Source/Swig/cwrap.c
@@ -277,7 +277,7 @@
 	  SwigType_del_rvalue_reference(tvalue);
 	  tycode = SwigType_type(tvalue);
 	  if (tycode != T_USER) {
-	    /* plain primitive type, we copy the the def value */
+	    /* plain primitive type, we copy the def value */
 	    String *lstr = SwigType_lstr(tvalue, defname);
 	    defvalue = NewStringf("%s = %s", lstr, qvalue);
 	    Delete(lstr);
@@ -1024,6 +1024,15 @@
       }
     }
 
+    if (!self && SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) {
+      String *memory_header = NewString("<memory>");
+      Setfile(memory_header, Getfile(n));
+      Setline(memory_header, Getline(n));
+      Swig_fragment_emit(memory_header);
+      self = NewString("std::move(*this).");
+      Delete(memory_header);
+    }
+
     call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type);
     cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call);
 
diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c
index cfa0c68..f80fb67 100644
--- a/Source/Swig/misc.c
+++ b/Source/Swig/misc.c
@@ -823,10 +823,11 @@
 
 
 /* -----------------------------------------------------------------------------
- * Swig_scopename_prefix()
+ * Swig_scopename_split()
  *
- * Take a qualified name like "A::B::C" and return the scope name.
- * In this case, "A::B".   Returns NULL if there is no base.
+ * Take a qualified name like "A::B::C" and splits off the last name.
+ * In this case, returns "C" as last and "A::B" as prefix.
+ * Always returns non NULL for last, but prefix may be NULL if there is no prefix.
  * ----------------------------------------------------------------------------- */
 
 void Swig_scopename_split(const String *s, String **rprefix, String **rlast) {
@@ -882,6 +883,12 @@
   }
 }
 
+/* -----------------------------------------------------------------------------
+ * Swig_scopename_prefix()
+ *
+ * Take a qualified name like "A::B::C" and return the scope name.
+ * In this case, "A::B".   Returns NULL if there is no base.
+ * ----------------------------------------------------------------------------- */
 
 String *Swig_scopename_prefix(const String *s) {
   char *tmp = Char(s);
@@ -1068,6 +1075,31 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * Swig_scopename_tolist()
+ *
+ * Take a qualified scope name like "A::B::C" and convert it to a list.
+ * In this case, return a list of 3 elements "A", "B", "C".
+ * Returns an empty list if the input is empty.
+ * ----------------------------------------------------------------------------- */
+
+List *Swig_scopename_tolist(const String *s) {
+  List *scopes = NewList();
+  String *name = Len(s) == 0 ? 0 : NewString(s);
+
+  while (name) {
+    String *last = 0;
+    String *prefix = 0;
+    Swig_scopename_split(name, &prefix, &last);
+    Insert(scopes, 0, last);
+    Delete(last);
+    Delete(name);
+    name = prefix;
+  }
+  Delete(name);
+  return scopes;
+}
+
+/* -----------------------------------------------------------------------------
  * Swig_scopename_check()
  *
  * Checks to see if a name is qualified with a scope name, examples:
diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c
index ce1dbe8..d127701 100644
--- a/Source/Swig/naming.c
+++ b/Source/Swig/naming.c
@@ -1681,6 +1681,7 @@
  *   "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
  *   "MyNameSpace::ABC::ABC(int,double)"
  *   "MyNameSpace::ABC::constmethod(int) const"
+ *   "MyNameSpace::ABC::refqualifiermethod(int) const &"
  *   "MyNameSpace::ABC::variablename"
  * 
  * ----------------------------------------------------------------------------- */
@@ -1690,11 +1691,22 @@
   String *decl;
 
   qname = Swig_name_str(n);
+  decl = NewStringf("%s", qname);
 
-  if (checkAttribute(n, "kind", "variable"))
-    decl = NewStringf("%s", qname);
-  else
-    decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : "");
+  if (!checkAttribute(n, "kind", "variable")) {
+    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);
+      if (qualifiers) {
+	String *qualifiers_string = SwigType_str(qualifiers, 0);
+	Printv(decl, " ", qualifiers_string, NIL);
+	Delete(qualifiers_string);
+      }
+      Delete(decl_temp);
+    }
+  }
 
   Delete(qname);
 
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
index 829005c..364329d 100644
--- a/Source/Swig/stype.c
+++ b/Source/Swig/stype.c
@@ -44,7 +44,7 @@
  *  'z.'                = Rvalue reference (&&)
  *  'a(n).'             = Array of size n  [n]
  *  'f(..,..).'         = Function with arguments  (args)
- *  'q(str).'           = Qualifier (such as const or volatile) (const, volatile)
+ *  'q(str).'           = Qualifier, such as const or volatile (cv-qualifier)
  *  'm(cls).'           = Pointer to member (cls::*)
  *
  * The encoding follows the order that you might describe a type in words.
@@ -64,11 +64,19 @@
  *
  * More examples:
  *
- *        String Encoding                 C++ Example
- *        ---------------                 -----------
- *        p.f(bool).q(const).long         const long (*)(bool)
- *        m(Funcs).q(const).f(bool).long  long (Funcs::*)(bool) const
- *        r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int)
+ *        String Encoding                     C++ Example
+ *        ---------------                     -----------
+ *        p.f(bool).r.q(const).long           const long & (*)(bool)
+ *        m(Funcs).q(const).f(bool).long      long (Funcs::*)(bool) const
+ *        r.q(const).m(Funcs).f(int).long     long (Funcs::*const &)(int)
+ *        m(Funcs).z.q(const).f(bool).long    long (Funcs::*)(bool) const &&
+ *
+ * Function decl examples:
+ *
+ *        f(bool).                            long a(bool);
+ *        r.f(bool).                          long b(bool) &;
+ *        z.f(bool).                          long c(bool) &&;
+ *        z.q(const).f(bool).                 long d(bool) const &&;
  *
  * For the most part, this module tries to minimize the use of special
  * characters (*, [, <, etc...) in its type encoding.  One reason for this
@@ -536,10 +544,9 @@
   String *element = 0;
   String *nextelement;
   String *forwardelement;
-  String *member_const_function_element = 0;
+  SwigType *member_function_qualifiers = 0;
   List *elements;
   int nelements, i;
-  int member_const_function = 0;
 
   if (id) {
     /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */
@@ -570,14 +577,12 @@
       forwardelement = 0;
     }
     if (SwigType_isqualifier(element)) {
-      if (!member_const_function) {
+      if (!member_function_qualifiers) {
 	DOH *q = 0;
 	q = SwigType_parm(element);
 	Insert(result, 0, " ");
 	Insert(result, 0, q);
 	Delete(q);
-      } else {
-        member_const_function = 0;
       }
     } else if (SwigType_ispointer(element)) {
       Insert(result, 0, "*");
@@ -594,20 +599,28 @@
 	Insert(result, 0, "(");
 	Append(result, ")");
       }
-      if (SwigType_isqualifier(nextelement)) {
-	member_const_function_element = nextelement;
-	member_const_function = 1;
+      {
+	String *next3elements = NewStringEmpty();
+	int j;
+	for (j = i + 1; j < i + 4 && j < nelements; j++) {
+	  Append(next3elements, Getitem(elements, j));
+	}
+	if (SwigType_isfunction(next3elements))
+	  member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
+	Delete(next3elements);
       }
       Delete(q);
     } else if (SwigType_isreference(element)) {
-      Insert(result, 0, "&");
+      if (!member_function_qualifiers)
+	Insert(result, 0, "&");
       if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
 	Insert(result, 0, "(");
 	Append(result, ")");
       }
     } else if (SwigType_isrvalue_reference(element)) {
-      Insert(result, 0, "&&");
-      if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+      if (!member_function_qualifiers)
+	Insert(result, 0, "&&");
+      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
 	Insert(result, 0, "(");
 	Append(result, ")");
       }
@@ -631,12 +644,13 @@
 	  Append(result, ",");
       }
       Append(result, ")");
-      if (member_const_function_element) {
-	String *p = SwigType_str(member_const_function_element, 0);
+      if (member_function_qualifiers) {
+	String *p = SwigType_str(member_function_qualifiers, 0);
 	Append(result, " ");
 	Append(result, p);
 	Delete(p);
-	member_const_function_element = 0;
+	Delete(member_function_qualifiers);
+	member_function_qualifiers = 0;
       }
       Delete(parms);
     } else {
@@ -670,6 +684,7 @@
   int nelements, i;
   int firstarray = 1;
   int notypeconv = 0;
+  int ignore_member_function_qualifiers = 0;
 
   result = NewStringEmpty();
   tc = Copy(s);
@@ -696,6 +711,7 @@
       tc = td;
     }
   }
+
   elements = SwigType_split(tc);
   nelements = Len(elements);
 
@@ -705,14 +721,33 @@
     /* when we see a function, we need to preserve the following types */
     if (SwigType_isfunction(element)) {
       notypeconv = 1;
+      ignore_member_function_qualifiers = 0;
     }
-    if (SwigType_isqualifier(element)) {
-      /* Do nothing. Ignore */
+    if (ignore_member_function_qualifiers) {
+      /* cv-qualifiers and ref-qualifiers up until the f() element have already been added */
+    } else if (SwigType_isqualifier(element)) {
+      /* swallow cv-qualifiers */
     } else if (SwigType_ispointer(element)) {
       Append(result, element);
       firstarray = 0;
     } else if (SwigType_ismemberpointer(element)) {
       Append(result, element);
+      {
+	String *next3elements = NewStringEmpty();
+	int j;
+	for (j = i + 1; j < i + 4 && j < nelements; j++) {
+	  Append(next3elements, Getitem(elements, j));
+	}
+	if (SwigType_isfunction(next3elements)) {
+	  SwigType *member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
+	  /* compilers won't let us cast from a member function without qualifiers to one with qualifiers, so the qualifiers are kept in the ltype */
+	  if (member_function_qualifiers)
+	    Append(result, member_function_qualifiers);
+	  Delete(member_function_qualifiers);
+	  ignore_member_function_qualifiers = 1;
+	}
+	Delete(next3elements);
+      }
       firstarray = 0;
     } else if (SwigType_isreference(element)) {
       if (notypeconv) {
@@ -752,13 +787,14 @@
 }
 
 /* -----------------------------------------------------------------------------
- * SwigType_lstr(DOH *s, DOH *id)
+ * SwigType_lstr()
  *
  * Produces a type-string that is suitable as a lvalue in an expression.
  * That is, a type that can be freely assigned a value without violating
  * any C assignment rules.
  *
  *      -   Qualifiers such as 'const' and 'volatile' are stripped.
+ *          Except for member function cv-qualifiers and ref-qualifiers.
  *      -   Arrays are converted into a *single* pointer (i.e.,
  *          double [][] becomes double *).
  *      -   References are converted into a pointer.
@@ -788,7 +824,7 @@
   String *element = 0;
   String *nextelement;
   String *forwardelement;
-  String *member_const_function_element = 0;
+  String *member_function_qualifiers = 0;
   SwigType *td, *tc = 0;
   const SwigType *rs;
   List *elements;
@@ -797,7 +833,6 @@
   int firstarray = 1;
   int isreference = 0;
   int isfunction = 0;
-  int member_const_function = 0;
 
   result = NewStringEmpty();
 
@@ -846,15 +881,13 @@
       forwardelement = 0;
     }
     if (SwigType_isqualifier(element)) {
-      if (!member_const_function) {
+      if (!member_function_qualifiers) {
 	DOH *q = 0;
 	q = SwigType_parm(element);
 	Insert(result, 0, " ");
 	Insert(result, 0, q);
 	Delete(q);
 	clear = 0;
-      } else {
-        member_const_function = 0;
       }
     } else if (SwigType_ispointer(element)) {
       Insert(result, 0, "*");
@@ -868,32 +901,42 @@
       Insert(result, 0, "::*");
       q = SwigType_parm(element);
       Insert(result, 0, q);
-      Delete(q);
       if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
 	Insert(result, 0, "(");
 	Append(result, ")");
       }
-      if (SwigType_isqualifier(nextelement)) {
-	member_const_function_element = nextelement;
-	member_const_function = 1;
+      {
+	String *next3elements = NewStringEmpty();
+	int j;
+	for (j = i + 1; j < i + 4 && j < nelements; j++) {
+	  Append(next3elements, Getitem(elements, j));
+	}
+	if (SwigType_isfunction(next3elements))
+	  member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
+	Delete(next3elements);
       }
       firstarray = 0;
+      Delete(q);
     } else if (SwigType_isreference(element)) {
-      Insert(result, 0, "&");
+      if (!member_function_qualifiers) {
+	Insert(result, 0, "&");
+	if (!isfunction)
+	  isreference = 1;
+      }
       if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
 	Insert(result, 0, "(");
 	Append(result, ")");
       }
-      if (!isfunction)
-	isreference = 1;
     } else if (SwigType_isrvalue_reference(element)) {
-      Insert(result, 0, "&&");
+      if (!member_function_qualifiers) {
+	Insert(result, 0, "&&");
+	if (!isfunction)
+	  isreference = 1;
+      }
       if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
 	Insert(result, 0, "(");
 	Append(result, ")");
       }
-      if (!isfunction)
-	isreference = 1;
       clear = 0;
     } else if (SwigType_isarray(element)) {
       DOH *size;
@@ -923,12 +966,13 @@
       }
       Append(result, ")");
       Delete(parms);
-      if (member_const_function_element) {
-	String *p = SwigType_str(member_const_function_element, 0);
+      if (member_function_qualifiers) {
+	String *p = SwigType_str(member_function_qualifiers, 0);
 	Append(result, " ");
 	Append(result, p);
 	Delete(p);
-	member_const_function_element = 0;
+	Delete(member_function_qualifiers);
+	member_function_qualifiers = 0;
 	clear = 0;
       }
       isfunction = 1;
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index f25f099..7452c37 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -136,6 +136,7 @@
   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 ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node);
   extern List *SwigType_split(const SwigType *t);
   extern String *SwigType_pop(SwigType *t);
@@ -326,6 +327,7 @@
   extern String *Swig_scopename_last(const String *s);
   extern String *Swig_scopename_first(const String *s);
   extern String *Swig_scopename_suffix(const String *s);
+  extern List *Swig_scopename_tolist(const String *s);
   extern int Swig_scopename_check(const String *s);
   extern String *Swig_string_lower(String *s);
   extern String *Swig_string_upper(String *s);
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
index c548a06..965a844 100644
--- a/Source/Swig/symbol.c
+++ b/Source/Swig/symbol.c
@@ -599,7 +599,7 @@
     Setattr(ccurrent, name, n);
   }
 
-  /* Multiple entries in the C symbol table.   We append to to the symbol table */
+  /* Multiple entries in the C symbol table.   We append to the symbol table */
   if (append) {
     Node *fn, *pn = 0;
     cn = Getattr(ccurrent, name);
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index 8970c71..c0f5397 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -61,13 +61,44 @@
 
 static Hash *typemaps;
 
+/* -----------------------------------------------------------------------------
+ * typemap_identifier_fix()
+ *
+ * Create a type that can be used as a hash key lookup independent of the various
+ * ways a template parameter list can be defined. This is achieved by fully
+ * resolving the template parameters.
+ *
+ * This is a copy and modification of feature_identifier_fix in parser.y.
+ * ----------------------------------------------------------------------------- */
+
+static SwigType *typemap_identifier_fix(const SwigType *s) {
+  String *tp = SwigType_istemplate_templateprefix(s);
+  if (tp) {
+    String *ts, *ta, *tq, *tr;
+    ts = SwigType_templatesuffix(s);
+    ta = SwigType_templateargs(s);
+    tq = Swig_symbol_type_qualify(ta, 0);
+    tr = SwigType_typedef_resolve_all(ta);
+    Append(tp,tr);
+    Append(tp,ts);
+    Delete(ts);
+    Delete(ta);
+    Delete(tq);
+    Delete(tr);
+    return tp;
+  } else {
+    return NewString(s);
+  }
+}
+
 static Hash *get_typemap(const SwigType *type) {
   Hash *tm = 0;
   SwigType *dtype = 0;
   SwigType *hashtype;
 
   if (SwigType_istemplate(type)) {
-    String *ty = Swig_symbol_template_deftype(type, 0);
+    SwigType *rty = typemap_identifier_fix(type);
+    String *ty = Swig_symbol_template_deftype(rty, 0);
     dtype = Swig_symbol_type_qualify(ty, 0);
     type = dtype;
     Delete(ty);
@@ -88,7 +119,7 @@
   Hash *new_tm = 0;
   assert(*tmhash == 0);
   if (SwigType_istemplate(type)) {
-    SwigType *rty = SwigType_typedef_resolve_all(type);
+    SwigType *rty = typemap_identifier_fix(type);
     String *ty = Swig_symbol_template_deftype(rty, 0);
     String *tyq = Swig_symbol_type_qualify(ty, 0);
     hashtype = SwigType_remove_global_scope_prefix(tyq);
@@ -733,6 +764,7 @@
       SwigType *oldctype = ctype;
       ctype = SwigType_typedef_resolve(ctype_unstripped);
       Delete(oldctype);
+      Delete(ctype_unstripped);
       ctype_unstripped = Copy(ctype);
     }
   }
diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c
index b2832b6..7a0626c 100644
--- a/Source/Swig/typeobj.c
+++ b/Source/Swig/typeobj.c
@@ -43,12 +43,12 @@
  * All type constructors are denoted by a trailing '.':
  * 
  *  'p.'                = Pointer (*)
- *  'r.'                = Reference (&)
- *  'z.'                = Rvalue reference (&&)
+ *  'r.'                = Reference or ref-qualifier (&)
+ *  'z.'                = Rvalue reference or ref-qualifier (&&)
  *  'a(n).'             = Array of size n  [n]
  *  'f(..,..).'         = Function with arguments  (args)
- *  'q(str).'           = Qualifier (such as const or volatile) (const, volatile)
- *  'm(qual).'          = Pointer to member (qual::*)
+ *  'q(str).'           = Qualifier, such as const or volatile (cv-qualifier)
+ *  'm(cls).'           = Pointer to member (cls::*)
  *
  *  The complete type representation for varargs is:
  *  'v(...)'
@@ -183,9 +183,10 @@
  * SwigType_pop()
  * 
  * Pop one type element off the type.
- * Example: t in:  q(const).p.Integer
- *          t out: p.Integer
- *	   result: q(const).
+ * For example:
+ *   t in:   q(const).p.Integer
+ *   t out:  p.Integer
+ *   result: q(const).
  * ----------------------------------------------------------------------------- */
 
 SwigType *SwigType_pop(SwigType *t) {
@@ -771,7 +772,6 @@
  *                                    Functions
  *
  * SwigType_add_function()
- * SwigType_del_function()
  * SwigType_isfunction()
  * SwigType_pop_function()
  *
@@ -795,14 +795,36 @@
   return t;
 }
 
+/* -----------------------------------------------------------------------------
+ * SwigType_pop_function()
+ *
+ * Pop and return the function from the input type leaving the function's return
+ * type, if any.
+ * For example:
+ *   t in:   q(const).f().p.
+ *   t out:  p.
+ *   result: q(const).f().
+ * ----------------------------------------------------------------------------- */
+
 SwigType *SwigType_pop_function(SwigType *t) {
   SwigType *f = 0;
   SwigType *g = 0;
   char *c = Char(t);
-  if (strncmp(c, "q(", 2) == 0) {
+  if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
+    /* Remove ref-qualifier */
     f = SwigType_pop(t);
     c = Char(t);
   }
+  if (strncmp(c, "q(", 2) == 0) {
+    /* Remove cv-qualifier */
+    String *qual = SwigType_pop(t);
+    if (f) {
+      SwigType_push(qual, f);
+      Delete(f);
+    }
+    f = qual;
+    c = Char(t);
+  }
   if (strncmp(c, "f(", 2)) {
     printf("Fatal error. SwigType_pop_function applied to non-function.\n");
     abort();
@@ -814,14 +836,55 @@
   return g;
 }
 
+/* -----------------------------------------------------------------------------
+ * SwigType_pop_function_qualifiers()
+ *
+ * Pop and return the function qualifiers from the input type leaving the rest of
+ * function declaration. Returns NULL if no qualifiers.
+ * For example:
+ *   t in:   r.q(const).f().p.
+ *   t out:  f().p.
+ *   result: r.q(const)
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_pop_function_qualifiers(SwigType *t) {
+  SwigType *qualifiers = 0;
+  char *c = Char(t);
+  if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
+    /* Remove ref-qualifier */
+    String *qual = SwigType_pop(t);
+    qualifiers = qual;
+    c = Char(t);
+  }
+  if (strncmp(c, "q(", 2) == 0) {
+    /* Remove cv-qualifier */
+    String *qual = SwigType_pop(t);
+    if (qualifiers) {
+      SwigType_push(qual, qualifiers);
+      Delete(qualifiers);
+    }
+    qualifiers = qual;
+    c = Char(t);
+  }
+  assert(strncmp(c, "f(", 2) == 0);
+
+  return qualifiers;
+}
+
 int SwigType_isfunction(const SwigType *t) {
   char *c;
   if (!t) {
     return 0;
   }
   c = Char(t);
+  if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
+    /* Might be a function with a ref-qualifier, skip over */
+    c += 2;
+    if (!*c)
+      return 0;
+  }
   if (strncmp(c, "q(", 2) == 0) {
-    /* Might be a 'const' function.  Try to skip over the 'const' */
+    /* Might be a function with a cv-qualifier, skip over */
     c = strchr(c, '.');
     if (c)
       c++;
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
index e11fc78..409e28f 100644
--- a/Source/Swig/typesys.c
+++ b/Source/Swig/typesys.c
@@ -42,10 +42,15 @@
  *    "name"            -  Scope name
  *    "qname"           -  Fully qualified typename
  *    "typetab"         -  Type table containing typenames and typedef information
+ *                         For a given key in the typetab table, the value is a fully
+ *                         qualified name if not pointing to itself.
  *    "symtab"          -  Hash table of symbols defined in a scope
  *    "inherit"         -  List of inherited scopes       
  *    "parent"          -  Parent scope
  * 
+ * The contents of these tables can be viewed for debugging using the -debug-typedef
+ * option which calls SwigType_print_scope().
+ *
  * Typedef information is stored in the "typetab" hash table.  For example,
  * if you have these declarations:
  *
@@ -53,8 +58,7 @@
  *      typedef A B;
  *      typedef B *C;
  *
- * typetab is built as follows:
- *
+ * typetab in scope '' contains:
  *      "A"     : "int"
  *      "B"     : "A"
  *      "C"     : "p.B"
@@ -67,31 +71,76 @@
  *               ---> a(40).p.p.A     (B --> A)
  *               ---> a(40).p.p.int   (A --> int)
  *
+ *
+ * Using declarations are stored in the "typetab" hash table. For example,
+ *
+ *      namespace NN {
+ *        struct SS {};
+ *      }
+ *      namespace N {
+ *        struct S {};
+ *        using NN::SS;
+ *      }
+ *      using N::S;
+ *
+ * typetab in scope '' contains:
+ *      "S" : "N::S"
+ * 
+ * and typetab in scope 'N' contains:
+ *      "SS" : "NN::SS"
+ *      "S" : "S"
+ *
+ *
  * For inheritance, SWIG tries to resolve types back to the base class. For instance, if
  * you have this:
  *
- *     class Foo {
- *     public:
- *        typedef int Integer;
- *     };
+ *      class Foo {
+ *      public:
+ *         typedef int Integer;
+ *      };
+ *      struct Bar : public Foo {
+ *        void blah(Integer x);
+ *      };
  *
- *     class Bar : public Foo {
- *           void blah(Integer x);
- *     };
+ * In this case typetab in scope '' contains:
+ *      "Foo" : "Foo"
+ *      "Bar" : "Bar"
+ * and scope 'Foo' contains:
+ *      "Integer" : "int"
+ * and scope 'Bar' inherits from 'Foo' but is empty (observe that blah is not a scope or typedef)
  *
  * The argument type of Bar::blah will be set to Foo::Integer.   
  *
+ *
+ * The scope-inheritance mechanism is used to manage C++ using directives.
+ *
+ *      namespace XX {
+ *        class CC {};
+ *      }
+ *      namespace X {
+ *        class C {};
+ *        using namespace XX;
+ *      }
+ *      using namespace X;
+ *
+ * typetab in scope '' inherits from 'X'
+ * typetab in scope 'X' inherits from 'XX' and contains:
+ *      "C" : "C"
+ * typetab in scope 'XX' contains:
+ *      "CC" : "CC"
+ *
+ *
  * The scope-inheritance mechanism is used to manage C++ namespace aliases.
  * For example, if you have this:
  *
- *    namespace Foo {
- *         typedef int Integer;
- *    }
+ *      namespace Foo {
+ *        typedef int Integer;
+ *      }
  *
- *   namespace F = Foo;
+ *      namespace F = Foo;
  *
- * In this case, "F::" is defined as a scope that "inherits" from Foo.  Internally,
- * "F::" will merely be an empty scope that refers to Foo.  SWIG will never 
+ * In this case, F is defined as a scope that "inherits" from Foo.  Internally,
+ * F will merely be an empty scope that points to Foo.  SWIG will never 
  * place new type information into a namespace alias---attempts to do so
  * will generate a warning message (in the parser) and will place information into 
  * Foo instead.
@@ -166,6 +215,7 @@
  * ----------------------------------------------------------------------------- */
 
 int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name) {
+  /* Printf(stdout, "typedef %s %s\n", type, name); */
   if (Getattr(current_typetab, name))
     return -1;			/* Already defined */
   if (Strcmp(type, name) == 0) {	/* Can't typedef a name to itself */
@@ -248,10 +298,26 @@
   ttab = NewHash();
   Setattr(s, "typetab", ttab);
 
-  /* Build fully qualified name and */
+  /* Build fully qualified name */
   qname = SwigType_scope_name(s);
+#if 1
+  {
+    /* TODO: only do with templates? What happens with non-templates with code below? */
+    String *stripped_qname;
+    stripped_qname = SwigType_remove_global_scope_prefix(qname);
+    /* Use fully qualified name for hash key without unary scope prefix, qname may contain unary scope */
+    Setattr(scopes, stripped_qname, s);
+    Setattr(s, "qname", qname);
+    /*
+    Printf(stdout, "SwigType_new_scope stripped %s %s\n", qname, stripped_qname);
+    */
+    Delete(stripped_qname);
+  }
+#else
+  Printf(stdout, "SwigType_new_scope %s\n", qname);
   Setattr(scopes, qname, s);
   Setattr(s, "qname", qname);
+#endif
   Delete(qname);
 
   current_scope = s;
@@ -418,12 +484,14 @@
   Typetab *s_orig = s;
   String *nnameprefix = 0;
   static int check_parent = 1;
+  int is_template = 0;
 
   if (Getmark(s))
     return 0;
   Setmark(s, 1);
 
-  if (SwigType_istemplate(nameprefix)) {
+  is_template = SwigType_istemplate(nameprefix);
+  if (is_template) {
     nnameprefix = SwigType_typedef_resolve_all(nameprefix);
     nameprefix = nnameprefix;
   }
@@ -437,10 +505,12 @@
     } else {
       full = NewString(nameprefix);
     }
-    if (Getattr(scopes, full)) {
-      s = Getattr(scopes, full);
-    } else {
-      s = 0;
+    s = Getattr(scopes, full);
+    if (!s && is_template) {
+      /* try look up scope with all the unary scope operators within the template parameter list removed */
+      SwigType *full_stripped = SwigType_remove_global_scope_prefix(full);
+      s = Getattr(scopes, full_stripped);
+      Delete(full_stripped);
     }
     Delete(full);
     if (s) {
@@ -541,8 +611,11 @@
 /* ----------------------------------------------------------------------------- 
  * template_parameters_resolve()
  *
- * For use with templates only. The template parameters are resolved. If none
- * of the parameters can be resolved, zero is returned.
+ * For use with templates only. Attempts to resolve one template parameter.
+ *
+ * If one of the template parameters can be resolved, the type is returned with
+ * just the one parameter resolved and the remaining parameters left as is.
+ * If none of the template parameters can be resolved, zero is returned.
  * ----------------------------------------------------------------------------- */
 
 static String *template_parameters_resolve(const String *base) {
@@ -574,14 +647,15 @@
     if ((i + 1) < sz)
       Append(type, ",");
   }
-  Append(type, ")>");
-  Append(type, suffix);
-  Delete(suffix);
-  Delete(tparms);
-  if (!rep) {
+  if (rep) {
+    Append(type, ")>");
+    Append(type, suffix);
+  } else {
     Delete(type);
     type = 0;
   }
+  Delete(suffix);
+  Delete(tparms);
   return type;
 }
 
@@ -592,6 +666,17 @@
 
 /* ----------------------------------------------------------------------------- 
  * SwigType_typedef_resolve()
+ *
+ * Given a type declaration, this function looks to reduce/resolve the type via a
+ * typedef (including via C++ using declarations).
+ *
+ * If it is able to find a typedef, the resolved type is returned. If no typedef
+ * is found NULL is returned. The type name is resolved in the current scope.
+ * The type returned is not always fully qualified for the global scope, it is
+ * valid for use in the current scope. If the current scope is global scope, a
+ * fully qualified type should be returned.
+ *
+ * Some additional notes are in Doc/Manual/Extending.html.
  * ----------------------------------------------------------------------------- */
 
 /* #define SWIG_DEBUG */
@@ -718,6 +803,25 @@
       }
     }
 
+    if (!type && SwigType_istemplate(base)) {
+      String *tprefix = SwigType_templateprefix(base);
+      String *rtprefix = SwigType_typedef_resolve(tprefix);
+      /* We're looking for a using declaration on the template prefix to resolve the template prefix
+       * in another scope. Using declaration do not have template parameters. */
+      if (rtprefix && !SwigType_istemplate(rtprefix)) {
+	String *tsuffix = SwigType_templatesuffix(base);
+	String *targs = SwigType_templateargs(base);
+	type = NewString(rtprefix);
+	newtype = 1;
+	Append(type, targs);
+	Append(type, tsuffix);
+	Delete(targs);
+	Delete(tsuffix);
+	Delete(rtprefix);
+      }
+      Delete(tprefix);
+    }
+
     if (type && (Equal(base, type))) {
       if (newtype)
 	Delete(type);
@@ -911,6 +1015,9 @@
     return Copy(r);
   }
 
+#ifdef SWIG_DEBUG
+  Printf(stdout, "SwigType_typedef_resolve_all start ... %s\n", t);
+#endif
   /* Recursively resolve the typedef */
   r = NewString(t);
   while ((n = SwigType_typedef_resolve(r))) {
@@ -931,6 +1038,9 @@
     Delete(key);
     Delete(rr);
   }
+#ifdef SWIG_DEBUG
+  Printf(stdout, "SwigType_typedef_resolve_all end   === %s => %s\n", t, r);
+#endif
   return r;
 }
 
@@ -938,8 +1048,17 @@
 /* -----------------------------------------------------------------------------
  * SwigType_typedef_qualified()
  *
- * Given a type declaration, this function tries to fully qualify it according to
- * typedef scope rules.
+ * Given a type declaration, this function tries to fully qualify it so that the
+ * resulting type can be used in the global scope. The type name is resolved in
+ * the current scope.
+ *
+ * It provides a fully qualified name, not necessarily a fully expanded name.
+ * When a using declaration or using directive is found the type may not be fully
+ * expanded, but it will be resolved and fully qualified for use in the global scope.
+ *
+ * This function is for looking up scopes to qualify a type. It does not resolve
+ * C typedefs, it just qualifies them. See SwigType_typedef_resolve for resolving.
+ *
  * If the unary scope operator (::) is used as a prefix to the type to denote global
  * scope, it is left in place.
  * ----------------------------------------------------------------------------- */
@@ -1000,20 +1119,14 @@
 	       out of the current scope */
 
 	    Typetab *cs = current_scope;
-	    while (cs) {
-	      String *qs = SwigType_scope_name(cs);
-	      if (Len(qs)) {
-		Append(qs, "::");
-	      }
-	      Append(qs, e);
-	      if (Getattr(scopes, qs)) {
+	    if (cs) {
+	      Typetab *found_scope = SwigType_find_scope(cs, e);
+	      if (found_scope) {
+		String *qs = SwigType_scope_name(found_scope);
 		Clear(e);
 		Append(e, qs);
 		Delete(qs);
-		break;
 	      }
-	      Delete(qs);
-	      cs = Getattr(cs, "parent");
 	    }
 	  }
 	}
@@ -1029,10 +1142,6 @@
 	Parm *p;
 	List *parms;
 	ty = Swig_symbol_template_deftype(e, current_symtab);
-	/*
-	String *dt = Swig_symbol_template_deftype(e, current_symtab);
-	ty = Swig_symbol_type_qualify(dt, 0);
-	*/
 	e = ty;
 	parms = SwigType_parmlist(e);
 	tprefix = SwigType_templateprefix(e);
@@ -1099,9 +1208,6 @@
 	Delete(tprefix);
 	Delete(qprefix);
 	Delete(parms);
-	/*
-	Delete(dt);
-	*/
       }
       Append(result, e);
       Delete(ty);
@@ -1181,7 +1287,7 @@
 
   String *defined_name = 0;
 
-  /*  Printf(stdout,"using %s\n", name); */
+  /* Printf(stdout, "using %s\n", name); */
 
   if (!Swig_scopename_check(name))
     return -1;			/* Not properly qualified */
diff --git a/Tools/travis-linux-install.sh b/Tools/travis-linux-install.sh
index 43bdb77..4a958df 100755
--- a/Tools/travis-linux-install.sh
+++ b/Tools/travis-linux-install.sh
@@ -33,10 +33,7 @@
 	"javascript")
 		case "$ENGINE" in
 			"node")
-				travis_retry sudo add-apt-repository -y ppa:chris-lea/node.js
-				travis_retry sudo apt-get -qq update
-				travis_retry sudo apt-get install -qq nodejs rlwrap
-				travis_retry sudo npm install -g node-gyp
+				travis_retry sudo apt-get install -qq nodejs node-gyp
 				;;
 			"jsc")
 				travis_retry sudo apt-get install -qq libwebkitgtk-dev
@@ -88,7 +85,7 @@
 		travis_retry sudo apt-get -qq install php$VER-cli php$VER-dev
 		;;
 	"python")
-		pip install pep8
+		pip install --user pep8
 		if [[ "$PY3" ]]; then
 			travis_retry sudo apt-get install -qq python3-dev
 		fi
diff --git a/configure.ac b/configure.ac
index 130882c..d2f2c85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -280,7 +280,7 @@
 AC_MSG_RESULT($RPATH)
 
 # LINKFORSHARED are the flags passed to the $(CC) command that links
-# the a few executables -- this is only needed for a few systems
+# a few executables -- this is only needed for a few systems
 
 AC_MSG_CHECKING(LINKFORSHARED)
 if test -z "$LINKFORSHARED"