Merge pull request #1142 from jder/csharp-doc-fix

Copy over Java documentation changes on possible GC issues to C# docs
diff --git a/CHANGES.current b/CHANGES.current
index b1c35d4..0aad216 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,52 @@
 Version 4.0.0 (in progress)
 ===========================
 
+2018-01-12: wsfulton
+            [Java] Fix issue #1156. Add missing throws clause for interfaces when using the
+            %interface family of macros.
+
+2018-01-05: wsfulton
+            Fix default arguments using expressions containing -> syntax error. Problem reported on
+            swig-user mailing list.
+
+2017-12-30: wsfulton
+            [Python] Replace pep8 with pycodestyle for checking the Python code style when
+            running Python tests.
+
+2017-12-30: davedissian
+            Fixed a symbol lookup issue when encountering a typedef of a symbol from the tag
+            namespace to the global namespace when the names are identical, such as 'typedef
+            struct Foo Foo;'.
+
+2017-12-13: wsfulton
+            [Perl] add missing support for directorfree typemaps.
+
+2017-12-13: wsfulton
+            Issue #1167 Fix directorout typemaps which were causing undefined behaviour when
+            returning pointers by reference.
+
+2017-12-08: olly
+	    [PHP] Use ZEND_MODULE_GLOBALS_ACCESSOR to access globals - this
+	    should make the generated code work with PHP 7.2.0.
+
+2017-12-04: wsfulton
+            [Python] Add missing checks for failures in calls to PyUnicode_AsUTF8String. Previously a 
+            seg fault could occur when passing invalid UTF8 strings (low surrogates), eg passing
+            u"\udcff" to the C layer (Python 3).
+
+2017-11-24: joequant
+	    Fix #1124 and return R_NilValue for null pointers
+
+2017-11-29: wsfulton
+            [Java] director exception handling improvements.
+
+            When a director method throws an exception and it is caught by DirectorException
+            and passed back to Java using Swig::DirectorException::throwException, the Java
+            stack trace now contains the original source line that threw the exception.
+
+            Deprecate Swig::DirectorException::raiseJavaException, please replace usage with
+            Swig::DirectorException::throwException.
+
 2017-10-26: wsfulton
             Add support for C++11 ref-qualifiers when using directors.
 
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 061f4e2..5cc796c 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -484,7 +484,7 @@
 <li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a>
 <li><a href="Typemaps.html#Typemaps_nn36">"varin" typemap</a>
 <li><a href="Typemaps.html#Typemaps_nn37">"varout" typemap</a>
-<li><a href="Typemaps.html#throws_typemap">"throws" typemap</a>
+<li><a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemap</a>
 </ul>
 <li><a href="Typemaps.html#Typemaps_nn39">Some typemap examples</a>
 <ul>
@@ -1036,6 +1036,9 @@
 <li><a href="Java.html#Java_directors_threading">Director threading issues</a>
 <li><a href="Java.html#Java_directors_performance">Director performance tuning</a>
 <li><a href="Java.html#Java_exceptions_from_directors">Java exceptions from directors</a>
+<ul>
+<li><a href="Java.html#Java_customizing_director_exceptions">Customizing director exceptions</a>
+</ul>
 </ul>
 <li><a href="Java.html#Java_allprotected">Accessing protected members</a>
 <li><a href="Java.html#Java_common_customization">Common customization features</a>
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html
index 69cdc4e..3b6cb3a 100644
--- a/Doc/Manual/Java.html
+++ b/Doc/Manual/Java.html
@@ -94,6 +94,9 @@
 <li><a href="#Java_directors_threading">Director threading issues</a>
 <li><a href="#Java_directors_performance">Director performance tuning</a>
 <li><a href="#Java_exceptions_from_directors">Java exceptions from directors</a>
+<ul>
+<li><a href="#Java_customizing_director_exceptions">Customizing director exceptions</a>
+</ul>
 </ul>
 <li><a href="#Java_allprotected">Accessing protected members</a>
 <li><a href="#Java_common_customization">Common customization features</a>
@@ -3746,12 +3749,10 @@
 
 <div class="code">
 <pre>
-public class DirectorDerived extends DirectorBase {
-  public DirectorDerived() {
-  }
-
+class DirectorDerived extends DirectorBase {
+  @Override
   public void upcall_method() {
-    System.out.println("DirectorDerived::upcall_method() invoked.");
+    System.out.println("DirectorDerived.upcall_method() invoked.");
   }
 }
 </pre>
@@ -3774,7 +3775,7 @@
 
 <div class="code">
 <pre>
-DirectorDerived::upcall_method() invoked.
+DirectorDerived.upcall_method() invoked.
 </pre>
 </div>
 
@@ -3825,45 +3826,186 @@
 <p>
 With directors routing method calls to Java, and proxies routing them
 to C++, the handling of exceptions is an important concern.
-The default behavior from SWIG 3.0
-onwards is to convert the thrown Java exception into a SWIG defined
-<code>DirectorException</code> C++ exception.
-SWIG 2.0 and earlier versions didn't provide any mechanism to handle the Java director method exceptions in C++.
+The default behavior for Java exceptions thrown in a director method overridden in Java is
+to store the thrown Java exception into a SWIG defined
+<code>Swig::DirectorException</code> C++ class exception in the C++ layer and then throw this C++ exception.
 </p>
 
 <p>
-Converting Java exceptions into C++ exceptions can be done in two different ways using
-the <code>director:except</code> <a href="Customization.html#Customization_features">feature</a>.
-In the simplest approach, a code block is attached to each director method to
-handle the mapping of Java exceptions into C++ exceptions.
+Of course, should this exception be thrown, your C++ code must catch it and handle it before returning back to Java.
+The default generated code <b>does not</b> attempt to handle the C++ exception, but there is a simple way
+to make this all work by catching the C++ exception and extracting the original Java exception by using <tt>%catches</tt> for <tt>Swig::DirectorException</tt>.
+Consider the example shown earlier with a modification to the <tt>upcall_method</tt> Java method to throw a Java exception:
 </p>
 
 <div class="code">
 <pre>
-%feature("director:except") MyClass::method(int x) {
-  jthrowable $error = jenv-&gt;ExceptionOccurred();
-  if ($error) {
-    jenv-&gt;ExceptionClear();
-    if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
-      throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
-    if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
-      throw MyCppException(Swig::JavaExceptionMessage(jenv, $error).message());
-    throw std::runtime_error("Unexpected exception thrown in MyClass::method");
+class DirectorDerived extends DirectorBase {
+  @Override
+  public void upcall_method() {
+    System.out.println("DirectorDerived.upcall_method() invoked.");
+    throw new RuntimeException("There was a problem!");
   }
 }
-
-class MyClass {
-  /** Throws either a std::out_of_range or MyCppException on error */
-  void method(int x);
-}
 </pre>
 </div>
 
 <p>
-This approach allows a flexible mapping of Java exceptions thrown by director methods into
-C++ exceptions expected by a C++ caller.  There
-need not be any C++ <em>exception specifications</em> on the C++ method. The
-utility function <code>Swig::ExceptionMatches</code>
+Now, by default, the JVM will abort when <tt>example.callup(director)</tt> is called as the C++
+<tt>Swig::DirectorException</tt> (storing the Java exception) is thrown and not handled by the <tt>callup</tt> method.
+Needless to say this is not very user friendly and so the recommendation is to add the following
+simple <tt>%catches</tt> directive before SWIG parses the <tt>callup</tt> function:
+</p>
+
+<div class="code">
+<pre>
+%catches(Swig::DirectorException) callup;
+</pre>
+</div>
+
+<p>
+Or target all wrapped methods using:
+</p>
+
+<div class="code">
+<pre>
+%catches(Swig::DirectorException);
+</pre>
+</div>
+
+<p>
+This tells SWIG to generate a C++ catch handler using some code from the <a href="Typemaps.html#Typemaps_throws_typemap">throws typemap</a> for <tt>Swig::DirectorException</tt> that SWIG supplies by default, see <a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>.
+This typemap code is written to simply catch the C++ <tt>Swig::DirectorException</tt> class and immediately
+return to Java throwing the original Java exception that it has stored.
+The net result is a stack trace containing the original Java exception including the location that the exception was thown from.
+</p>
+
+<div class="shell">
+<pre>
+DirectorDerived.upcall_method() invoked.
+Exception in thread "main" java.lang.RuntimeException: There was a problem!
+    at DirectorDerived.upcall_method(runme.java:4)
+    at exampleJNI.SwigDirector_DirectorBase_upcall_method(exampleJNI.java:20)
+    at exampleJNI.callup(Native Method)
+    at example.callup(example.java:12)
+    at runme.main(runme.java:21)
+</pre>
+</div>
+
+<p>
+More on the <tt>Swig::DirectorException</tt> class can be found in the next section which details how to customize the handling of director exceptions.
+</p>
+
+<H4><a name="Java_customizing_director_exceptions">25.5.7.1 Customizing director exceptions</a></H4>
+
+
+<p>
+This section is for advanced customization of director exceptions.
+The recommendation for most users is to use the simple <tt>%catches</tt> directive described above as it should be sufficient for most users needs.
+</p>
+
+<p>
+The conversion of Java exceptions into C++ exceptions can be customized in two different ways using
+the <code>director:except</code> <a href="Customization.html#Customization_features">feature</a>.
+In the first approach, a code block is attached to each director method to
+handle the mapping of Java exceptions into C++ exceptions.
+The code block is generated just after the call up from the C++ director method into the overloaded method in Java. Its primary function is to check if a Java exception has been thrown and then handle it in C++.
+The example below converts a 
+<tt>java.lang.IndexOutOfBoundsException</tt> into a C++ <tt>std::out_of_range</tt> exception and converts a
+user's Java <tt>MyJavaException</tt> into a C++ <tt>MyCppException</tt> exception.
+If the Java exception doesn't match either of these, a fallback <tt>std::runtime_error</tt> C++ exception is thrown.
+</p>
+
+<div class="code">
+<pre>
+%feature("director:except") MyClass::dirmethod(int x) {
+  jthrowable $error = jenv-&gt;ExceptionOccurred();
+  if ($error) {
+    if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
+      throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
+    if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
+      throw MyCppException(Swig::JavaExceptionMessage(jenv, $error).message());
+    throw std::runtime_error("Unexpected exception thrown in MyClass::dirmethod");
+  }
+}
+
+class MyClass {
+public:
+  /** Throws either a std::out_of_range or MyCppException on error */
+  virtual void dirmethod(int x);
+  virtual ~MyClass();
+};
+</pre>
+</div>
+
+<p>
+A few special variables are expanded within the <tt>director:except</tt> feature.
+</p>
+<ul>
+  <li> The special variable <tt>$error</tt> is expanded into a unique variable name (swigerror)
+  and should be used for the assignment of the jthrowable exception that occurred.</li>
+  <li> The special variable <tt>$packagepath</tt> is
+  replaced by the outer package provided for SWIG generation by the -package option. </li>
+  <li> The special variable <tt>$directorthrowshandlers</tt> is not shown above, but is replaced
+  by applicable "directorthrows" typemap contents (covered later in this section). </li>
+  <li> The special variable <tt>$null</tt> is not shown above, but is replaced
+  by a suitable default constructed object for returning from the director method (or nothing if
+  the director method has a void return).
+  </li>
+</ul>
+
+<p>
+Utility functions/classes in director.swg are provided to aid the exception conversion as follows:
+</p>
+
+<div class="code">
+<pre>
+namespace Swig {
+
+  // Helper method to determine if a Java throwable matches a particular Java class type
+  // Note side effect of clearing any pending exceptions
+  bool ExceptionMatches(JNIEnv *jenv, jthrowable throwable, const char *classname);
+
+  // Helper class to extract the exception message from a Java throwable
+  class JavaExceptionMessage {
+  public:
+    JavaExceptionMessage(JNIEnv *jenv, jthrowable throwable);
+
+    // Return a C string of the exception message in the jthrowable passed in the constructor
+    // If no message is available, null_string is return instead
+    const char *message(const char *null_string = 
+                        "Could not get exception message in JavaExceptionMessage") const;
+  };
+
+  // C++ Exception class for handling Java exceptions thrown during a director method Java upcall
+  class DirectorException : public std::exception {
+  public:
+
+    // Construct exception from a Java throwable
+    DirectorException(JNIEnv *jenv, jthrowable throwable);
+
+    // More general constructor for handling as a java.lang.RuntimeException
+    DirectorException(const char *msg);
+
+    // Return exception message extracted from the Java throwable
+    const char *what() const throw();
+
+    // Reconstruct and raise/throw the Java Exception that caused the DirectorException
+    // Note that any error in the JNI exception handling results in a Java RuntimeException
+    void throwException(JNIEnv *jenv) const;
+
+    // Create and throw the DirectorException
+    static void raise(JNIEnv *jenv, jthrowable throwable) {
+      throw DirectorException(jenv, throwable);
+    }
+  };
+
+}
+</pre>
+</div>
+
+<p>
+The utility function <code>Swig::ExceptionMatches</code>
 and class <code>Swig::JavaExceptionMessage</code> are provided to simplify
 writing code for wrappers that use the <code>director:except</code> feature. The
 function <code>Swig::ExceptionMatches</code> matches the type of the
@@ -3871,13 +4013,10 @@
 name, such as <code>"java/lang/IOError"</code>.  If the throwable class is the same
 type, or derives from the given type, <code>Swig::ExceptionMatches</code> will return true.  Care must be taken to
 provide the correct fully qualified name, since for wrapped exceptions the
-generated proxy class will have additional package qualification, depending on
+generated proxy class will have an additional package qualification, depending on
 the '-package' argument and use of the <a href="#Java_namespaces">nspace
-  feature</a>.  The special variable <code>$error</code> is expanded by SWIG into a unique variable name and
-should be used for the 
-assignment of the exception that occurred.  The special variable <code>$packagepath</code> is
-replaced by the outer package provided for SWIG generation by the -package
-option.  The utility class <code>Swig::JavaExceptionMessage</code> is a holder
+  feature</a>.  
+The utility class <code>Swig::JavaExceptionMessage</code> is a holder
 providing access to the message from the thrown Java exception.
 The <code>message()</code> method returns the exception message as a <code>const char *</code>,
 which is only valid during the lifetime of the holder.  Any code using this message
@@ -3885,20 +4024,27 @@
 </p>
 
 <p>
-Using the above approach to
+Using the first approach above to
 write handlers for a large number of methods will require 
-repetitive duplication of the <code>director:except</code> feature code.
-To mitigate this, an alternative approach is provided via typemaps in a
+repetitive duplication of the <code>director:except</code> feature code
+for each director method.
+To mitigate this, a second approach is provided via typemaps in a
 fashion analagous to
-the <a href="Typemaps.html#throws_typemap">"throws" typemap.</a>  The
-"throws" typemap provides an approach to automatically map all the C++
+the <a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
+The "throws" typemap provides a way to map all the C++
 exceptions listed in a method's defined exceptions (either from
 a C++ <em>exception specification</em> or a <code>%catches</code>
 feature) into Java exceptions.
 The "directorthrows" typemap provides the inverse mapping and should contain
 code to convert a suitably matching Java exception into a C++ exception.
+Only use this typemap if you wish to write custom conversions of Java exceptions into C++ exceptions
+and apply them to many different methods.
+The default handling which uses the <code>Swig::DirectorException</code> class should otherwise meet your needs.
+</p>
+
+<p>
 The example below converts a Java <code>java.lang.IndexOutOfBoundsException</code> exception
-to the typemap's type, that is <code>std::out_of_range</code>:
+to the typemap's type, that is a <code>std::out_of_range</code> C++ exception:
 
 <div class="code">
 <pre>
@@ -3913,7 +4059,7 @@
 <p>
 The "directorthrows" typemap is then used in conjunction with the
 <code>director:except</code> feature if the <code>$directorthrowshandlers</code> special variable
-is used in the feature code. Consider the following, which also happens to be the default:
+is used in the code block. Consider the following, which also happens to be the default:
 </p>
 
 <div class="code">
@@ -3921,7 +4067,6 @@
 %feature("director:except") %{
   jthrowable $error = jenv-&gt;ExceptionOccurred();
   if ($error) {
-    jenv-&gt;ExceptionClear();
     $directorthrowshandlers
     Swig::DirectorException::raise(jenv, $error);
   }
@@ -3930,34 +4075,33 @@
 </div>
 
 <p>
-where <tt>Swig::DirectorException::raise</tt> is a helper method in the DirectorException class to throw a C++ exception (implemented in director.swg):
-</p>
-
-<div class="code">
-<pre>
-  static void raise(JNIEnv *jenv, jthrowable throwable) {
-    throw DirectorException(jenv, throwable);
-  }
-</pre>
-</div>
-
-<p>The code generated using the <code>director:except</code> feature
-replaces the <code>$directorthrowshandlers</code> special variable with the code in
-the "directorthrows" typemaps, for each and every exception defined for the method. 
-The possible exceptions can be defined either with a C++ exception
+where <tt>Swig::DirectorException::raise</tt> is the helper method to throw a C++ <tt>Swig::DirectorException</tt>, see above.
+The code generated from the <code>director:except</code> feature
+has the <code>$directorthrowshandlers</code> special variable replaced with the code in
+the relevant "directorthrows" typemaps, for each and every exception defined for the method. 
+The relevant exceptions can be defined either with a C++ exception
 specification or <code>%catches</code> as described for the
 <a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
 </p>
 
 <p>
-Consider the following director method:
+Let's try and put all this together by considering the following director method:
 </p>
 
 <div class="code">
 <pre>
-  ...
+struct X {
   virtual void doSomething(int index) throw (std::out_of_range);
   ...
+};
+
+OR
+
+%catches(std::out_of_range) X::doSomething;
+struct X {
+  virtual void doSomething(int index);
+  ...
+};
 </pre>
 </div>
 
@@ -3970,11 +4114,9 @@
 <pre>
 jthrowable swigerror = jenv-&gt;ExceptionOccurred();
 if (swigerror) {
-  jenv-&gt;ExceptionClear();
   if (Swig::ExceptionMatches(jenv, swigerror, "java/lang/IndexOutOfBoundsException")) {
     throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
   }
-  
   Swig::DirectorException::raise(jenv, swigerror);
 }
 </pre>
@@ -3983,7 +4125,7 @@
 <p><em>
 Note: Beware of using exception specifications as the SWIG director methods
 will be generated with the same exception specifications and if the
-director method throws an exception that is not specified it is likely
+director method throws an exception that is not specified in the exception specifications list it is likely
 to terminate your program. See the C++ standard for more details.
 Using the %catches feature instead to define the handled exceptions does not suffer
 this potential fate.
@@ -3991,8 +4133,9 @@
 
 <p>Because the default code generation maps any unhandled Java exceptions to
 <code>Swig::DirectorException</code>, any director methods that have exception
-specifications may cause program termination.  To simply ignore
-unexpected exceptions, the default handling can be changed with:
+specifications may cause program termination as this exception class won't be in the exception specifications list.
+You can avoid throwing <tt>Swig::DirectorException</tt> by changing the default handling for all methods by adding a <tt>director:except</tt> feature without any method name.
+For example, you can just ignore them:
 </p>
 
 <div class="code">
@@ -4000,8 +4143,8 @@
 %feature("director:except") %{
   jthrowable $error = jenv-&gt;ExceptionOccurred();
   if ($error) {
-    jenv-&gt;ExceptionClear();
     $directorthrowshandlers
+    jenv-&gt;ExceptionClear();
     return $null; // exception is ignored
   }
 %}
@@ -4011,7 +4154,7 @@
 <p>Alternatively an exception compatible with the existing director
 method exception specifications can be thrown. Assuming that all
 methods allow std::runtime_error to be thrown,
-the <code>return&nbsp;$null;</code> could be changed to:
+the <code>return&nbsp;$null</code> line above could be changed to:
 </p>
 
 <div class="code">
@@ -4021,124 +4164,296 @@
 </div>
 
 <p>In more complex situations, a separate <code>director:except</code> feature
-may need to be attached to specific methods.
+may need to be attached to specific methods by providing a method name to the <tt>director:except</tt> feature.
 </p>
 
-<p>Below is a complete example demonstrating the use
-of the "directorthrows" typemaps.  In this example, a
-generic "directorthrows" typemap is appropriate for all three exceptions - all
-take single string constructors.  If the exceptions had different constructors,
-it would be necessary to have separate typemaps for each exception type.
+<p>This is all no doubt quite hard to follow without seeing a full example and some code.
+Below is a complete example demonstrating the use
+of most of the exception customizations one can use, that is,
+"directorthrows" and "throws" typemaps, %exception and %catches.
+See the <a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
+section for more on converting C++ exceptions to Java exceptions.
+The example also has a user defined C++ exception class called <tt>MyNS::MyException</tt> and this is wrapped as a Java exception.
+The director class being wrapped is <tt>MyClass</tt> and the director method is called <tt>MyClass::dirmethod</tt>.
+A number of <tt>std::cout</tt> calls have been added to help understand code flow.
+You can copy the code below into an interface file and run SWIG on it and examine the generated code.
 
 
-<!-- All the DEFINE_ and DECLARE_EXCEPTIONS CAN BE OMITTED to make
-  this more succinct.  They are included to make this a complete
-  example interface that could be generated and built.  -->
 <div class="code">
 <pre>
 %module(directors="1") example
 
 %{
-  #include &lt;string&gt;
   #include &lt;stdexcept&gt;
+  #include &lt;iostream&gt;
 %}
 
-// Define exceptions in header section using std::runtime_error
-%define DEFINE_EXCEPTION(NAME)
-%{
-  namespace MyNS {
-    struct NAME : public std::runtime_error { NAME(const std::string &amp;what) : runtime_error(what) {} };
+// Generic catch handler for all wrapped methods
+%exception %{
+  try {
+    $action
+  } catch (const std::exception &amp;e) {
+    std::cout &lt;&lt; "Generic std::exception catch handler" &lt;&lt; std::endl;
+    jclass clazz = jenv-&gt;FindClass("java/lang/RuntimeException");
+    jenv-&gt;ThrowNew(clazz, e.what()); 
+    return $null;
   }
 %}
-%enddef
 
-// Expose C++ exceptions as Java Exceptions by changing the Java base class and providing a getMessage()
-%define DECLARE_EXCEPTION(NAME)
-%typemap(javabase) MyNS::NAME "java.lang.Exception";
-%rename(getMessage) MyNS::NAME::what;
+// Expose C++ exception as a Java Exception by changing the Java base class and providing a getMessage()
+%typemap(javabase) MyNS::MyException "java.lang.RuntimeException";
+%rename(getMessage) MyNS::MyException::whatsup;
+
+%inline %{
 namespace MyNS {
-  struct NAME {
-    NAME(const std::string&amp; what);
-    const char * what();
+  class MyException {
+    std::string msg;
+  public:
+    MyException(const char *msg) : msg(msg) {}
+    const char * whatsup() const { return msg.c_str(); }
   };
 }
-%enddef
-
-DEFINE_EXCEPTION(ExceptionA)
-DEFINE_EXCEPTION(ExceptionB)
-DEFINE_EXCEPTION(Unexpected)
-
-// Mark three methods to map director thrown exceptions.
-%feature("director:except") MyClass::meth1(int);
-%feature("director:except") MyClass::meth2;
-%feature("director:except") meth3;
-
-%typemap(directorthrows) MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected %{
-  if (Swig::ExceptionMatches(jenv, $error, "$packagepath/$javaclassname"))
-    throw $1_type(Swig::JavaExceptionMessage(jenv, $error).message());
 %}
 
-DECLARE_EXCEPTION(ExceptionA)
-DECLARE_EXCEPTION(ExceptionB)
-DECLARE_EXCEPTION(Unexpected)
+%typemap(directorthrows) MyNS::MyException %{
+  if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyException")) {
+    std::cout &lt;&lt; "$1_type exception matched (directorthrows typemap)" &lt;&lt; std::endl;
+    throw $1_type(Swig::JavaExceptionMessage(jenv, $error).message());
+  }
+%}
 
-%catches(MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected) MyClass::meth2();
+%typemap(throws) MyNS::MyException %{
+  std::cout &lt;&lt; "$1_type caught (throws typemap)" &lt;&lt; std::endl;
+  jclass excep = jenv-&gt;FindClass("MyException");
+  if (excep) {
+    std::cout &lt;&lt; "$1_type class found (throws typemap)" &lt;&lt; std::endl;
+    jenv-&gt;ThrowNew(excep, $1.whatsup());
+  }
+  return $null;
+%}
 
-%inline {
-  class MyClass {
-  public:
-    virtual void meth1(int x) throw(MyNS::ExceptionA, MyNS::ExceptionB) = 0;
-    virtual void meth2() = 0;   /* throws MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected */
-    virtual void meth3(float x) throw(MyNS::Unexpected) = 0;
-    virtual ~MyClass() {}
-  };
+// These are the exceptions that the director method MyClass::dirmethod will have catch handlers for.
+// Note that this is also a virtual method / director method and the C++ exceptions listed can be
+// thrown after converting them from Java exceptions.
+%catches(MyNS::MyException, Swig::DirectorException) MyClass::dirmethod;
+
+// These are the exceptions that call_dirmethod C++ wrapper will have catch handlers for.
+// Note that this is not a virtual method, hence not a director method.
+%catches(MyNS::MyException, Swig::DirectorException) call_dirmethod;
+
+%feature("director") MyClass;
+
+%feature("director:except") MyClass::dirmethod(int x) {
+  jthrowable $error = jenv-&gt;ExceptionOccurred();
+  if ($error) {
+    std::cout &lt;&lt; "Upcall finished, an exception was thrown in Java" &lt;&lt; std::endl;
+    $directorthrowshandlers
+    std::cout &lt;&lt; "Upcall finished, no exception conversion, throwing DirectorException" &lt;&lt; std::endl;
+    Swig::DirectorException::raise(jenv, $error);
+  }
 }
+
+%inline %{
+class MyClass {
+public:
+  /** Throws either a std::out_of_range or MyException on error */
+  virtual void dirmethod(int x) {
+    if (x &lt;= 0)
+      throw std::out_of_range("MyClass::dirmethod index is out of range");
+    else if (x == 1)
+      throw MyNS::MyException("MyClass::dirmethod some problem!");
+  }
+  virtual ~MyClass() {}
+  static void call_dirmethod(MyClass&amp; c, int x) {
+    return c.dirmethod(x);
+  }
+};
+%}
 </pre>
 </div>
 
 <p>
-In this case the three different "directorthrows" typemaps will be used
-to generate the three different exception handlers for
-<code>meth1</code>, <code>meth2</code> and <code>meth3</code>.  The generated
-handlers will have "if" blocks for each exception type specified, in
-the exception specification or <code>%catches</code> feature. 
-</p>
-
-<p>Note that the "directorthrows" typemaps are important
-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,
-the default <code>Swig::DirectorException</code> class provides enough information
-to reconstruct the original exception.  In this case removing the
-<code>$directorthrowshandlers</code> special variable from the
-default <code>director:except</code> feature and simply always
-throwing a <code>Swig::DirectorException</code> will achieve the desired result.
-Along with this a generic exception feature is added to convert any
-caught <code>Swig::DirectorException</code>s back into the underlying
-Java exceptions via the <code>Swig::DirectorException::raiseJavaException</code> method,
-as demonstrated with <code>%javaexception</code> below:
+The generated code for the <tt>call_dirmethod</tt> wrapper contains the various exception handlers.
+The outer exception handler is from the <tt>%exception</tt> directive and the others
+are from the "throws" typemaps.
 </p>
 
 <div class="code">
 <pre>
-%javaexception("Exception") MyClass::myMethod %{
+SWIGEXPORT void JNICALL Java_exampleJNI_MyClass_1call_1dirmethod(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) {
+  ...
   try {
-    $action
-  } catch (Swig::DirectorException &amp;e) {
-    // raise/throw the Java exception that originally caused the DirectorException
-    e.raiseJavaException(jenv);
-    return $null;
+    try {
+      MyClass::call_dirmethod(*arg1,arg2);
+    } catch(MyNS::MyException &amp;_e) {
+      std::cout &lt;&lt; "MyNS::MyException caught (throws typemap)" &lt;&lt; std::endl;
+      jclass excep = jenv-&gt;FindClass("MyException");
+      if (excep) {
+        std::cout &lt;&lt; "MyNS::MyException class found (throws typemap)" &lt;&lt; std::endl;
+        jenv-&gt;ThrowNew(excep, (&amp;_e)-&gt;whatsup());
+      }
+      return ;
+      
+    } catch(Swig::DirectorException &amp;_e) {
+      (&amp;_e)-&gt;throwException(jenv);
+      return ; 
+    }
+  } catch (const std::exception &amp;e) {
+    std::cout &lt;&lt; "Generic std::exception catch handler" &lt;&lt; std::endl;
+    jclass clazz = jenv-&gt;FindClass("java/lang/RuntimeException");
+    jenv-&gt;ThrowNew(clazz, e.what()); 
+    return ;
   }
-%}
 </pre>
 </div>
 
 <p>
-See the <a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
-section for more on converting C++ exceptions to Java exceptions.
+The director method calling up to Java contains the exception handling code from the "directorthrows" typemaps and <tt>director:except</tt> feature.
 </p>
 
+<div class="code">
+<pre>
+void SwigDirector_MyClass::dirmethod(int x) {
+      ... [call up to Java using CallStaticVoidMethod]
+      jthrowable swigerror = jenv-&gt;ExceptionOccurred();
+      if (swigerror) {
+        std::cout &lt;&lt; "Upcall finished, an exception was thrown in Java" &lt;&lt; std::endl;
+        
+        if (Swig::ExceptionMatches(jenv, swigerror, "MyException")) {
+          std::cout &lt;&lt; "MyNS::MyException exception matched (directorthrows typemap)" &lt;&lt; std::endl;
+          throw MyNS::MyException(Swig::JavaExceptionMessage(jenv, swigerror).message());
+        }
+        
+        std::cout &lt;&lt; "Upcall finished, no exception conversion, throwing DirectorException" &lt;&lt; std::endl;
+        Swig::DirectorException::raise(jenv, swigerror);
+      }
+</pre>
+</div>
+
+<p>
+Let's use the following Java class to override the director method.
+</p>
+
+<div class="code">
+<pre>
+class DerivedClass extends MyClass {
+  @Override
+  public void dirmethod(int x) {
+    if (x &lt; 0)
+      throw new IndexOutOfBoundsException("Index is negative");
+    else if (x == 0)
+      throw new MyException("MyException: bad dirmethod");
+  }
+}
+public class runme {
+  public static void main(String argv[]) {
+    System.loadLibrary("example");
+    ... code snippets shown below ...
+  }
+}
+</pre>
+</div>
+
+<p>
+Consider the output using the Java code in the four slightly different scenarios below.
+</p>
+
+<p>
+1. Non-director C++ class is used, thus, no upcall to a Java director method is made.
+A <tt>std::out_of_range</tt> exception is thrown, which is derived from <tt>std::exception</tt>,
+and hence caught by the generic exception handler in the <tt>call_dirmethod</tt> wrapper.
+The Java code snippet and resulting output is:
+</p>
+
+
+<div class="code">
+<pre>
+MyClass.call_dirmethod(new MyClass(), 0);
+</pre>
+</div>
+
+<div class="shell">
+<pre>
+Generic std::exception catch handler
+Exception in thread "main" java.lang.RuntimeException: MyClass::dirmethod index is out of range
+        at exampleJNI.MyClass_call_dirmethod(Native Method)
+        at MyClass.call_dirmethod(MyClass.java:57)
+        at runme.main(runme.java:14)
+</pre>
+</div>
+
+<p>
+2. Non-director C++ class again but this time the <tt>MyNS::MyException</tt> class is thrown and caught:
+</p>
+
+<div class="code">
+<pre>
+MyClass.call_dirmethod(new MyClass(), 1);
+</pre>
+</div>
+
+<div class="shell">
+<pre>
+MyNS::MyException caught (throws typemap)
+MyNS::MyException class found (throws typemap)
+Exception in thread "main" MyException: MyClass::dirmethod some problem!
+        at exampleJNI.MyClass_call_dirmethod(Native Method)
+        at MyClass.call_dirmethod(MyClass.java:57)
+        at runme.main(runme.java:15)
+</pre>
+</div>
+
+<p>
+3. The <tt>DerivedClass</tt> director class is used so the upcall to Java occurs, but it throws
+a Java <tt>MyException</tt>, which gets converted into a C++ <tt>MyNS::MyException</tt>, then caught and converted back
+into a Java <tt>MyException</tt>:
+</p>
+
+<div class="code">
+<pre>
+MyClass.call_dirmethod(new DerivedClass(), 0);
+</pre>
+</div>
+
+<div class="shell">
+<pre>
+Upcall finished, an exception was thrown in Java
+MyNS::MyException exception matched (directorthrows typemap)
+MyNS::MyException caught (throws typemap)
+MyNS::MyException class found (throws typemap)
+Exception in thread "main" MyException: MyException: bad dirmethod
+        at exampleJNI.MyClass_call_dirmethod(Native Method)
+        at MyClass.call_dirmethod(MyClass.java:57)
+        at runme.main(runme.java:16)
+</pre>
+</div>
+
+<p>
+4. The director class is used again, but this time the director method throws a Java <tt>IndexOutOfBoundsException</tt> exception which is converted into a C++ <tt>Swig::DirectorException</tt>, thrown and caught again.
+This time the original Java exception is extracted from the <tt>Swig::DirectorException</tt> and rethrown.
+Note that this approach keeps the stack trace information of the original exception, so it has the exact location of where the <tt>IndexOutOfBoundsException</tt> exception was thrown.
+This is arguably an improvement over the approach above that converts from a Java excepton to C++ exception and then back to a new Java exception, losing the location of the original exception.
+</p>
+
+<div class="code">
+<pre>
+MyClass.call_dirmethod(new DerivedClass(), -1);
+</pre>
+</div>
+
+<div class="shell">
+<pre>
+Upcall finished, an exception was thrown in Java
+Upcall finished, no exception conversion, throwing DirectorException
+Exception in thread "main" java.lang.IndexOutOfBoundsException: Index is negative
+        at DerivedClass.dirmethod(runme.java:5)
+        at exampleJNI.SwigDirector_MyClass_dirmethod(exampleJNI.java:23)
+        at exampleJNI.MyClass_call_dirmethod(Native Method)
+        at MyClass.call_dirmethod(MyClass.java:57)
+        at runme.main(runme.java:17)
+</pre>
+</div>
+
 <H2><a name="Java_allprotected">25.6 Accessing protected members</a></H2>
 
 
diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html
index 0c0023d..27ce084 100644
--- a/Doc/Manual/Python.html
+++ b/Doc/Manual/Python.html
@@ -6521,14 +6521,16 @@
 <div class="code"><pre>
 %module example
 
-%include &lt;std_string.i&gt;
-
 %inline %{
 
-const char* non_utf8_c_str(void) {
+const char * non_utf8_c_str(void) {
   return "h\xe9llo w\xc3\xb6rld";
 }
 
+void instring(const char *s) {
+  ...
+}
+
 %}
 </pre></div>
 
@@ -6591,6 +6593,20 @@
 </p>
 
 <p>
+When Python 3 strings are passed to the C/C++ layer, they are expected to be valid UTF8 Unicode strings too.
+For example, when the <tt>instring</tt> method above is wrapped and called, any invalid UTF8 Unicode code strings
+will result in a TypeError because the attempted conversion fails:
+</p>
+
+<div class="targetlang"><pre>
+&gt;&gt;&gt; example.instring('h\xe9llo')
+&gt;&gt;&gt; example.instring('h\udce9llo')
+Traceback (most recent call last):
+  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
+TypeError: in method 'instring', argument 1 of type 'char const *'
+</pre></div>
+
+<p>
 In some cases, users may wish to instead handle all byte strings as bytes
 objects in Python 3. This can be accomplished by adding
 <tt>SWIG_PYTHON_STRICT_BYTE_CHAR</tt> to the generated code:
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index 144a24d..5eac552 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -4630,7 +4630,7 @@
 Exceptions are automatically handled for methods with an exception specification.
 Similar handling can be achieved for methods without exception specifications through the <tt>%catches</tt> feature.
 It is also possible to replace any declared exception specification using the <tt>%catches</tt> feature.
-In fact, <tt>%catches</tt> uses the same <a href="Typemaps.html#throws_typemap">"throws" typemaps</a> that SWIG uses for exception specifications in handling exceptions.
+In fact, <tt>%catches</tt> uses the same <a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemaps</a> that SWIG uses for exception specifications in handling exceptions.
 The <tt>%catches</tt> feature must contain a list of possible types that can be thrown.
 For each type that is in the list, SWIG will generate a catch handler, in the same way that it would for types declared in the exception specification.
 Note that the list can also include the catch all specification "...".
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
index ee807d1..d0d8d79 100644
--- a/Doc/Manual/Typemaps.html
+++ b/Doc/Manual/Typemaps.html
@@ -67,7 +67,7 @@
 <li><a href="#Typemaps_nn35">"memberin" typemap</a>
 <li><a href="#Typemaps_nn36">"varin" typemap</a>
 <li><a href="#Typemaps_nn37">"varout" typemap</a>
-<li><a href="#throws_typemap">"throws" typemap</a>
+<li><a href="#Typemaps_throws_typemap">"throws" typemap</a>
 </ul>
 <li><a href="#Typemaps_nn39">Some typemap examples</a>
 <ul>
@@ -2884,11 +2884,11 @@
 language when reading a C/C++ global variable.  This is implementation specific.
 </p>
 
-<H3><a name="throws_typemap">11.5.14 "throws" typemap</a></H3>
+<H3><a name="Typemaps_throws_typemap">11.5.14 "throws" typemap</a></H3>
 
 
 <p>
-The "throws" typemap is only used when SWIG parses a C++ method with an exception specification or has the <tt>%catches</tt> feature attached to the method.
+The "throws" typemap is only used when SWIG parses a C++ method with an exception specification or has the <tt>%catches</tt> feature attached to the method (see <a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>).
 It provides a default mechanism for handling C++ methods that have declared the exceptions they will throw.
 The purpose of this typemap is to convert a C++ exception into an error or exception in the target language.
 It is slightly different to the other typemaps as it is based around the exception type rather than the type of a parameter or variable.
@@ -2901,13 +2901,19 @@
   PyErr_SetString(PyExc_RuntimeError, $1);
   SWIG_fail;
 %}
-void bar() throw (const char *);
+
+// Either an exception specification on the method
+  void bar() throw (const char *);
+
+// Or a %catches feature attached to the method
+  %catches(const char *) bar();
+  void bar();
 </pre>
 </div>
 
 <p>
-As can be seen from the generated code below, SWIG generates an exception handler
-with the catch block comprising the "throws" typemap content.
+As can be seen from the resulting generated code below, SWIG generates an exception handler
+when wrapping the <tt>bar</tt> function with the catch block comprising the "throws" typemap content.
 </p>
 
 <div class="code">
@@ -2915,8 +2921,7 @@
 ...
 try {
   bar();
-}
-catch(char const *_e) {
+} catch(char const *_e) {
   PyErr_SetString(PyExc_RuntimeError, _e);
   SWIG_fail;
 }
@@ -2925,8 +2930,8 @@
 </div>
 
 <p>
-Note that if your methods do not have an exception specification yet they do throw exceptions, SWIG cannot know how to deal with them.
-For a neat way to handle these, see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section.
+Note that if your methods do not have an exception specification but they do throw exceptions and you are not using <tt>%catches</tt>, SWIG cannot know how to deal with them.
+Please also see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section for another way to handle exceptions.
 </p>
 
 <H2><a name="Typemaps_nn39">11.6 Some typemap examples</a></H2>
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index eba8163..014a38c 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -529,8 +529,11 @@
       SWIG_fail;
     }
     pystr = PyUnicode_AsUTF8String(pyobj);
+    if (!pystr) {
+      SWIG_fail;
+    }
     str = strdup(PyBytes_AsString(pystr));
-    Py_XDECREF(pystr);
+    Py_DECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
       PyErr_SetString(PyExc_ValueError, "Expected a string");
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index e020a65..81697c8 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -334,8 +334,8 @@
   SWIGOPTPY3 = -py3
 endif
 
-PEP8         = @PEP8@
-PEP8_FLAGS   = --ignore=E402,E501,E30,W291,W391
+PYCODESTYLE       = @PYCODESTYLE@
+PYCODESTYLE_FLAGS = --ignore=E402,E501,E30,W291,W391
 
 # ----------------------------------------------------------------
 # Build a C dynamically loadable module
@@ -389,8 +389,8 @@
 PY2TO3 = @PY2TO3@ `@PY2TO3@ -l | grep -v -E "Available|import$$" | awk '{print "-f "$$0}'`
 
 python_run: $(PYSCRIPT)
-ifneq (,$(PEP8))
-	$(COMPILETOOL) $(PEP8) $(PEP8_FLAGS) $(PYSCRIPT)
+ifneq (,$(PYCODESTYLE))
+	$(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
 endif
 	env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
 
diff --git a/Examples/python/import_packages/Makefile b/Examples/python/import_packages/Makefile
index f428d6f..2857866 100644
--- a/Examples/python/import_packages/Makefile
+++ b/Examples/python/import_packages/Makefile
@@ -12,7 +12,7 @@
 	relativeimport2 \
 	relativeimport3 \
 	split_modules \
-	namespace_pkg
+	namespace_pkg \
 
 
 check: build
@@ -21,19 +21,19 @@
 			mkdir -p `dirname $$file`; \
 			cp "${SRCDIR}$$file" "$$file" || exit 1; \
 		done; \
-	fi; \
+	fi
 	for s in $(import_packages_subdirs); do \
-		(cd $$s && $(MAKE) check); \
+		(cd $$s && $(MAKE) check) || exit 1; \
 	done
 
 build:
 	for s in $(import_packages_subdirs); do \
-		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
+		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build) || exit 1; \
 	done
 
 static:
 	for s in $(import_packages_subdirs); do \
-		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
+		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static) || exit 1; \
 	done
 
 clean:
@@ -42,7 +42,7 @@
 		for file in `cd $(SRCDIR) && find . -type f -name "*.py"`; do \
 			rm -f "$$file" || exit 1; \
 		done; \
-	fi; \
+	fi
 	for s in $(import_packages_subdirs); do \
-		(cd $$s && $(MAKE) clean); \
+		(cd $$s && $(MAKE) clean) || exit 1; \
 	done
diff --git a/Examples/python/import_packages/from_init1/runme.py b/Examples/python/import_packages/from_init1/runme.py
index dda3974..424e9ca 100644
--- a/Examples/python/import_packages/from_init1/runme.py
+++ b/Examples/python/import_packages/from_init1/runme.py
@@ -5,6 +5,10 @@
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
 print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
 
+if sys.version_info < (2, 5):
+    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    sys.exit(0)
+
 if sys.version_info < (3, 0):
     import py2.pkg2
     print "  Finished importing py2.pkg2"
diff --git a/Examples/python/import_packages/from_init2/runme.py b/Examples/python/import_packages/from_init2/runme.py
index dda3974..424e9ca 100644
--- a/Examples/python/import_packages/from_init2/runme.py
+++ b/Examples/python/import_packages/from_init2/runme.py
@@ -5,6 +5,10 @@
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
 print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
 
+if sys.version_info < (2, 5):
+    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    sys.exit(0)
+
 if sys.version_info < (3, 0):
     import py2.pkg2
     print "  Finished importing py2.pkg2"
diff --git a/Examples/python/import_packages/from_init3/runme.py b/Examples/python/import_packages/from_init3/runme.py
index dda3974..424e9ca 100644
--- a/Examples/python/import_packages/from_init3/runme.py
+++ b/Examples/python/import_packages/from_init3/runme.py
@@ -5,6 +5,10 @@
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
 print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
 
+if sys.version_info < (2, 5):
+    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    sys.exit(0)
+
 if sys.version_info < (3, 0):
     import py2.pkg2
     print "  Finished importing py2.pkg2"
diff --git a/Examples/python/import_packages/relativeimport1/runme.py b/Examples/python/import_packages/relativeimport1/runme.py
index 997476b..5b1b5f4 100644
--- a/Examples/python/import_packages/relativeimport1/runme.py
+++ b/Examples/python/import_packages/relativeimport1/runme.py
@@ -5,6 +5,10 @@
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
 print "Testing " + testname + " - %module(package=...) with -relativeimport"
 
+if sys.version_info < (2, 5):
+    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    sys.exit(0)
+
 if sys.version_info < (3, 0):
     import py2.pkg2.bar
     print "  Finished importing py2.pkg2.bar"
diff --git a/Examples/python/import_packages/relativeimport2/runme.py b/Examples/python/import_packages/relativeimport2/runme.py
index 9789afc..9d1a05e 100644
--- a/Examples/python/import_packages/relativeimport2/runme.py
+++ b/Examples/python/import_packages/relativeimport2/runme.py
@@ -5,6 +5,10 @@
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
 print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
 
+if sys.version_info < (2, 5):
+    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    sys.exit(0)
+
 if sys.version_info < (3, 0):
     import py2.pkg2.bar
     print "  Finished importing py2.pkg2.bar"
diff --git a/Examples/python/import_packages/relativeimport3/runme.py b/Examples/python/import_packages/relativeimport3/runme.py
index 997476b..5b1b5f4 100644
--- a/Examples/python/import_packages/relativeimport3/runme.py
+++ b/Examples/python/import_packages/relativeimport3/runme.py
@@ -5,6 +5,10 @@
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
 print "Testing " + testname + " - %module(package=...) with -relativeimport"
 
+if sys.version_info < (2, 5):
+    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    sys.exit(0)
+
 if sys.version_info < (3, 0):
     import py2.pkg2.bar
     print "  Finished importing py2.pkg2.bar"
diff --git a/Examples/python/import_packages/split_modules/Makefile b/Examples/python/import_packages/split_modules/Makefile
index 65d635b..9eaaabd 100644
--- a/Examples/python/import_packages/split_modules/Makefile
+++ b/Examples/python/import_packages/split_modules/Makefile
@@ -6,21 +6,21 @@
 
 check: build
 	for s in $(subdirs); do \
-		(cd $$s && $(MAKE) check); \
+		(cd $$s && $(MAKE) check) || exit 1; \
 	done
 
 build:
 	for s in $(subdirs); do \
-		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
+		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build) || exit 1; \
 	done
 
 static:
 	for s in $(subdirs); do \
-		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
+		(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static) || exit 1; \
 	done
 
 clean:
 	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
 	for s in $(subdirs); do \
-		(cd $$s && $(MAKE) clean); \
+		(cd $$s && $(MAKE) clean) || exit 1; \
 	done
diff --git a/Examples/python/import_packages/split_modules/vanilla_split/Makefile b/Examples/python/import_packages/split_modules/vanilla_split/Makefile
index c322b5a..5d1c352 100644
--- a/Examples/python/import_packages/split_modules/vanilla_split/Makefile
+++ b/Examples/python/import_packages/split_modules/vanilla_split/Makefile
@@ -19,4 +19,6 @@
 
 clean:
 	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
-	cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
+	if test -d pkg1; then \
+		cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean; \
+	fi
diff --git a/Examples/python/multimap/example.i b/Examples/python/multimap/example.i
index 66c0f74..3ff5d52 100644
--- a/Examples/python/multimap/example.i
+++ b/Examples/python/multimap/example.i
@@ -39,7 +39,11 @@
 %#if PY_VERSION_HEX >= 0x03000000
     {
       PyObject *utf8str = PyUnicode_AsUTF8String(s);
-      const char *cstr = PyBytes_AsString(utf8str);
+      const char *cstr;
+      if (!utf8str) {
+        SWIG_fail;
+      }
+      cstr = PyBytes_AsString(utf8str);
       $2[i] = strdup(cstr);
       Py_DECREF(utf8str);
     }
@@ -72,6 +76,9 @@
     SWIG_fail;
   }
   utf8str = PyUnicode_AsUTF8String($input);
+  if (!utf8str) {
+    SWIG_fail;
+  }
   PyBytes_AsStringAndSize(utf8str, &cstr, &len);
   $1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
   $2 = (int)len;
@@ -105,6 +112,9 @@
   char *cstr;
   Py_ssize_t len;
   PyObject *utf8str = PyUnicode_AsUTF8String($input);
+  if (!utf8str) {
+    SWIG_fail;
+  }
   PyBytes_AsStringAndSize(utf8str, &cstr, &len);
   $1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
   $2 = (int)len;
diff --git a/Examples/python/variables/runme.py b/Examples/python/variables/runme.py
index 3388a0e..fba485a 100644
--- a/Examples/python/variables/runme.py
+++ b/Examples/python/variables/runme.py
@@ -52,14 +52,14 @@
 try:
     example.cvar.path = "Whoa!"
     print "Hey, what's going on?!?! This shouldn't work"
-except:
+except Exception:
     print "Good."
 
 print "     Trying to set 'status'"
 try:
     example.cvar.status = 0
     print "Hey, what's going on?!?! This shouldn't work"
-except:
+except Exception:
     print "Good."
 
 
diff --git a/Examples/ruby/free_function/runme.rb b/Examples/ruby/free_function/runme.rb
index a517ed4..cf405d4 100644
--- a/Examples/ruby/free_function/runme.rb
+++ b/Examples/ruby/free_function/runme.rb
@@ -39,7 +39,11 @@
 # C++ object
 ok = false
 begin
-  puts tiger2.get_name
+  # Let's stress the GC a bit, a single pass might not be enough.
+  10.times {
+    GC.start
+    puts tiger2.get_name
+  }
 rescue ObjectPreviouslyDeleted => error
   ok = true
 end
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 8d6f94f..3bcf67c 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -164,6 +164,7 @@
 	cpp_typedef \
 	curiously_recurring_template_pattern \
 	default_args \
+	default_arg_expressions \
 	default_arg_values \
 	default_constructor \
 	defvalue_constructor \
@@ -181,6 +182,7 @@
 	director_detect \
 	director_enum \
 	director_exception \
+	director_exception_catches \
 	director_extend \
 	director_finalizer \
 	director_frob \
@@ -489,6 +491,7 @@
 	throw_exception \
 	typedef_array_member \
 	typedef_class \
+	typedef_classforward_same_name \
 	typedef_funcptr \
 	typedef_inherit \
 	typedef_mptr \
@@ -675,6 +678,7 @@
 	string_simple \
 	struct_rename \
 	struct_initialization \
+	typedef_classforward_same_name \
 	typedef_struct \
 	typemap_subst \
 	union_parameter \
diff --git a/Examples/test-suite/default_arg_expressions.i b/Examples/test-suite/default_arg_expressions.i
new file mode 100644
index 0000000..ca2a27e
--- /dev/null
+++ b/Examples/test-suite/default_arg_expressions.i
@@ -0,0 +1,30 @@
+%module default_arg_expressions
+
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ptr;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) UsdGeomTokensPtr;
+%immutable UsdGeomTokens;
+
+%inline %{
+struct Numbers {
+  int val;
+  int *ptr;
+  Numbers() : val(), ptr(&val) {}
+};
+struct TfToken {
+  Numbers val;
+  Numbers *ptr;
+  TfToken() : val(), ptr(&val) {}
+};
+struct Tokens {
+  const TfToken face;
+  const TfToken *pface;
+  Tokens() : face(), pface(&face) {}
+};
+static Tokens UsdGeomTokens;
+static Tokens *UsdGeomTokensPtr = &UsdGeomTokens;
+void CreateMaterialBindSubset1(const Tokens &elementType = UsdGeomTokens) {}
+void CreateMaterialBindSubset2(int num = UsdGeomTokensPtr->pface->val.val) {}
+void CreateMaterialBindSubset3(int num = UsdGeomTokensPtr->pface->ptr->val) {}
+void CreateMaterialBindSubset4(int num = UsdGeomTokensPtr->face.val.val) {}
+//void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
+%}
diff --git a/Examples/test-suite/director_exception.i b/Examples/test-suite/director_exception.i
index 1ce14de..e25bfdc 100644
--- a/Examples/test-suite/director_exception.i
+++ b/Examples/test-suite/director_exception.i
@@ -20,14 +20,10 @@
 
 #ifndef SWIG_DIRECTORS
 namespace Swig {
-class DirectorException {};
-class DirectorMethodException: public Swig::DirectorException {};
+  class DirectorException {};
+  class DirectorMethodException: public Swig::DirectorException {};
 }
-  #ifndef SWIG_fail
-    #define SWIG_fail
-  #endif
 #endif /* !SWIG_DIRECTORS */
-
 %}
 
 %include "std_string.i"
@@ -41,8 +37,8 @@
 }
 
 %exception {
-	try { $action }
-	catch (Swig::DirectorException &) { SWIG_fail; }
+  try { $action }
+  catch (Swig::DirectorException &) { SWIG_fail; }
 }
 
 #endif
@@ -56,8 +52,8 @@
 }
 
 %exception {
-	try { $action }
-	catch (Swig::DirectorException &) { SWIG_fail; }
+  try { $action }
+  catch (Swig::DirectorException &) { SWIG_fail; }
 }
 
 #endif
@@ -75,12 +71,12 @@
 // Change back to old 2.0 default behavior
 
 %feature("director:except") {
-	jthrowable $error = jenv->ExceptionOccurred();
-	if ($error) {
-	  // Dont clear exception, still be active when return to java execution
-	  // Essentially ignore exception occurred -- old behavior.
-	  return $null;
-	}
+  jthrowable $error = jenv->ExceptionOccurred();
+  if ($error) {
+    // Dont clear exception, still be active when return to java execution
+    // Essentially ignore exception occurred -- old behavior.
+    return $null;
+  }
 }
 
 #endif
diff --git a/Examples/test-suite/director_exception_catches.i b/Examples/test-suite/director_exception_catches.i
new file mode 100644
index 0000000..ad18366
--- /dev/null
+++ b/Examples/test-suite/director_exception_catches.i
@@ -0,0 +1,25 @@
+%module(directors="1") director_exception_catches
+
+%include <std_string.i>
+%feature("director") BaseClass;
+
+%{
+// define dummy director exception classes to prevent spurious errors 
+// in target languages that do not support directors.
+
+#ifndef SWIG_DIRECTORS
+namespace Swig {
+  class DirectorException {};
+}
+#endif /* !SWIG_DIRECTORS */
+%}
+
+%catches(Swig::DirectorException) BaseClass::call_description;
+
+%inline %{
+struct BaseClass {
+  virtual std::string description() const = 0;
+  static std::string call_description(BaseClass& bc) { return bc.description(); }
+  virtual ~BaseClass() {}
+};
+%}
diff --git a/Examples/test-suite/java/director_exception_catches_runme.java b/Examples/test-suite/java/director_exception_catches_runme.java
new file mode 100644
index 0000000..c6fed19
--- /dev/null
+++ b/Examples/test-suite/java/director_exception_catches_runme.java
@@ -0,0 +1,35 @@
+
+import director_exception_catches.*;
+
+public class director_exception_catches_runme {
+
+  static {
+    try {
+      System.loadLibrary("director_exception_catches");
+    } 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[]) {
+
+    BaseClass b = new director_exception_catches_MyClass();
+
+    try {
+      String s = BaseClass.call_description(b);
+      throw new RuntimeException("Failed to catch exception");
+    } catch (NullPointerException e) {
+      if (!e.getMessage().startsWith("Testing exception thrown in BaseClass.description"))
+        throw new RuntimeException("Unexpected exception message: " + e.getMessage());
+    }
+  }
+}
+
+class director_exception_catches_MyClass extends BaseClass {
+  @Override
+  public String description() {
+    throw new NullPointerException("Testing exception thrown in BaseClass.description");
+  }
+}
+
diff --git a/Examples/test-suite/java/java_director_exception_feature_nspace_runme.java b/Examples/test-suite/java/java_director_exception_feature_nspace_runme.java
index ea7da5c..884b04c 100644
--- a/Examples/test-suite/java/java_director_exception_feature_nspace_runme.java
+++ b/Examples/test-suite/java/java_director_exception_feature_nspace_runme.java
@@ -126,19 +126,28 @@
 	  try {  b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
           catch (MyJavaException1 e) {
               failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP1.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              StackTraceElement[] st = e.getStackTrace();
+              failif( st.length != 5, "Stack length is only " + st.length);
+              failif( ! st[0].toString().startsWith("java_director_exception_feature_nspace_MyFooDirectorImpl.genericpong(java_director_exception_feature_nspace_runme.java:"), "Incorrect top of stack: " + st[0]);
           }
 	  try {  b.genericpong(2); fail("No exception thrown in genericpong(2)");}
           catch (java_director_exception_feature_nspace_NewCheckedException e) {
               failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP2.equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              StackTraceElement[] st = e.getStackTrace();
+              failif( st.length != 5, "Stack length is only " + st.length);
+              failif( ! st[0].toString().startsWith("java_director_exception_feature_nspace_MyFooDirectorImpl.genericpong(java_director_exception_feature_nspace_runme.java:"), "Incorrect top of stack: " + st[0]);
           }
 	  try {  b.genericpong(3); fail("No exception thrown in genericpong(3)");}
           catch (java_director_exception_feature_nspace_NewUncheckedException e) {
               failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP3.equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              StackTraceElement[] st = e.getStackTrace();
+              failif( st.length != 5, "Stack length is only " + st.length);
+              failif( ! st[0].toString().startsWith("java_director_exception_feature_nspace_MyFooDirectorImpl.genericpong(java_director_exception_feature_nspace_runme.java:"), "Incorrect top of stack: " + st[0]);
           }
 	  try {  b.genericpong(4); fail("No exception thrown in genericpong(4)");}
           catch (RuntimeException e) {
-              failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RumtimeException");
-              failif( ! java_director_exception_feature_nspace_Consts.GENERICPONGEXCP4.equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RuntimeException");
+              failif( ! "Unspecified DirectorException message".equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
           }
       }
       catch (Exception e) {
diff --git a/Examples/test-suite/java/java_director_exception_feature_runme.java b/Examples/test-suite/java/java_director_exception_feature_runme.java
index 2e919c1..d9763c9 100644
--- a/Examples/test-suite/java/java_director_exception_feature_runme.java
+++ b/Examples/test-suite/java/java_director_exception_feature_runme.java
@@ -127,19 +127,28 @@
 	  try {  b.genericpong(1); fail("No exception thrown in genericpong(1)"); }
           catch (MyJavaException1 e) {
               failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP1.equals(e.getMessage()), "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              StackTraceElement[] st = e.getStackTrace();
+              failif( st.length != 5, "Stack length is only " + st.length);
+              failif( ! st[0].toString().startsWith("java_director_exception_feature_MyFooDirectorImpl.genericpong(java_director_exception_feature_runme.java:"), "Incorrect top of stack: " + st[0]);
           }
 	  try {  b.genericpong(2); fail("No exception thrown in genericpong(2)");}
           catch (NewCheckedException e) {
               failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP2.equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              StackTraceElement[] st = e.getStackTrace();
+              failif( st.length != 5, "Stack length is only " + st.length);
+              failif( ! st[0].toString().startsWith("java_director_exception_feature_MyFooDirectorImpl.genericpong(java_director_exception_feature_runme.java:"), "Incorrect top of stack: " + st[0]);
           }
 	  try {  b.genericpong(3); fail("No exception thrown in genericpong(3)");}
           catch (NewUncheckedException e) {
               failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP3.equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              StackTraceElement[] st = e.getStackTrace();
+              failif( st.length != 5, "Stack length is only " + st.length);
+              failif( ! st[0].toString().startsWith("java_director_exception_feature_MyFooDirectorImpl.genericpong(java_director_exception_feature_runme.java:"), "Incorrect top of stack: " + st[0]);
           }
 	  try {  b.genericpong(4); fail("No exception thrown in genericpong(4)");}
           catch (RuntimeException e) {
-              failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RumtimeException");
-              failif( ! java_director_exception_feature_Consts.GENERICPONGEXCP4.equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
+              failif ( e.getClass() != RuntimeException.class, "Exception " + e + " is not exactly RuntimeException");
+              failif( ! "Unspecified DirectorException message".equals(e.getMessage()),  "Expected exception has unexpected message: '" + e.getMessage() + "'");
           }
 
       }
diff --git a/Examples/test-suite/java/java_throws_runme.java b/Examples/test-suite/java/java_throws_runme.java
index 0365b69..16eab7c 100644
--- a/Examples/test-suite/java/java_throws_runme.java
+++ b/Examples/test-suite/java/java_throws_runme.java
@@ -93,6 +93,28 @@
       if (!pass)
         throw new RuntimeException("Test 6 failed");
 
+      // Interface function
+      pass = false;
+      try {
+        InterfaceTestImpl iti = new InterfaceTestImpl();
+        iti.imethod(true);
+      }
+      catch (MyException e) { pass = true; }
+
+      if (!pass)
+        throw new RuntimeException("Test interface 1 failed");
+
+      pass = false;
+      try {
+        InterfaceTestImpl iti = new InterfaceTestImpl();
+        iti.imethod(false);
+        pass = true;
+      }
+      catch (MyException e) { pass = false; }
+
+      if (!pass)
+        throw new RuntimeException("Test interface 2 failed");
+
       // Global function
       pass = false;
       try {
diff --git a/Examples/test-suite/java/typedef_classforward_same_name_runme.java b/Examples/test-suite/java/typedef_classforward_same_name_runme.java
new file mode 100644
index 0000000..86e713d
--- /dev/null
+++ b/Examples/test-suite/java/typedef_classforward_same_name_runme.java
@@ -0,0 +1,26 @@
+
+import typedef_classforward_same_name.*;
+
+public class typedef_classforward_same_name_runme {
+
+  static {
+    try {
+	    System.loadLibrary("typedef_classforward_same_name");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    Foo foo = new Foo();
+    foo.setX(5);
+    if (typedef_classforward_same_name.extractFoo(foo) != 5)
+      throw new RuntimeException("unexpected value");
+
+    Boo boo = new Boo();
+    boo.setX(5);
+    if (typedef_classforward_same_name.extractBoo(boo) != 5)
+      throw new RuntimeException("unexpected value");
+  }
+}
diff --git a/Examples/test-suite/java_director_exception_feature.i b/Examples/test-suite/java_director_exception_feature.i
index a0b3b72..b5b9c39 100644
--- a/Examples/test-suite/java_director_exception_feature.i
+++ b/Examples/test-suite/java_director_exception_feature.i
@@ -42,7 +42,6 @@
 %feature("director:except") MyNS::Foo::ping {
   jthrowable $error = jenv->ExceptionOccurred();
   if ($error) {
-    jenv->ExceptionClear();  // clear java exception since mapping to c++ exception
     if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException1")) {
       throw 1;
     } else if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyJavaException2")) {
@@ -71,7 +70,6 @@
 %feature("director:except") MyNS::Foo::pong %{
   jthrowable $error = jenv->ExceptionOccurred();
   if ($error) {
-    jenv->ExceptionClear();
     $directorthrowshandlers
     throw ::MyNS::Unexpected(Swig::JavaExceptionMessage(jenv,$error).message());
   }
@@ -121,7 +119,10 @@
 %feature("director:except") MyNS::Foo::genericpong {
   jthrowable $error = jenv->ExceptionOccurred();
   if ($error) {
-    jenv->ExceptionClear();
+    if (Swig::ExceptionMatches(jenv,$error,"UnconstructableException")) {
+      // Purposefully test NULL
+      throw Swig::DirectorException(jenv, NULL);
+    }
     throw Swig::DirectorException(jenv,$error);
   }
 }
@@ -131,9 +132,10 @@
 %}
 
 %feature ("except",throws="Exception")  MyNS::Bar::genericpong %{
-  try { $action }
-  catch (Swig::DirectorException & direxcp) {
-    direxcp.raiseJavaException(jenv);  // jenv always available in JNI code
+  try {
+    $action
+  } catch (Swig::DirectorException & direxcp) {
+    direxcp.throwException(jenv);  // jenv always available in JNI code
     return $null;
   }
 %}
diff --git a/Examples/test-suite/java_director_exception_feature_nspace.i b/Examples/test-suite/java_director_exception_feature_nspace.i
index 3111538..9f542fd 100644
--- a/Examples/test-suite/java_director_exception_feature_nspace.i
+++ b/Examples/test-suite/java_director_exception_feature_nspace.i
@@ -49,7 +49,6 @@
 %feature("director:except") MyNS::Foo::ping {
   jthrowable $error = jenv->ExceptionOccurred();
   if ($error) {
-    jenv->ExceptionClear();  // clear java exception since mapping to c++ exception
     if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyNS/MyJavaException1")) {
       throw 1;
     } else if (Swig::ExceptionMatches(jenv,$error,"$packagepath/MyNS/MyJavaException2")) {
@@ -78,7 +77,6 @@
 %feature("director:except") MyNS::Foo::pong %{
   jthrowable $error = jenv->ExceptionOccurred();
   if ($error) {
-    jenv->ExceptionClear();
     $directorthrowshandlers
     throw ::MyNS::Unexpected(Swig::JavaExceptionMessage(jenv,$error).message());
   }
@@ -128,7 +126,10 @@
 %feature("director:except") MyNS::Foo::genericpong {
   jthrowable $error = jenv->ExceptionOccurred();
   if ($error) {
-    jenv->ExceptionClear();
+    if (Swig::ExceptionMatches(jenv,$error,"java_director_exception_feature_nspace_UnconstructibleException")) {
+      // Purposefully test NULL
+      throw Swig::DirectorException(jenv, NULL);
+    }
     throw Swig::DirectorException(jenv,$error);
   }
 }
@@ -138,9 +139,10 @@
 %}
 
 %feature ("except",throws="Exception")  MyNS::Bar::genericpong %{
-  try { $action }
-  catch (Swig::DirectorException & direxcp) {
-    direxcp.raiseJavaException(jenv);  // jenv always available in JNI code
+  try {
+    $action
+  } catch (Swig::DirectorException & direxcp) {
+    direxcp.throwException(jenv);  // jenv always available in JNI code
     return $null;
   }
 %}
diff --git a/Examples/test-suite/java_throws.i b/Examples/test-suite/java_throws.i
index c628a45..875bce0 100644
--- a/Examples/test-suite/java_throws.i
+++ b/Examples/test-suite/java_throws.i
@@ -135,6 +135,23 @@
     };
 %}
 
+%include <swiginterface.i>
+%interface_impl(InterfaceTest);
+JAVAEXCEPTION(imethod)
+
+%inline %{
+    struct InterfaceTest {
+        virtual void imethod(bool raise) = 0;
+    };
+
+    struct InterfaceTestImpl : InterfaceTest {
+        void imethod(bool raise) {
+            if (raise)
+                throw MyException("raise message");
+        }
+    };
+%}
+
 // Mixing except feature and typemaps when both generate a class for the throws clause
 %typemap(in, throws="ClassNotFoundException") int both { 
     $1 = (int)$input;
diff --git a/Examples/test-suite/li_std_string_extra.i b/Examples/test-suite/li_std_string_extra.i
index 6bef12f..1fc2225 100644
--- a/Examples/test-suite/li_std_string_extra.i
+++ b/Examples/test-suite/li_std_string_extra.i
@@ -49,6 +49,14 @@
    return x;
 }
 
+std::basic_string<char,std::char_traits<char>,std::allocator<char> > test_value_basic_overload(std::basic_string<char,std::char_traits<char>,std::allocator<char> > x) {
+   return x;
+}
+
+std::basic_string<char,std::char_traits<char>,std::allocator<char> > test_value_basic_overload(int) {
+   return "int";
+}
+
 #ifdef SWIGPYTHON_BUILTIN
 bool is_python_builtin() { return true; }
 #else
diff --git a/Examples/test-suite/php5/newobject3.php b/Examples/test-suite/php5/newobject3.php
deleted file mode 100644
index 21e1769..0000000
--- a/Examples/test-suite/php5/newobject3.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-
-/* ----------------------------------------------------------------------------
- * This file was automatically generated by SWIG (http://www.swig.org).
- * Version 4.0.0
- *
- * This file is not intended to be easily readable and contains a number of
- * coding conventions designed to improve portability and efficiency. Do not make
- * changes to this file unless you know what you are doing--modify the SWIG
- * interface file instead.
- * ----------------------------------------------------------------------------- */
-
-// Try to load our extension if it's not already loaded.
-if (!extension_loaded('newobject3')) {
-  if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {
-    if (!dl('php_newobject3.dll')) return;
-  } else {
-    // PHP_SHLIB_SUFFIX gives 'dylib' on MacOS X but modules are 'so'.
-    if (PHP_SHLIB_SUFFIX === 'dylib') {
-      if (!dl('newobject3.so')) return;
-    } else {
-      if (!dl('newobject3.'.PHP_SHLIB_SUFFIX)) return;
-    }
-  }
-}
-
-
-
-/* PHP Proxy Classes */
-class Product {
-	public $_cPtr=null;
-	protected $_pData=array();
-
-	function __set($var,$value) {
-		if ($var === 'thisown') return swig_newobject3_alter_newobject($this->_cPtr,$value);
-		$this->_pData[$var] = $value;
-	}
-
-	function __get($var) {
-		if ($var === 'thisown') return swig_newobject3_get_newobject($this->_cPtr);
-		return $this->_pData[$var];
-	}
-
-	function __isset($var) {
-		if ($var === 'thisown') return true;
-		return array_key_exists($var, $this->_pData);
-	}
-
-	function __construct($res=null) {
-		if (is_resource($res) && get_resource_type($res) === '_p_Product') {
-			$this->_cPtr=$res;
-			return;
-		}
-		$this->_cPtr=new_Product();
-	}
-}
-
-class factory {
-	public $_cPtr=null;
-	protected $_pData=array();
-
-	function __set($var,$value) {
-		if ($var === 'thisown') return swig_newobject3_alter_newobject($this->_cPtr,$value);
-		$this->_pData[$var] = $value;
-	}
-
-	function __get($var) {
-		if ($var === 'thisown') return swig_newobject3_get_newobject($this->_cPtr);
-		return $this->_pData[$var];
-	}
-
-	function __isset($var) {
-		if ($var === 'thisown') return true;
-		return array_key_exists($var, $this->_pData);
-	}
-
-	function create($id_or_name,$type=0) {
-		$r=factory_create($this->_cPtr,$id_or_name,$type);
-		if (!is_resource($r)) return $r;
-		return new Product($r);
-	}
-
-	function __construct($res=null) {
-		if (is_resource($res) && get_resource_type($res) === '_p_factory') {
-			$this->_cPtr=$res;
-			return;
-		}
-		$this->_cPtr=new_factory();
-	}
-}
-
-
-?>
diff --git a/Examples/test-suite/php5/php_newobject3.h b/Examples/test-suite/php5/php_newobject3.h
deleted file mode 100644
index 6ff3070..0000000
--- a/Examples/test-suite/php5/php_newobject3.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* ----------------------------------------------------------------------------
- * This file was automatically generated by SWIG (http://www.swig.org).
- * Version 4.0.0
- *
- * This file is not intended to be easily readable and contains a number of
- * coding conventions designed to improve portability and efficiency. Do not make
- * changes to this file unless you know what you are doing--modify the SWIG
- * interface file instead.
- * ----------------------------------------------------------------------------- */
-
-#ifndef PHP_NEWOBJECT3_H
-#define PHP_NEWOBJECT3_H
-
-extern zend_module_entry newobject3_module_entry;
-#define phpext_newobject3_ptr &newobject3_module_entry
-
-#ifdef PHP_WIN32
-# define PHP_NEWOBJECT3_API __declspec(dllexport)
-#else
-# define PHP_NEWOBJECT3_API
-#endif
-
-#ifdef ZTS
-#include "TSRM.h"
-#endif
-
-PHP_MINIT_FUNCTION(newobject3);
-PHP_MSHUTDOWN_FUNCTION(newobject3);
-PHP_RINIT_FUNCTION(newobject3);
-PHP_RSHUTDOWN_FUNCTION(newobject3);
-PHP_MINFO_FUNCTION(newobject3);
-
-ZEND_NAMED_FUNCTION(_wrap_new_Product);
-ZEND_NAMED_FUNCTION(_wrap_factory_create);
-ZEND_NAMED_FUNCTION(_wrap_new_factory);
-#endif /* PHP_NEWOBJECT3_H */
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index 8694265..12844e3 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -10,8 +10,8 @@
 
 LANGUAGE     = python
 PYTHON       = $(PYBIN)
-PEP8         = @PEP8@
-PEP8_FLAGS   = --ignore=E30,E402,E501,E731,W291,W391
+PYCODESTYLE       = @PYCODESTYLE@
+PYCODESTYLE_FLAGS = --ignore=E30,E402,E501,E731,W291,W391
 
 #*_runme.py for Python 2.x, *_runme3.py for Python 3.x
 PY2SCRIPTSUFFIX = _runme.py
@@ -141,12 +141,12 @@
 py2_runme = $(SCRIPTPREFIX)$*$(PY2SCRIPTSUFFIX)
 py3_runme = $(SCRIPTPREFIX)$*$(PY3SCRIPTSUFFIX)
 
-ifneq (,$(PEP8))
-check_pep8 = $(COMPILETOOL) $(PEP8) $(PEP8_FLAGS) $(SCRIPTPREFIX)$*.py
+ifneq (,$(PYCODESTYLE))
+check_pep8 = $(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(SCRIPTPREFIX)$*.py
 
 check_pep8_multi_cpp = \
 	for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
-	  $(COMPILETOOL) $(PEP8) $(PEP8_FLAGS) $$f.py; \
+	  $(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $$f.py; \
 	done
 endif
 
diff --git a/Examples/test-suite/python/li_std_string_extra_runme.py b/Examples/test-suite/python/li_std_string_extra_runme.py
index b65f077..9835eaa 100644
--- a/Examples/test-suite/python/li_std_string_extra_runme.py
+++ b/Examples/test-suite/python/li_std_string_extra_runme.py
@@ -87,6 +87,24 @@
 if li_std_string_extra.test_value_basic3(x) != x:
     raise RuntimeError, "bad string mapping"
 
+if li_std_string_extra.test_value_basic_overload(x) != x:
+    raise RuntimeError, "bad overload string"
+
+if li_std_string_extra.test_value_basic_overload(123) != "int":
+    raise RuntimeError, "bad overload int"
+
+try:
+    li_std_string_extra.test_value_basic_overload([x])
+    raise RuntimeError, "should throw NotImplementedError"
+except NotImplementedError:
+    pass
+
+try:
+    li_std_string_extra.test_value_basic_overload([123])
+    raise RuntimeError, "should throw NotImplementedError"
+except NotImplementedError:
+    pass
+
 # Global variables
 s = "initial string"
 if li_std_string_extra.cvar.GlobalString2 != "global string 2":
diff --git a/Examples/test-suite/python/typedef_classforward_same_name_runme.py b/Examples/test-suite/python/typedef_classforward_same_name_runme.py
new file mode 100644
index 0000000..61f45fb
--- /dev/null
+++ b/Examples/test-suite/python/typedef_classforward_same_name_runme.py
@@ -0,0 +1,11 @@
+from typedef_classforward_same_name import *
+
+foo = Foo()
+foo.x = 5
+if extractFoo(foo) != 5:
+    raise RuntimeError("unexpected value")
+
+boo = Boo()
+boo.x = 5
+if extractBoo(boo) != 5:
+    raise RuntimeError("unexpected value")
diff --git a/Examples/test-suite/python/unicode_strings_runme.py b/Examples/test-suite/python/unicode_strings_runme.py
index fa9c514..39e93b0 100644
--- a/Examples/test-suite/python/unicode_strings_runme.py
+++ b/Examples/test-suite/python/unicode_strings_runme.py
@@ -25,3 +25,13 @@
     check(unicode_strings.charstring(unicode("hello4")), "hello4")
     unicode_strings.charstring(u"hell\xb05")
     unicode_strings.charstring(u"hell\u00f66")
+
+low_surrogate_string = u"\udcff"
+try:
+    unicode_strings.instring(low_surrogate_string)
+    # Will succeed with Python 2
+except TypeError, e:
+    # Python 3 will fail the PyUnicode_AsUTF8String conversion resulting in a TypeError.
+    # The real error is actually:
+    # UnicodeEncodeError: 'utf-8' codec can't encode character '\udcff' in position 0: surrogates not allowed
+    pass
diff --git a/Examples/test-suite/python_varargs_typemap.i b/Examples/test-suite/python_varargs_typemap.i
index f05fb98..d809bf1 100644
--- a/Examples/test-suite/python_varargs_typemap.i
+++ b/Examples/test-suite/python_varargs_typemap.i
@@ -23,8 +23,11 @@
        SWIG_fail;
     }
     pystr = PyUnicode_AsUTF8String(pyobj);
+    if (!pystr) {
+      SWIG_fail;
+    }
     str = strdup(PyBytes_AsString(pystr));
-    Py_XDECREF(pystr);
+    Py_DECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
        PyErr_SetString(PyExc_ValueError, "Expected a string");
diff --git a/Examples/test-suite/r/Makefile.in b/Examples/test-suite/r/Makefile.in
index 38cd78e..13fd365 100644
--- a/Examples/test-suite/r/Makefile.in
+++ b/Examples/test-suite/r/Makefile.in
@@ -20,7 +20,8 @@
 	r_double_delete \
 	r_overload_array \
 	r_sexp \
-        r_overload_comma
+        r_overload_comma \
+	r_use_isnull
 
 # These tests are failing because enums currently cannot handle
 # arithmetic expressions
diff --git a/Examples/test-suite/r/r_use_isnull_runme.R b/Examples/test-suite/r/r_use_isnull_runme.R
new file mode 100644
index 0000000..0dbf876
--- /dev/null
+++ b/Examples/test-suite/r/r_use_isnull_runme.R
@@ -0,0 +1,11 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("r_use_isnull", .Platform$dynlib.ext, sep=""))
+source("r_use_isnull.R")
+cacheMetaData(1)
+
+tp <- pointerTest()
+circ1 <- tp$getCircle(1)
+circ1
+unittest(is.null(circ1), TRUE)
diff --git a/Examples/test-suite/r_use_isnull.i b/Examples/test-suite/r_use_isnull.i
new file mode 100644
index 0000000..03b4c15
--- /dev/null
+++ b/Examples/test-suite/r_use_isnull.i
@@ -0,0 +1,34 @@
+%module r_use_isnull
+
+%inline %{
+// C++ code
+class circle {
+public:
+circle(double radius)
+{
+m_radius = radius;
+}
+double getArea() const
+{
+return (3.14 * m_radius * m_radius);
+}
+
+private:
+double m_radius;
+};
+
+class pointerTest {
+public:
+pointerTest() : m_circle(2) {}
+const circle * getCircle(int index) const {
+if (index == 0)
+return & m_circle;
+else
+return 0;
+}
+
+private:
+    circle m_circle;
+
+};
+ %}
diff --git a/Examples/test-suite/typedef_classforward_same_name.i b/Examples/test-suite/typedef_classforward_same_name.i
new file mode 100644
index 0000000..ad2e456
--- /dev/null
+++ b/Examples/test-suite/typedef_classforward_same_name.i
@@ -0,0 +1,15 @@
+%module typedef_classforward_same_name
+
+%inline %{
+typedef struct Foo Foo;
+struct Foo {
+   int x;
+};
+int extractFoo(Foo* foo) { return foo->x; }
+
+struct Boo {
+   int x;
+};
+typedef struct Boo Boo;
+int extractBoo(Boo* boo) { return boo->x; }
+%}
diff --git a/Examples/test-suite/unicode_strings.i b/Examples/test-suite/unicode_strings.i
index 9be3748..e726626 100644
--- a/Examples/test-suite/unicode_strings.i
+++ b/Examples/test-suite/unicode_strings.i
@@ -20,4 +20,6 @@
   return s;
 }
 
+void instring(const char *s) {
+}
 %}
diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg
index 5b53933..e1554dc 100644
--- a/Lib/csharp/csharp.swg
+++ b/Lib/csharp/csharp.swg
@@ -857,8 +857,10 @@
 %{ $result = (void *)*$1; %} 
 %typemap(directorin) SWIGTYPE *const&
 %{ $input = (void *) $1; %}
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const&
-%{ $result = ($1_ltype)&$input; %}
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) SWIGTYPE *const&
+%{ static $*1_ltype swig_temp;
+   swig_temp = ($*1_ltype)$input;
+   $result = &swig_temp; %}
 %typemap(csdirectorin) SWIGTYPE *const& "($iminput == global::System.IntPtr.Zero) ? null : new $*csclassname($iminput, false)"
 %typemap(csdirectorout) SWIGTYPE *const& "$*csclassname.getCPtr($cscall).Handle"
 
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index 19b7000..f0d604b 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -185,7 +185,9 @@
 %typemap(directorin) SWIGTYPE *const&
   "$input = (void *) $1;"
 %typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const&
-  "$result = ($1_ltype)&$input;"
+%{ static $*1_ltype swig_temp;
+   swig_temp = ($*1_ltype)$input;
+   $result = &swig_temp; %}
 %typemap(ddirectorin,
   nativepointer="cast($dtype)$winput"
 ) SWIGTYPE *const& "($winput is null) ? null : new $*dclassname($winput, false)"
diff --git a/Lib/go/director.swg b/Lib/go/director.swg
new file mode 100644
index 0000000..69244eb
--- /dev/null
+++ b/Lib/go/director.swg
@@ -0,0 +1,15 @@
+/* -----------------------------------------------------------------------------
+ * director.swg
+ *
+ * This file contains support for director classes so that Go proxy
+ * methods can be called from C++.
+ * ----------------------------------------------------------------------------- */
+
+#include <exception>
+
+namespace Swig {
+
+  class DirectorException : public std::exception {
+  };
+}
+
diff --git a/Lib/go/go.swg b/Lib/go/go.swg
index 3e1fab2..c225ed9 100644
--- a/Lib/go/go.swg
+++ b/Lib/go/go.swg
@@ -380,6 +380,11 @@
 %typemap(directorout) SWIGTYPE &
 %{ *($&1_ltype)&$result = $input; %}
 
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const&
+%{ static $*1_ltype swig_temp;
+   swig_temp = *($1_ltype)&$input;
+   $result = &swig_temp; %}
+
 %typemap(gotype) SWIGTYPE &&
 %{$gotypename%}
 
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index abde722..2275976 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -259,8 +259,10 @@
     JavaExceptionMessage(JNIEnv *jenv, jthrowable throwable) : message_(jenv, exceptionMessageFromThrowable(jenv, throwable)) {
     }
 
-    const char *message() const {
-      return message_.c_str("Could not get exception message in JavaExceptionMessage");
+    // Return a C string of the exception message in the jthrowable passed in the constructor
+    // If no message is available, null_string is return instead
+    const char *message(const char *null_string = "Could not get exception message in JavaExceptionMessage") const {
+      return message_.c_str(null_string);
     }
 
   private:
@@ -294,10 +296,11 @@
   public:
 
     // Construct exception from a Java throwable
-    DirectorException(JNIEnv *jenv, jthrowable throwable) : classname_(0), msg_(0) {
+    DirectorException(JNIEnv *jenv, jthrowable throwable) : jenv_(jenv), throwable_(throwable), classname_(0), msg_(0) {
 
       // Call Java method Object.getClass().getName() to obtain the throwable's class name (delimited by '/')
-      if (throwable) {
+      if (jenv && throwable) {
+	jenv->ExceptionClear(); // Cannot invoke methods with any pending exceptions
 	jclass throwclz = jenv->GetObjectClass(throwable);
 	if (throwclz) {
 	  jclass clzclz = jenv->GetObjectClass(throwclz);
@@ -318,11 +321,11 @@
       }
 
       JavaExceptionMessage exceptionmsg(jenv, throwable);
-      msg_ = copystr(exceptionmsg.message());
+      msg_ = copystr(exceptionmsg.message(0));
     }
 
     // More general constructor for handling as a java.lang.RuntimeException
-    DirectorException(const char *msg) : classname_(0), msg_(copystr(msg ? msg : "Unspecified DirectorException message")) {
+    DirectorException(const char *msg) : jenv_(0), throwable_(0), classname_(0), msg_(msg ? copystr(msg) : 0) {
     }
 
     ~DirectorException() throw() {
@@ -331,31 +334,49 @@
     }
 
     const char *what() const throw() {
-      return msg_;
+      return msg_ ? msg_ : "Unspecified DirectorException message";
     }
 
     // Reconstruct and raise/throw the Java Exception that caused the DirectorException
     // Note that any error in the JNI exception handling results in a Java RuntimeException
-    void raiseJavaException(JNIEnv *jenv) const {
+    void throwException(JNIEnv *jenv) const {
       if (jenv) {
-	jenv->ExceptionClear();
+        if (jenv == jenv_ && throwable_) {
+          // Throw original exception if not already pending
+          jthrowable throwable = jenv->ExceptionOccurred();
+          if (throwable && jenv->IsSameObject(throwable, throwable_) == JNI_FALSE) {
+            jenv->ExceptionClear();
+            throwable = 0;
+          }
+          if (!throwable)
+            jenv->Throw(throwable_);
+        } else {
+          // Try and reconstruct original exception, but original stacktrace is not reconstructed
+          jenv->ExceptionClear();
 
-	jmethodID ctorMethodID = 0;
-	jclass throwableclass = 0;
-        if (classname_) {
-          throwableclass = jenv->FindClass(classname_);
-          if (throwableclass)
-            ctorMethodID = jenv->GetMethodID(throwableclass, "<init>", "(Ljava/lang/String;)V");
-	}
+          jmethodID ctorMethodID = 0;
+          jclass throwableclass = 0;
+          if (classname_) {
+            throwableclass = jenv->FindClass(classname_);
+            if (throwableclass)
+              ctorMethodID = jenv->GetMethodID(throwableclass, "<init>", "(Ljava/lang/String;)V");
+          }
 
-	if (ctorMethodID) {
-	  jenv->ThrowNew(throwableclass, what());
-	} else {
-	  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, what());
-	}
+          if (ctorMethodID) {
+            jenv->ThrowNew(throwableclass, what());
+          } else {
+            SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, what());
+          }
+        }
       }
     }
 
+    // Deprecated - use throwException
+    void raiseJavaException(JNIEnv *jenv) const {
+      throwException(jenv);
+    }
+
+    // Create and throw the DirectorException
     static void raise(JNIEnv *jenv, jthrowable throwable) {
       throw DirectorException(jenv, throwable);
     }
@@ -380,11 +401,14 @@
       return target;
     }
 
+    JNIEnv *jenv_;
+    jthrowable throwable_;
     const char *classname_;
     const char *msg_;
   };
 
   // Helper method to determine if a Java throwable matches a particular Java class type
+  // Note side effect of clearing any pending exceptions
   SWIGINTERN bool ExceptionMatches(JNIEnv *jenv, jthrowable throwable, const char *classname) {
     bool matches = false;
 
diff --git a/Lib/java/java.swg b/Lib/java/java.swg
index 903387a..19e597b 100644
--- a/Lib/java/java.swg
+++ b/Lib/java/java.swg
@@ -1051,6 +1051,14 @@
 %{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1);
    return $null; %}
 
+/* For methods to raise/throw the original Java exception thrown in a director method */
+%typemap(throws) Swig::DirectorException
+%{  $1.throwException(jenv);
+    return $null; %}
+
+/* Java to C++ DirectorException should already be handled. Suppress warning and do nothing in the
+   event a user specifies a global: %catches(Swig::DirectorException); */
+%typemap(directorthrows) Swig::DirectorException ""
 
 /* Typemaps for code generation in proxy classes and Java type wrapper classes */
 
@@ -1175,8 +1183,10 @@
 %{ *($1_ltype)&$result = *$1; %} 
 %typemap(directorin,descriptor="L$packagepath/$*javaclassname;") SWIGTYPE *const&
 %{ *(($1_ltype)&$input) = ($*1_ltype) $1; %}
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const&
-%{ $result = ($1_ltype)&$input; %}
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) SWIGTYPE *const&
+%{ static $*1_ltype swig_temp;
+   swig_temp = *($1_ltype)&$input;
+   $result = &swig_temp; %}
 %typemap(javadirectorin) SWIGTYPE *const& "($jniinput == 0) ? null : new $*javaclassname($jniinput, false)"
 %typemap(javadirectorout) SWIGTYPE *const& "$*javaclassname.getCPtr($javacall)"
 
diff --git a/Lib/octave/director.swg b/Lib/octave/director.swg
index e80877e..86ac3b0 100644
--- a/Lib/octave/director.swg
+++ b/Lib/octave/director.swg
@@ -46,7 +46,22 @@
     }
   };
 
-  struct DirectorTypeMismatchException {
+  // Base class for director exceptions.
+  class DirectorException : public std::exception {
+  public:
+    static void raise(const char *msg) {
+      // ... todo
+      throw(DirectorException());
+    }
+
+    static void raise(const octave_value &ov, const char *msg) {
+      // ... todo
+      raise(msg);
+    }
+  };
+
+  class DirectorTypeMismatchException : public DirectorException {
+  public:
     static void raise(const char *msg) {
       // ... todo
       throw(DirectorTypeMismatchException());
@@ -58,7 +73,8 @@
     }
   };
 
-  struct DirectorPureVirtualException {
+  class DirectorPureVirtualException : public DirectorException {
+  public:
     static void raise(const char *msg) {
       // ... todo
       throw(DirectorPureVirtualException());
diff --git a/Lib/octave/std_basic_string.i b/Lib/octave/std_basic_string.i
index 19712e8..01a2c34 100644
--- a/Lib/octave/std_basic_string.i
+++ b/Lib/octave/std_basic_string.i
@@ -10,24 +10,20 @@
 %fragment(SWIG_AsPtr_frag(std::basic_string<char>),"header",
 	  fragment="SWIG_AsCharPtrAndSize") {
 SWIGINTERN int
-SWIG_AsPtr(std::basic_string<char>)(octave_value obj, std::string **val)
-{
+SWIG_AsPtr(std::basic_string<char>)(octave_value obj, std::string **val) {
   if (obj.is_string()) {
     if (val)
       *val = new std::string(obj.string_value());
     return SWIG_NEWOBJ;
   }
-  if (val)
-    error("a string is expected");
-  return 0;
+  return SWIG_ERROR;
 }
 }
 
 %fragment(SWIG_From_frag(std::basic_string<char>),"header",
 	  fragment="SWIG_FromCharPtrAndSize") {
 SWIGINTERNINLINE octave_value
-  SWIG_From(std::basic_string<char>)(const std::string& s)
-  {
+  SWIG_From(std::basic_string<char>)(const std::string& s) {
     return SWIG_FromCharPtrAndSize(s.data(), s.size());
   }
 }
@@ -45,41 +41,20 @@
 %fragment(SWIG_AsPtr_frag(std::basic_string<wchar_t>),"header",
 	  fragment="SWIG_AsWCharPtrAndSize") {
 SWIGINTERN int
-  SWIG_AsPtr(std::basic_string<wchar_t>)(PyObject* obj, std::wstring **val)
-  {
-    static swig_type_info* string_info = 
-      SWIG_TypeQuery("std::basic_string<wchar_t> *");
-    std::wstring *vptr;    
-    if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
-      if (val) *val = vptr;
-      return SWIG_OLDOBJ;
-    } else {
-      PyErr_Clear();
-      wchar_t *buf = 0 ; size_t size = 0; int alloc = 0;
-      if (SWIG_AsWCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
-	if (buf) {
-	  if (val) *val = new std::wstring(buf, size - 1);
-	  if (alloc == SWIG_NEWOBJ) %delete_array(buf);
-	  return SWIG_NEWOBJ;
-	}
-      } else {
-	PyErr_Clear();
-      }  
-      if (val) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-	PyErr_SetString(PyExc_TypeError,"a wstring is expected");
-	SWIG_PYTHON_THREAD_END_BLOCK;
-      }
-      return 0;
-    }
+SWIG_AsPtr(std::basic_string<wchar_t>)(octave_value obj, std::wstring **val) {
+  if (obj.is_string()) {
+    if (val)
+      *val = new std::wstring(obj.string_value());
+    return SWIG_NEWOBJ;
   }
+  return SWIG_ERROR;
+}
 }
 
 %fragment(SWIG_From_frag(std::basic_string<wchar_t>),"header",
 	  fragment="SWIG_FromWCharPtrAndSize") {
 SWIGINTERNINLINE PyObject*
-  SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s)
-  {
+  SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s) {
     return SWIG_FromWCharPtrAndSize(s.data(), s.size());
   }
 }
diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg
index cc4ba44..02714c4 100644
--- a/Lib/perl5/perlrun.swg
+++ b/Lib/perl5/perlrun.swg
@@ -20,6 +20,7 @@
 #define SWIG_ConvertPtr(obj, pp, type, flags)           SWIG_Perl_ConvertPtr(SWIG_PERL_OBJECT_CALL obj, pp, type, flags)
 #define SWIG_ConvertPtrAndOwn(obj, pp, type, flags,own) SWIG_Perl_ConvertPtrAndOwn(SWIG_PERL_OBJECT_CALL obj, pp, type, flags, own)
 #define SWIG_NewPointerObj(p, type, flags)              SWIG_Perl_NewPointerObj(SWIG_PERL_OBJECT_CALL p, type, flags)
+#define SWIG_AcquirePtr(ptr, src)                       SWIG_Perl_AcquirePtr(ptr, src)
 #define swig_owntype                                    int
 
 /* for raw packed data */
@@ -229,6 +230,14 @@
   return 0;
 }
 
+/* Acquire a pointer value */
+
+SWIGRUNTIME int
+SWIG_Perl_AcquirePtr(SWIG_MAYBE_PERL_OBJECT SV *sv, int own) {
+  /* TODO */
+  return 0;
+}
+
 /* Function for getting a pointer value */
 
 SWIGRUNTIME int
diff --git a/Lib/perl5/perltypemaps.swg b/Lib/perl5/perltypemaps.swg
index ffec5ea..a86d3ad 100644
--- a/Lib/perl5/perltypemaps.swg
+++ b/Lib/perl5/perltypemaps.swg
@@ -71,6 +71,10 @@
 /* raise exception */
 %define %raise(obj, type, desc) sv_setsv(get_sv("@", GV_ADD), obj); SWIG_fail %enddef
 
+/* For directors to raise/throw the original exception */
+%typemap(throws) Swig::DirectorException
+%{ sv_setsv(ERRSV, $1.getNative()); SWIG_fail; %}
+
 /* Include the unified typemap library */
 %include <typemaps/swigtypemaps.swg>
 
diff --git a/Lib/python/pyerrors.swg b/Lib/python/pyerrors.swg
index fe73135..463afae 100644
--- a/Lib/python/pyerrors.swg
+++ b/Lib/python/pyerrors.swg
@@ -53,14 +53,17 @@
   PyObject *value = 0;
   PyObject *traceback = 0;
 
-  if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
+  if (PyErr_Occurred())
+    PyErr_Fetch(&type, &value, &traceback);
   if (value) {
-    char *tmp;
     PyObject *old_str = PyObject_Str(value);
+    const char *tmp = SWIG_Python_str_AsChar(old_str);
     PyErr_Clear();
     Py_XINCREF(type);
-
-    PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
+    if (tmp)
+      PyErr_Format(type, "%s %s", tmp, mesg);
+    else
+      PyErr_Format(type, "%s", mesg);
     SWIG_Python_str_DelForPy3(tmp);
     Py_DECREF(old_str);
     Py_DECREF(value);
diff --git a/Lib/python/pyhead.swg b/Lib/python/pyhead.swg
index 55eb95a..2fa8b5b 100644
--- a/Lib/python/pyhead.swg
+++ b/Lib/python/pyhead.swg
@@ -38,14 +38,16 @@
 SWIG_Python_str_AsChar(PyObject *str)
 {
 #if PY_VERSION_HEX >= 0x03000000
-  char *cstr;
-  char *newstr;
-  Py_ssize_t len;
+  char *newstr = 0;
   str = PyUnicode_AsUTF8String(str);
-  PyBytes_AsStringAndSize(str, &cstr, &len);
-  newstr = (char *) malloc(len+1);
-  memcpy(newstr, cstr, len+1);
-  Py_XDECREF(str);
+  if (str) {
+    char *cstr;
+    Py_ssize_t len;
+    PyBytes_AsStringAndSize(str, &cstr, &len);
+    newstr = (char *) malloc(len+1);
+    memcpy(newstr, cstr, len+1);
+    Py_XDECREF(str);
+  }
   return newstr;
 #else
   return PyString_AsString(str);
diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg
index fe45ac9..826f841 100644
--- a/Lib/python/pyinit.swg
+++ b/Lib/python/pyinit.swg
@@ -84,10 +84,10 @@
 
 SWIGINTERN int
 swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
-  char *tmp;
   PyObject *str = swig_varlink_str(v);
+  const char *tmp = SWIG_Python_str_AsChar(str);
   fprintf(fp,"Swig global variables ");
-  fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
+  fprintf(fp,"%s\n", tmp ? tmp : "Invalid global variable");
   SWIG_Python_str_DelForPy3(tmp);
   Py_DECREF(str);
   return 0;
diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg
index efc4766..430d3af 100644
--- a/Lib/python/pyrun.swg
+++ b/Lib/python/pyrun.swg
@@ -1672,14 +1672,16 @@
     PyObject *traceback = 0;
     PyErr_Fetch(&type, &value, &traceback);
     if (value) {
-      char *tmp;
       PyObject *old_str = PyObject_Str(value);
+      const char *tmp = SWIG_Python_str_AsChar(old_str);
+      if (!tmp)
+        tmp = "Invalid error message";
       Py_XINCREF(type);
       PyErr_Clear();
       if (infront) {
-	PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
+	PyErr_Format(type, "%s %s", mesg, tmp);
       } else {
-	PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
+	PyErr_Format(type, "%s %s", tmp, mesg);
       }
       SWIG_Python_str_DelForPy3(tmp);
       Py_DECREF(old_str);
@@ -1805,6 +1807,8 @@
       Py_INCREF(name);
     } else {
       encoded_name = PyUnicode_AsUTF8String(name);
+      if (!encoded_name)
+        return -1;
     }
     PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
     Py_DECREF(encoded_name);
diff --git a/Lib/python/pystrings.swg b/Lib/python/pystrings.swg
index fd37855..301e0f3 100644
--- a/Lib/python/pystrings.swg
+++ b/Lib/python/pystrings.swg
@@ -16,6 +16,7 @@
 %#endif
   {
     char *cstr; Py_ssize_t len;
+    int ret = SWIG_OK;
 %#if PY_VERSION_HEX>=0x03000000
 %#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
     if (!alloc && cptr) {
@@ -26,7 +27,10 @@
         return SWIG_RuntimeError;
     }
     obj = PyUnicode_AsUTF8String(obj);
-    if(alloc) *alloc = SWIG_NEWOBJ;
+    if (!obj)
+      return SWIG_TypeError;
+    if (alloc)
+      *alloc = SWIG_NEWOBJ;
 %#endif
     PyBytes_AsStringAndSize(obj, &cstr, &len);
 %#else
@@ -64,6 +68,8 @@
 %#endif
 %#else
 	*cptr = SWIG_Python_str_AsChar(obj);
+        if (!*cptr)
+          ret = SWIG_TypeError;
 %#endif
       }
     }
@@ -71,7 +77,7 @@
 %#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
     Py_XDECREF(obj);
 %#endif
-    return SWIG_OK;
+    return ret;
   } else {
 %#if defined(SWIG_PYTHON_2_UNICODE)
 %#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
@@ -84,6 +90,8 @@
         return SWIG_RuntimeError;
       }
       obj = PyUnicode_AsUTF8String(obj);
+      if (!obj)
+        return SWIG_TypeError;
       if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) {
         if (cptr) {
           if (alloc) *alloc = SWIG_NEWOBJ;
diff --git a/Lib/python/std_basic_string.i b/Lib/python/std_basic_string.i
index 7d3366d..e3f524d 100644
--- a/Lib/python/std_basic_string.i
+++ b/Lib/python/std_basic_string.i
@@ -9,41 +9,34 @@
 %fragment(SWIG_AsPtr_frag(std::basic_string<char>),"header",
 	  fragment="SWIG_AsCharPtrAndSize") {
 SWIGINTERN int
-SWIG_AsPtr(std::basic_string<char>)(PyObject* obj, std::string **val)
-{
-  static swig_type_info* string_info = 
-    SWIG_TypeQuery("std::basic_string<char> *");
-  std::string *vptr;    
-  if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
+SWIG_AsPtr(std::basic_string<char>)(PyObject* obj, std::string **val) {
+  static swig_type_info* string_info = SWIG_TypeQuery("std::basic_string<char> *");
+  std::string *vptr;
+  if (SWIG_IsOK(SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0))) {
     if (val) *val = vptr;
     return SWIG_OLDOBJ;
   } else {
     PyErr_Clear();
     char* buf = 0 ; size_t size = 0; int alloc = 0;
-    if (SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
+    if (SWIG_IsOK(SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc))) {
       if (buf) {
 	if (val) *val = new std::string(buf, size - 1);
 	if (alloc == SWIG_NEWOBJ) %delete_array(buf);
 	return SWIG_NEWOBJ;
+      } else {
+        if (val) *val = 0;
+        return SWIG_OLDOBJ;
       }
-    } else {
-      PyErr_Clear();
-    }  
-    if (val) {
-      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-      PyErr_SetString(PyExc_TypeError,"a string is expected");
-      SWIG_PYTHON_THREAD_END_BLOCK;
     }
-    return 0;
+    return SWIG_ERROR;
   }
-}  
+}
 }
 
 %fragment(SWIG_From_frag(std::basic_string<char>),"header",
 	  fragment="SWIG_FromCharPtrAndSize") {
 SWIGINTERNINLINE PyObject*
-  SWIG_From(std::basic_string<char>)(const std::string& s)
-  {
+  SWIG_From(std::basic_string<char>)(const std::string& s) {
     return SWIG_FromCharPtrAndSize(s.data(), s.size());
   }
 }
@@ -59,41 +52,34 @@
 %fragment(SWIG_AsPtr_frag(std::basic_string<wchar_t>),"header",
 	  fragment="SWIG_AsWCharPtrAndSize") {
 SWIGINTERN int
-  SWIG_AsPtr(std::basic_string<wchar_t>)(PyObject* obj, std::wstring **val)
-  {
-    static swig_type_info* string_info = 
-      SWIG_TypeQuery("std::basic_string<wchar_t> *");
-    std::wstring *vptr;    
-    if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
-      if (val) *val = vptr;
-      return SWIG_OLDOBJ;
-    } else {
-      PyErr_Clear();
-      wchar_t *buf = 0 ; size_t size = 0; int alloc = 0;
-      if (SWIG_AsWCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
-	if (buf) {
-	  if (val) *val = new std::wstring(buf, size - 1);
-	  if (alloc == SWIG_NEWOBJ) %delete_array(buf);
-	  return SWIG_NEWOBJ;
-	}
+SWIG_AsPtr(std::basic_string<wchar_t>)(PyObject* obj, std::wstring **val) {
+  static swig_type_info* string_info = SWIG_TypeQuery("std::basic_string<wchar_t> *");
+  std::wstring *vptr;
+  if (SWIG_IsOK(SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0))) {
+    if (val) *val = vptr;
+    return SWIG_OLDOBJ;
+  } else {
+    PyErr_Clear();
+    wchar_t *buf = 0 ; size_t size = 0; int alloc = 0;
+    if (SWIG_IsOK(SWIG_AsWCharPtrAndSize(obj, &buf, &size, &alloc))) {
+      if (buf) {
+        if (val) *val = new std::wstring(buf, size - 1);
+        if (alloc == SWIG_NEWOBJ) %delete_array(buf);
+        return SWIG_NEWOBJ;
       } else {
-	PyErr_Clear();
-      }  
-      if (val) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-	PyErr_SetString(PyExc_TypeError,"a wstring is expected");
-	SWIG_PYTHON_THREAD_END_BLOCK;
+        if (val) *val = 0;
+        return SWIG_OLDOBJ;
       }
-      return 0;
     }
+    return SWIG_ERROR;
   }
 }
+}
 
 %fragment(SWIG_From_frag(std::basic_string<wchar_t>),"header",
 	  fragment="SWIG_FromWCharPtrAndSize") {
 SWIGINTERNINLINE PyObject*
-  SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s)
-  {
+  SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s) {
     return SWIG_FromWCharPtrAndSize(s.data(), s.size());
   }
 }
diff --git a/Lib/r/rrun.swg b/Lib/r/rrun.swg
index bec9815..8067f0a 100644
--- a/Lib/r/rrun.swg
+++ b/Lib/r/rrun.swg
@@ -260,7 +260,11 @@
 /* Create a new pointer object */
 SWIGRUNTIMEINLINE SEXP
 SWIG_R_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
-  SEXP rptr = R_MakeExternalPtr(ptr, 
+  SEXP rptr;
+  if (!ptr) {
+     return R_NilValue;
+  }
+  rptr = R_MakeExternalPtr(ptr, 
   R_MakeExternalPtr(type, R_NilValue, R_NilValue), R_NilValue); 
   SET_S4_OBJECT(rptr);
   return rptr;
diff --git a/Lib/r/rtype.swg b/Lib/r/rtype.swg
index 22639f2..c55c703 100644
--- a/Lib/r/rtype.swg
+++ b/Lib/r/rtype.swg
@@ -152,19 +152,26 @@
 %typemap(scoerceout) SEXP %{ %}
 
 %typemap(scoerceout) SWIGTYPE
-  %{ $result <- new("$&R_class", ref=$result); %}
+  %{ $result <- if (is.null($result)) $result
+  else new("$&R_class", ref=$result); %}
  
 %typemap(scoerceout) SWIGTYPE &
-  %{ $result <- new("$R_class", ref=$result) ; %}
+  %{ $result <- if (is.null($result)) $result
+  else new("$R_class", ref=$result); %}
+
  
 %typemap(scoerceout) SWIGTYPE &&
-  %{ $result <- new("$R_class", ref=$result) ; %}
+  %{ $result <- if (is.null($result)) $result
+  else new("$R_class", ref=$result); %}
  
 %typemap(scoerceout) SWIGTYPE *
-  %{ $result <- new("$R_class", ref=$result) ; %}
+  %{ $result <- if (is.null($result)) $result
+  else new("$R_class", ref=$result); %}
+
  
 %typemap(scoerceout) SWIGTYPE *const
-  %{ $result <- new("$R_class", ref=$result) ; %}
+  %{ $result <- if (is.null($result)) $result
+  else new("$R_class", ref=$result); %}
 
 
 /* Override the SWIGTYPE * above. */
diff --git a/Lib/ruby/rubytracking.swg b/Lib/ruby/rubytracking.swg
index 8f9f01b..b9fb249 100644
--- a/Lib/ruby/rubytracking.swg
+++ b/Lib/ruby/rubytracking.swg
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------------
  * rubytracking.swg
  *
- * This file contains support for tracking mappings from 
+ * This file contains support for tracking mappings from
  * Ruby objects to C++ objects.  This functionality is needed
  * to implement mark functions for Ruby's mark and sweep
  * garbage collector.
@@ -28,7 +28,7 @@
 #endif
 
 /* Global hash table to store Trackings from C/C++
-   structs to Ruby Objects. 
+   structs to Ruby Objects.
 */
 static st_table* swig_ruby_trackings = NULL;
 
@@ -42,7 +42,7 @@
   /* Create a hash table to store Trackings from C++
      objects to Ruby objects. */
 
-  /* Try to see if some other .so has already created a 
+  /* Try to see if some other .so has already created a
      tracking hash table, which we keep hidden in an instance var
      in the SWIG module.
      This is done to allow multiple DSOs to share the same
@@ -101,13 +101,14 @@
 
 /* This is a helper method that unlinks a Ruby object from its
    underlying C++ object.  This is needed if the lifetime of the
-   Ruby object is longer than the C++ object */
+   Ruby object is longer than the C++ object. */
 SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) {
   VALUE object = SWIG_RubyInstanceFor(ptr);
 
   if (object != Qnil) {
-    if (TYPE(object) != T_DATA)
-      abort();
+    // object might have the T_ZOMBIE type, but that's just
+    // because the GC has flagged it as such for a deferred
+    // destruction. Until then, it's still a T_DATA object.
     DATA_PTR(object) = 0;
   }
 }
diff --git a/Lib/ruby/std_basic_string.i b/Lib/ruby/std_basic_string.i
index 4435b22..ba13ba7 100644
--- a/Lib/ruby/std_basic_string.i
+++ b/Lib/ruby/std_basic_string.i
@@ -13,36 +13,30 @@
 %fragment(SWIG_AsPtr_frag(std::basic_string<char>),"header",
 	  fragment="SWIG_AsCharPtrAndSize") {
 SWIGINTERN int
-SWIG_AsPtr(std::basic_string<char>)(VALUE obj, std::string **val)
-{
-  static swig_type_info* string_info = 
-    SWIG_TypeQuery("std::basic_string<char> *");
-  std::string *vptr;    
-  if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
+SWIG_AsPtr(std::basic_string<char>)(VALUE obj, std::string **val) {
+  static swig_type_info* string_info = SWIG_TypeQuery("std::basic_string<char> *");
+  std::string *vptr;
+  if (SWIG_IsOK(SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0))) {
     if (val) *val = vptr;
     return SWIG_OLDOBJ;
   } else {
     char* buf = 0 ; size_t size = 0; int alloc = 0;
-    if (SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
+    if (SWIG_IsOK(SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc))) {
       if (buf) {
 	if (val) *val = new std::string(buf, size - 1);
 	if (alloc == SWIG_NEWOBJ) %delete_array(buf);
 	return SWIG_NEWOBJ;
       }
     }
-    if (val) {
-      rb_raise( rb_eTypeError, "a string is expected");
-    }
-    return 0;
+    return SWIG_ERROR;
   }
-}  
+}
 }
 
 %fragment(SWIG_From_frag(std::basic_string<char>),"header",
 	  fragment="SWIG_FromCharPtrAndSize") {
 SWIGINTERNINLINE VALUE
-  SWIG_From(std::basic_string<char>)(const std::string& s)
-  {
+  SWIG_From(std::basic_string<char>)(const std::string& s) {
     return SWIG_FromCharPtrAndSize(s.data(), s.size());
   }
 }
@@ -65,36 +59,30 @@
 %fragment(SWIG_AsPtr_frag(std::basic_string<wchar_t>),"header",
 	  fragment="SWIG_AsWCharPtrAndSize") {
 SWIGINTERN int
-  SWIG_AsPtr(std::basic_string<wchar_t>)(VALUE obj, std::wstring **val)
-  {
-    static swig_type_info* string_info = 
-      SWIG_TypeQuery("std::basic_string<wchar_t> *");
-    std::wstring *vptr;    
-    if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
-      if (val) *val = vptr;
-      return SWIG_OLDOBJ;
-    } else {
-      wchar_t *buf = 0 ; size_t size = 0; int alloc = 0;
-      if (SWIG_AsWCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
-	if (buf) {
-	  if (val) *val = new std::wstring(buf, size - 1);
-	  if (alloc == SWIG_NEWOBJ) %delete_array(buf);
-	  return SWIG_NEWOBJ;
-	}
+SWIG_AsPtr(std::basic_string<wchar_t>)(VALUE obj, std::wstring **val) {
+  static swig_type_info* string_info = SWIG_TypeQuery("std::basic_string<wchar_t> *");
+  std::wstring *vptr;
+  if (SWIG_IsOK(SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0))) {
+    if (val) *val = vptr;
+    return SWIG_OLDOBJ;
+  } else {
+    wchar_t *buf = 0 ; size_t size = 0; int alloc = 0;
+    if (SWIG_IsOK(SWIG_AsWCharPtrAndSize(obj, &buf, &size, &alloc))) {
+      if (buf) {
+        if (val) *val = new std::wstring(buf, size - 1);
+        if (alloc == SWIG_NEWOBJ) %delete_array(buf);
+        return SWIG_NEWOBJ;
       }
-      if (val) {
-	rb_raise( rb_eTypeError, "a string is expected");
-      }
-      return 0;
     }
+    return SWIG_ERROR;
   }
 }
+}
 
 %fragment(SWIG_From_frag(std::basic_string<wchar_t>),"header",
 	  fragment="SWIG_FromWCharPtrAndSize") {
 SWIGINTERNINLINE VALUE
-  SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s)
-  {
+  SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s) {
     return SWIG_FromWCharPtrAndSize(s.data(), s.size());
   }
 }
diff --git a/Lib/scilab/std_basic_string.i b/Lib/scilab/std_basic_string.i
index 43b660d..b573538 100644
--- a/Lib/scilab/std_basic_string.i
+++ b/Lib/scilab/std_basic_string.i
@@ -21,8 +21,7 @@
         delete[] buf;
       }
       return SWIG_NEWOBJ;
-    }
-    else {
+    } else {
       if (_pstValue) {
         *_pstValue = NULL;
       }
diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg
index be68421..723dc08 100644
--- a/Lib/typemaps/swigtype.swg
+++ b/Lib/typemaps/swigtype.swg
@@ -431,6 +431,7 @@
 }
 
 /* directorout */
+
 #if defined(__cplusplus) && defined(%implicitconv_flag)
 %typemap(directorout,noblock=1,implicitconv=1) SWIGTYPE (void * swig_argp, int swig_res = 0) {
   swig_res = SWIG_ConvertPtr($input,&swig_argp,$&descriptor, %convertptr_flags | %implicitconv_flag);
@@ -471,8 +472,9 @@
   if (!SWIG_IsOK(swig_res)) {
     %dirout_fail(swig_res,"$type");
   }
-  $result = %reinterpret_cast(&swig_argp, $ltype);
-  swig_acquire_ownership_obj(%as_voidptr(*$result), own /* & TODO: SWIG_POINTER_OWN */);
+  $1_ltype swig_temp = new $*1_ltype(($*1_ltype)swig_argp);
+  swig_acquire_ownership(swig_temp);
+  $result = swig_temp;
 }
 %typemap(directorfree,noblock=1,match="directorout") SWIGTYPE *const& {
   if (director) {
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 857cecd..0c8d95e 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1604,7 +1604,7 @@
 %type <type>     type rawtype type_right anon_bitfield_type decltype ;
 %type <bases>    base_list inherit raw_inherit;
 %type <dtype>    definetype def_args etype default_delete deleted_definition explicit_default;
-%type <dtype>    expr exprnum exprcompound valexpr;
+%type <dtype>    expr exprnum exprcompound valexpr exprmem;
 %type <id>       ename ;
 %type <id>       less_valparms_greater;
 %type <str>      type_qualifier;
@@ -6266,7 +6266,33 @@
                }
 	       ;
 
-valexpr        : exprnum { $$ = $1; }
+/* simple member access expressions */
+exprmem        : ID ARROW ID {
+		 $$.val = NewStringf("%s->%s", $1, $3);
+		 $$.type = 0;
+	       }
+	       | exprmem ARROW ID {
+		 $$ = $1;
+		 Printf($$.val, "->%s", $3);
+	       }
+/* This generates a shift-reduce
+	       | ID PERIOD ID {
+		 $$.val = NewStringf("%s.%s", $1, $3);
+		 $$.type = 0;
+	       }
+*/
+	       | exprmem PERIOD ID {
+		 $$ = $1;
+		 Printf($$.val, ".%s", $3);
+	       }
+	       ;
+
+valexpr        : exprnum {
+		    $$ = $1;
+               }
+               | exprmem {
+		    $$ = $1;
+               }
                | string {
 		    $$.val = $1;
                     $$.type = T_STRING;
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
index c1ba075..43f87db 100644
--- a/Source/Modules/emit.cxx
+++ b/Source/Modules/emit.cxx
@@ -483,29 +483,29 @@
   if (catchlist) {
     int unknown_catch = 0;
     int has_varargs = 0;
-    Printf(eaction, "} ");
+    Printf(eaction, "}");
     for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) {
       String *em = Swig_typemap_lookup("throws", ep, "_e", 0);
       if (em) {
         SwigType *et = Getattr(ep, "type");
         SwigType *etr = SwigType_typedef_resolve_all(et);
         if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) {
-          Printf(eaction, "catch(%s) {", SwigType_str(et, "_e"));
+          Printf(eaction, " catch(%s) {", SwigType_str(et, "_e"));
         } else if (SwigType_isvarargs(etr)) {
-          Printf(eaction, "catch(...) {");
+          Printf(eaction, " catch(...) {");
           has_varargs = 1;
         } else {
-          Printf(eaction, "catch(%s) {", SwigType_str(et, "&_e"));
+          Printf(eaction, " catch(%s) {", SwigType_str(et, "&_e"));
         }
         Printv(eaction, em, "\n", NIL);
-        Printf(eaction, "}\n");
+        Printf(eaction, "}");
       } else {
 	Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), "No 'throws' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep, "type"), 0));
         unknown_catch = 1;
       }
     }
     if (unknown_catch && !has_varargs) {
-      Printf(eaction, "catch(...) { throw; }\n");
+      Printf(eaction, " catch(...) {\nthrow;\n}");
     }
   }
 
diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx
index 896872d..572985a 100644
--- a/Source/Modules/go.cxx
+++ b/Source/Modules/go.cxx
@@ -615,6 +615,12 @@
 
     Language::top(n);
 
+    if (directorsEnabled()) {
+      // Insert director runtime into the f_runtime file (make it occur before %header section)
+      Swig_insert_file("director_common.swg", f_c_runtime);
+      Swig_insert_file("director.swg", f_c_runtime);
+    }
+
     Delete(go_imports);
 
     // Write out definitions for the types not defined by SWIG.
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index 68f1bb2..d2b2542 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -2544,8 +2544,6 @@
 
     Printf(imcall, ")");
     Printf(function_code, ")");
-    if (is_interface)
-      Printf(interface_class_code, ");\n");
 
     // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class)
     if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {
@@ -2603,6 +2601,11 @@
       Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
     }
 
+    if (is_interface) {
+      Printf(interface_class_code, ")");
+      generateThrowsClause(n, interface_class_code);
+      Printf(interface_class_code, ";\n");
+    }
     generateThrowsClause(n, function_code);
     Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
     Printv(proxy_class_code, function_code, NIL);
@@ -4463,8 +4466,8 @@
     if (!directorexcept) {
       directorexcept = NewString("");
       Printf(directorexcept, "jthrowable $error = jenv->ExceptionOccurred();\n");
-      Printf(directorexcept, "if ($error) {\n");
-      Printf(directorexcept, "  jenv->ExceptionClear();$directorthrowshandlers\n");
+      Printf(directorexcept, "if ($error) {");
+      Printf(directorexcept, "$directorthrowshandlers\n");
       Printf(directorexcept, "  Swig::DirectorException::raise(jenv, $error);\n");
       Printf(directorexcept, "}\n");
     } else {
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
index 1e4a6bd..3464d23 100644
--- a/Source/Modules/lang.cxx
+++ b/Source/Modules/lang.cxx
@@ -3296,6 +3296,14 @@
 	break;
       if (Strcmp(nodeType(n), "class") == 0)
 	break;
+      Node *sibling = n;
+      while (sibling) {
+       sibling = Getattr(sibling, "csym:nextSibling");
+       if (sibling && Strcmp(nodeType(sibling), "class") == 0)
+         break;
+      }
+      if (sibling)
+       break;
       n = parentNode(n);
       if (!n)
 	break;
diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx
index d49da69..be586b4 100644
--- a/Source/Modules/perl5.cxx
+++ b/Source/Modules/perl5.cxx
@@ -900,6 +900,15 @@
       Printf(f->code, "%s\n", tm);
     }
 
+    if (director_method) {
+      if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) {
+	Replaceall(tm, "$input", Swig_cresult_name());
+	Replaceall(tm, "$result", "ST(argvi)");
+	Printf(f->code, "%s\n", tm);
+	Delete(tm);
+      }
+    }
+
     Printv(f->code, "XSRETURN(argvi);\n", "fail:\n", cleanup, "SWIG_croak_null();\n" "}\n" "}\n", NIL);
 
     /* Add the dXSARGS last */
@@ -2129,27 +2138,26 @@
      * if the return value is a reference or const reference, a specialized typemap must
      * handle it, including declaration of c_result ($result).
      */
-    if (!is_void) {
-      if (!ignored_method || pure_virtual) {
-	if (!SwigType_isclass(returntype)) {
-	  if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
-	    String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
-	    Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
-	    Delete(construct_result);
-	  } else {
-	    Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
-	  }
+    if (!is_void && (!ignored_method || pure_virtual)) {
+      if (!SwigType_isclass(returntype)) {
+	if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
+	  String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
+	  Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
+	  Delete(construct_result);
 	} else {
-	  String *cres = SwigType_lstr(returntype, "c_result");
-	  Printf(w->code, "%s;\n", cres);
-	  Delete(cres);
+	  Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
 	}
+      } else {
+	String *cres = SwigType_lstr(returntype, "c_result");
+	Printf(w->code, "%s;\n", cres);
+	Delete(cres);
       }
-      if (!ignored_method) {
-	String *pres = NewStringf("SV *%s", Swig_cresult_name());
-	Wrapper_add_local(w, Swig_cresult_name(), pres);
-	Delete(pres);
-      }
+    }
+
+    if (!is_void && !ignored_method) {
+      String *pres = NewStringf("SV *%s", Swig_cresult_name());
+      Wrapper_add_local(w, Swig_cresult_name(), pres);
+      Delete(pres);
     }
 
     if (ignored_method) {
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index dcfe4e3..b32f3c6 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -372,8 +372,8 @@
     Printf(s_header, "int error_code;\n");
     Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
     Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
-    Printf(s_header, "#define SWIG_ErrorMsg() (%s_globals.error_msg)\n", module);
-    Printf(s_header, "#define SWIG_ErrorCode() (%s_globals.error_code)\n", module);
+    Printf(s_header, "#define SWIG_ErrorMsg() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_msg)\n", module);
+    Printf(s_header, "#define SWIG_ErrorCode() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_code)\n", module);
 
     /* The following can't go in Lib/php/phprun.swg as it uses SWIG_ErrorMsg(), etc
      * which has to be dynamically generated as it depends on the module name.
diff --git a/Tools/travis-linux-install.sh b/Tools/travis-linux-install.sh
index 5704c4c..e8a5e4c 100755
--- a/Tools/travis-linux-install.sh
+++ b/Tools/travis-linux-install.sh
@@ -89,13 +89,13 @@
 		travis_retry sudo apt-get -qq install php$VER-cli php$VER-dev
 		;;
 	"python")
-		pip install --user pep8
+		pip install --user pycodestyle
 		if [[ "$PY3" ]]; then
 			travis_retry sudo apt-get install -qq python3-dev
 		fi
 		WITHLANG=$SWIGLANG$PY3
 		if [[ "$VER" ]]; then
-			travis_retry sudo add-apt-repository -y ppa:fkrull/deadsnakes
+			travis_retry sudo add-apt-repository -y ppa:deadsnakes/ppa
 			travis_retry sudo apt-get -qq update
 			travis_retry sudo apt-get -qq install python${VER}-dev
 			WITHLANG=$SWIGLANG$PY3=$SWIGLANG$VER
diff --git a/configure.ac b/configure.ac
index 85b24e7..cfc3381 100644
--- a/configure.ac
+++ b/configure.ac
@@ -895,11 +895,11 @@
 fi
 
 if test -n "$PYINCLUDE" || test -n "$PY3INCLUDE" ; then
-  AC_CHECK_PROGS(PEP8, pep8)
-  if test -n "$PEP8"; then
-    AC_MSG_CHECKING(pep8 version)
-    pep8_version=`$PEP8 --version 2>/dev/null`
-    AC_MSG_RESULT($pep8_version)
+  AC_CHECK_PROGS(PYCODESTYLE, pycodestyle)
+  if test -n "$PYCODESTYLE"; then
+    AC_MSG_CHECKING(pycodestyle version)
+    pycodestyle_version=`$PYCODESTYLE --version 2>/dev/null`
+    AC_MSG_RESULT($pycodestyle_version)
   fi
 fi