Merge branch 'master' of https://github.com/Liryna/swig into Liryna-master

* 'master' of https://github.com/Liryna/swig:
  [C#] Add ToArray to std_vector.i
diff --git a/CHANGES b/CHANGES
index 8376c0b..d18a11b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -11813,7 +11813,7 @@
            ie, no additional pointer elements are created, and
 	   the original 'foo' and 'A.bar' can be used as parameters.
 
-	   In the case of member fucntion however, still you need
+	   In the case of member function however, still you need
 	   to use the special variable Class::<fnc_name>_cb_ptr, ie:
 
  	     foobarm(3, a, A.barm_cb_ptr)
diff --git a/CHANGES.current b/CHANGES.current
index ac08d2b..0aad216 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -6,6 +6,66 @@
 
 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.
+
+2017-10-26: wsfulton
+            Fix generated code when using directors and methods returning const ref pointers.
+
+2017-10-26: wsfulton
+            [C#, D, Java, Octave, R, Scilab] Port director typemaps to these additional languages.
+            Issue #700.
+
+2017-10-26: radarsat1
+            [Ruby Python] Patch #1029 - Correct handling of null using directors and shared_ptr.
+
 2017-10-10: joequant
 	    [R] pass enum expressions to R.  This will generate
 	    incorrect files when there is an arithmetic expression
diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html
index 70010c9..13b6e49 100644
--- a/Doc/Manual/CSharp.html
+++ b/Doc/Manual/CSharp.html
@@ -2019,37 +2019,50 @@
   // Ensure that the GC doesn't collect any Element set from C#
   // as the underlying C++ class stores a shallow copy
   private Element elementReference;
-  private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) {
-    elementReference = element;
-    return Element.getCPtr(element);
-  }
 
   public void setElement(Element e) {
-    examplePINVOKE.Container_setElement(swigCPtr, getCPtrAndAddReference(e));
+    examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
+    elementReference = e;
   }
 }
 </pre>
 </div>
 
 <p>
-The following typemaps will generate the desired code.
-The 'csin' typemap matches the input parameter type for the <tt>setElement</tt> method.
-The 'cscode' typemap simply adds in the specified code into the C# proxy class.
+The following typemaps can be used to generate this code:
 </p>
 
 <div class="code">
 <pre>
-%typemap(csin) Element *e "getCPtrAndAddReference($csinput)"
-
 %typemap(cscode) Container %{
   // Ensure that the GC doesn't collect any Element set from C#
   // as the underlying C++ class stores a shallow copy
   private Element elementReference;
-  private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) {
-    elementReference = element;
-    return Element.getCPtr(element);
-  }
 %}
+
+%typemap(csin,
+         post="      elementReference = $csinput;"
+         ) Element *e "Element.getCPtr($csinput)"
+</pre>
+</div>
+
+<p>
+The 'cscode' typemap simply adds in the specified code into the C# proxy class.
+The 'csin' typemap matches the input parameter type and name for the <tt>setElement</tt> method and
+the 'post' typemap attribute allows adding code after the PInvoke call.
+The 'post' code is generated into a finally block after the PInvoke call so the resulting code isn't quite
+as mentioned earlier, <tt>setElement</tt> is actually:
+</p>
+
+<div class="code">
+<pre>
+  public void setElement(Element e) {
+    try {
+      examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
+    } finally {
+      elementReference = e;
+    }
+  }
 </pre>
 </div>
 
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 25f633c..5cc796c 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -269,6 +269,11 @@
 <li><a href="SWIGPlus.html#SWIGPlus_nn35">Using declarations and inheritance</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a>
 <li><a href="SWIGPlus.html#SWIGPlus_const">A brief rant about const-correctness</a>
+<li><a href="SWIGPlus.html#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>
+<ul>
+<li><a href="SWIGPlus.html#SWIGPlus_director_classes_introduction">Introduction to director classes</a>
+<li><a href="SWIGPlus.html#SWIGPlus_directors_for_function_pointers">Using directors and target language callbacks</a>
+</ul>
 <li><a href="SWIGPlus.html#SWIGPlus_nn42">Where to go for more information</a>
 </ul>
 </div>
@@ -479,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>
@@ -1031,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/Library.html b/Doc/Manual/Library.html
index d4fedd0..8a90539 100644
--- a/Doc/Manual/Library.html
+++ b/Doc/Manual/Library.html
@@ -420,11 +420,11 @@
 
 <div class="targetlang">
 <pre>
-a = new_doubleArray(10)             # Create an array
+a = new_doubleArray(10)               # Create an array
 for i in range(0, 10):
-    doubleArray_setitem(a, i, 2*i)  # Set a value
-print_array(a)                      # Pass to C
-delete_doubleArray(a)               # Destroy array
+    doubleArray_setitem(a, i, 2 * i)  # Set a value
+print_array(a)                        # Pass to C
+delete_doubleArray(a)                 # Destroy array
 </pre>
 </div>
 
@@ -487,7 +487,7 @@
 import example
 c = example.doubleArray(10)  # Create double[10]
 for i in range(0, 10):
-    c[i] = 2*i               # Assign values
+    c[i] = 2 * i             # Assign values
 example.print_array(c)       # Pass to C
 </pre>
 </div>
@@ -503,6 +503,7 @@
 <p>
 <b>Note:</b> <tt>%array_functions()</tt> and <tt>%array_class()</tt> should not be
 used with types of <tt>char</tt> or <tt>char *</tt>.
+SWIG's default handling of these types is to handle them as character strings and the two macros do not do enough to change this.
 </p>
 
 <H3><a name="Library_nn6">9.2.3 cmalloc.i</a></H3>
@@ -1475,7 +1476,7 @@
 <div class="targetlang">
 <pre>
 x = my_struct();
-x.foo="Hello World";      # assign with string
+x.foo = "Hello World";    # assign with string
 print x.foo;              # print as string
 </pre>
 </div>
@@ -1990,9 +1991,7 @@
 
 
 <p>
-There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
-and the degrees of success varies among the different target languages.
-Please help to improve this support by providing patches with improvements.
+The languages that support shared_ptr also have support for using shared_ptr with directors.
 </p>
 
 
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/SWIG.html b/Doc/Manual/SWIG.html
index d677a22..f6a62d5 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -2177,7 +2177,7 @@
 <p>
 Occasionally, a C library may include functions that expect to receive
 pointers to functions--possibly to serve as callbacks. SWIG
-provides full support for function pointers provided that the callback
+provides full support for function pointers when the callback
 functions are defined in C and not in the target language.  For example,
 consider a function like this:
 </p>
@@ -2321,7 +2321,9 @@
 does not normally allow callback functions to be written in the target language, this
 can be accomplished with the use of typemaps and other advanced SWIG features.
 See the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more about typemaps
-and individual target language chapters for more on callbacks and the 'director' feature.
+and individual target language chapters for more on callbacks.
+The 'director' feature can be used to make callbacks from C/C++ into the target language,
+see <a href="SWIGPlus.html#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>.
 </p>
 
 <H2><a name="SWIG_nn31">5.5 Structures and unions</a></H2>
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index 18059b4..5eac552 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -72,6 +72,11 @@
 <li><a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
 <li><a href="#SWIGPlus_nested_classes">Nested classes</a>
 <li><a href="#SWIGPlus_const">A brief rant about const-correctness</a>
+<li><a href="#SWIGPlus_target_language_callbacks">Callbacks to the target language</a>
+<ul>
+<li><a href="#SWIGPlus_director_classes_introduction">Introduction to director classes</a>
+<li><a href="#SWIGPlus_directors_for_function_pointers">Using directors and target language callbacks</a>
+</ul>
 <li><a href="#SWIGPlus_nn42">Where to go for more information</a>
 </ul>
 </div>
@@ -80,7 +85,10 @@
 
 
 <p>
-This chapter describes SWIG's support for wrapping C++.  As a prerequisite,
+This chapter describes SWIG's support for wrapping C++.
+It is mostly concerned about C++ as defined by the C++ 98 and 03 standards.
+For C++ 11 features please read the <a href="CPlusPlus11.html">SWIG and C++11</a> chapter.
+As a prerequisite,
 you should first read the chapter <a href="SWIG.html#SWIG">SWIG Basics</a> to see
 how SWIG wraps ANSI C.  Support for C++ builds upon ANSI C
 wrapping and that material will be useful in understanding this chapter.
@@ -4622,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 "...".
@@ -5385,7 +5393,152 @@
 of your project.
 </p>
 
-<H2><a name="SWIGPlus_nn42">6.29 Where to go for more information</a></H2>
+<H2><a name="SWIGPlus_target_language_callbacks">6.29 Callbacks to the target language</a></H2>
+
+
+<p>
+C/C++ function pointers are often used for callbacks and this is discussed in the 
+<a href="SWIG.html#SWIG_nn30">Pointers to functions and callbacks</a> section.
+The callback techniques described therein provide a way to control callbacks to a C/C++ function but not callbacks into the target language.
+The techniques described below show how the director feature can be used to support callbacks from C/C++ to the target language.
+</p>
+
+<H3><a name="SWIGPlus_director_classes_introduction">6.29.1 Introduction to director classes</a></H3>
+
+
+<p>
+The director feature enables the ability for a target language class to derive from a wrapped C++ class.
+The target language can override virtual methods of a wrapped C++ class, thereby supporting cross-language polymorphism.
+Code can 'call up' from C++ into the target language by simply calling a virtual method overridden in a derived class in the target language.
+The wrapped C++ classes that have this ability are termed 'director' classes.
+The director feature is documented individually in each target language and the reader should locate and read this to obtain a full understanding of directors.
+</p>
+
+<H3><a name="SWIGPlus_directors_for_function_pointers">6.29.2 Using directors and target language callbacks</a></H3>
+
+
+<p>
+SWIG's primary goal is to make it possible to call C/C++ code from a target language, however, the director feature enables the reverse.
+While there isn't simple direct support for calling target language code from C, the director feature makes this possible.
+It does require some work and additional wrapper code to be provided by the user.
+The additional code required must be C++ and not C code and hence may introduce a small dependency on C++ if using a pure C project.
+In a nutshell, the user must create a C++ base class and turn it into a director class.
+A virtual method in the director base class is required.
+SWIG generates the code to call up into the target language when wrapping the director virtual method.
+</p>
+
+<p>
+Let's look at some details next.
+Consider the same function pointer for a callback called <tt>binary_op</tt> from the
+<a href="SWIG.html#SWIG_nn30">Pointers to functions and callbacks</a> section.
+For completeness, the code required for the module and director feature is also shown:
+</p>
+
+<div class="code"><pre>
+%module(directors="1") example
+
+%{
+int binary_op(int a, int b, int (*op)(int, int)) {
+  return op(a, b);
+}
+%}
+</pre></div>
+
+<p>
+The goal is to have a target language function that gets called by <tt>binary_op</tt>.
+The target language function should have the equivalent signature as the C/C++ function pointer <tt>int (*op)(int, int)</tt>.
+As we are using directors, we need a C++ virtual method with this signature, so let's
+define the C++ class and pure virtual method first and make it a director class via the
+director feature:
+</p>
+
+<div class="code"><pre>
+%feature("director") BinaryOp;
+
+%inline %{
+struct BinaryOp {
+  virtual int handle(int a, int b) = 0;
+  virtual ~BinaryOp() {}
+};
+%}
+</pre></div>
+
+<p>
+The following <tt>handler_helper</tt> function and <tt>binary_op_wrapper</tt> function completes the code needed in the
+C++/SWIG layer. The <tt>binary_op_wrapper</tt> function is wrapped by SWIG and is very similar to the <tt>binary_op</tt> function,
+however, it takes a pointer to the director base class <tt>BinaryOp</tt> instead of a C/C++ function pointer.
+</p>
+
+<div class="code"><pre>
+%{
+static BinaryOp *handler_ptr = NULL;
+static int handler_helper(int a, int b) {
+  // Make the call up to the target language when handler_ptr
+  // is an instance of a target language director class
+  return handler_ptr-&gt;handle(a, b);
+}
+// If desired, handler_ptr above could be changed to a thread-local variable in order to make thread-safe
+%}
+
+%inline %{
+int binary_op_wrapper(int a, int b, BinaryOp *handler) {
+  handler_ptr = handler;
+  int result = binary_op(a, b, &amp;handler_helper);
+  handler = NULL;
+  return result;
+}
+%}
+</pre></div>
+
+<p>
+On the target language side, we need to derive a class from <tt>BinaryOp</tt> and override the
+<tt>handle</tt> method. In Python this could be as simple as:
+</p>
+
+<div class="targetlang">
+<pre>
+import example
+
+# PythonBinaryOp class is defined and derived from C++ class BinaryOp
+class PythonBinaryOp(example.BinaryOp):
+
+    # Define Python class 'constructor'
+    def __init__(self):
+        # Call C++ base class constructor
+        example.BinaryOp.__init__(self)
+
+    # Override C++ method: virtual int handle(int a, int b) = 0;
+    def handle(self, a, b):
+        # Return the product
+        return a * b
+</pre>
+</div>
+
+<p>
+For this to work from Python, an instance of the <tt>PythonBinaryOp</tt> class is created
+and then passed to <tt>binary_op_wrapper</tt>. The net result is the <tt>binary_op</tt>
+function will in turn be called which will call <tt>handler_helper</tt> which will call
+the virtual <tt>handle</tt> method, that is, the Python method <tt>handle</tt> in the PythonBinaryOp class. The result will be the product of 10 and 20 and make its way back to Python and hence
+200 will be printed with the following code:
+</p>
+
+<div class="targetlang">
+<pre>
+handler = PythonBinaryOp()
+result = example.binary_op_wrapper(10, 20, handler)
+print result
+</pre>
+</div>
+
+<p>
+This has thus demonstrated a C/C++ function pointer calling back into a target language function.
+The code could be made a little more user friendly by using <tt>%rename</tt> to provide the
+original <tt>binary_op</tt> name from the target language instead of <tt>binary_op_wrapper</tt>.
+A C++ functor base class and Python functor class
+could also be used instead, but these are left as exercises for the reader.
+</p>
+
+<H2><a name="SWIGPlus_nn42">6.30 Where to go for more information</a></H2>
 
 
 <p>
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 07937ac..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 \
@@ -263,9 +265,10 @@
 	li_attribute \
 	li_attribute_template \
 	li_boost_shared_ptr \
-	li_boost_shared_ptr_bits \
-	li_boost_shared_ptr_template \
 	li_boost_shared_ptr_attribute \
+	li_boost_shared_ptr_bits \
+	li_boost_shared_ptr_director \
+	li_boost_shared_ptr_template \
 	li_carrays_cpp \
 	li_cdata_cpp \
 	li_cpointer_cpp \
@@ -488,6 +491,7 @@
 	throw_exception \
 	typedef_array_member \
 	typedef_class \
+	typedef_classforward_same_name \
 	typedef_funcptr \
 	typedef_inherit \
 	typedef_mptr \
@@ -674,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/cpp11_directors.i b/Examples/test-suite/cpp11_directors.i
index 4462c1d..3d1fbea 100644
--- a/Examples/test-suite/cpp11_directors.i
+++ b/Examples/test-suite/cpp11_directors.i
@@ -1,20 +1,16 @@
 %module(directors="1") cpp11_directors
 %feature("director");
 
-%{
+%inline %{
 
 class Foo {
   public:
     virtual ~Foo() noexcept {}
     virtual int ping() noexcept = 0;
     virtual int pong() noexcept = 0;
+    virtual int pang() const& noexcept = 0;
+    virtual int peng() & noexcept = 0;
+    virtual int pung() & = 0;
 };
 
 %}
-
-class Foo {
-  public:
-    virtual ~Foo() noexcept {}
-    virtual int ping() noexcept = 0;
-    virtual int pong() noexcept = 0;
-};
\ No newline at end of file
diff --git a/Examples/test-suite/csharp/director_classes_runme.cs b/Examples/test-suite/csharp/director_classes_runme.cs
index 1125614..700492f 100644
--- a/Examples/test-suite/csharp/director_classes_runme.cs
+++ b/Examples/test-suite/csharp/director_classes_runme.cs
@@ -16,6 +16,7 @@
 Base - Val(444.555)
 Base - Ref(444.555)
 Base - Ptr(444.555)
+Base - ConstPtrRef(444.555)
 Base - FullyOverloaded(int 10)
 Base - FullyOverloaded(bool 1)
 Base - SemiOverloaded(int -678)
@@ -26,6 +27,7 @@
 Derived - Val(444.555)
 Derived - Ref(444.555)
 Derived - Ptr(444.555)
+Derived - ConstPtrRef(444.555)
 Derived - FullyOverloaded(int 10)
 Derived - FullyOverloaded(bool 1)
 Derived - SemiOverloaded(int -678)
@@ -36,6 +38,7 @@
 CSharpDerived - Val(444.555)
 CSharpDerived - Ref(444.555)
 CSharpDerived - Ptr(444.555)
+CSharpDerived - ConstPtrRef(444.555)
 CSharpDerived - FullyOverloaded(int 10)
 CSharpDerived - FullyOverloaded(bool True)
 CSharpDerived - SemiOverloaded(-678)
@@ -59,7 +62,7 @@
 
   void run()
   {
-    if (director_classes.PrintDebug) Console.WriteLine("------------ Start ------------ ");
+    if (director_classes.PrintDebug) Console.WriteLine("------------ Start ------------");
 
     Caller myCaller = new Caller();
 
@@ -85,7 +88,7 @@
       makeCalls(myCaller, myBase);
     }
 
-    if (director_classes.PrintDebug) Console.WriteLine("------------ Finish ------------ ");
+    if (director_classes.PrintDebug) Console.WriteLine("------------ Finish ------------");
   }
 
   void makeCalls(Caller myCaller, Base myBase)
@@ -99,6 +102,7 @@
     if (myCaller.ValCall(dh).val != dh.val) throw new Exception("failed");
     if (myCaller.RefCall(dh).val != dh.val) throw new Exception("failed");
     if (myCaller.PtrCall(dh).val != dh.val) throw new Exception("failed");
+    if (myCaller.ConstPtrRefCall(dh).val != dh.val) throw new Exception("failed");
 
     // Fully overloaded method test (all methods in base class are overloaded)
     if (NAMESPACE + myCaller.FullyOverloadedCall(10) != myBase.GetType() + "::FullyOverloaded(int)") throw new Exception("failed");
@@ -142,6 +146,11 @@
     if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - Ptr({0})", x.val);
     return x;
   }
+  public override DoubleHolder ConstPtrRef(DoubleHolder x)
+  {
+    if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - ConstPtrRef({0})", x.val);
+    return x;
+  }
   public override String FullyOverloaded(int x)
   {
     if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - FullyOverloaded(int {0})", x);
diff --git a/Examples/test-suite/csharp/li_boost_shared_ptr_director_runme.cs b/Examples/test-suite/csharp/li_boost_shared_ptr_director_runme.cs
new file mode 100644
index 0000000..0a03b7f
--- /dev/null
+++ b/Examples/test-suite/csharp/li_boost_shared_ptr_director_runme.cs
@@ -0,0 +1,111 @@
+using System;
+using li_boost_shared_ptr_directorNamespace;
+
+public class li_boost_shared_ptr_director_runme {
+
+  private static void check(int got, int expected) {
+    if (got != expected)
+      throw new Exception("Failed, got: " + got + " expected: " + expected);
+  }
+
+  public static void Main() {
+    Derived a = new Derived(false);
+    Derived b = new Derived(true);
+
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a),  1);
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
+    check(li_boost_shared_ptr_director.call_ret_c_by_value(a),    1);
+
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a),  1);
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
+    check(li_boost_shared_ptr_director.call_ret_c_by_value(a),    1);
+
+    check(li_boost_shared_ptr_director.call_take_c_by_value(a),                  5);
+    check(li_boost_shared_ptr_director.call_take_c_by_ref(a),                    6);
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer(a),                7);
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref(a),            8);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value(a),       9);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref(a),         10);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer(a),     11);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref(a), 12);
+
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer_with_null(a),                -2);
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref_with_null(a),            -3);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value_with_null(a),       -4);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref_with_null(a),         -5);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_with_null(a),     -6);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7);
+  }
+
+}
+
+class Derived : Base {
+
+  private bool return_none;
+
+  public Derived(bool flag) : base() {
+    this.return_none = flag;
+  }
+
+  public override C ret_c_shared_ptr() {
+    if (this.return_none)
+      return null;
+    else
+      return new C();
+  }
+
+  public override C ret_c_by_value() {
+    return new C();
+  }
+
+  public override int take_c_by_value(C c) {
+    return c.get_m();
+  }
+
+  public override int take_c_by_ref(C c) {
+      return c.get_m();
+  }
+
+  public override int take_c_by_pointer(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -2;
+  }
+
+  public override int take_c_by_pointer_ref(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -3;
+  }
+
+  public override int take_c_shared_ptr_by_value(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -4;
+  }
+
+  public override int take_c_shared_ptr_by_ref(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -5;
+  }
+
+  public override int take_c_shared_ptr_by_pointer(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -6;
+  }
+
+  public override int take_c_shared_ptr_by_pointer_ref(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -7;
+  }
+
+}
diff --git a/Examples/test-suite/d/director_classes_runme.1.d b/Examples/test-suite/d/director_classes_runme.1.d
index 9c34db8..e753f5f 100644
--- a/Examples/test-suite/d/director_classes_runme.1.d
+++ b/Examples/test-suite/d/director_classes_runme.1.d
@@ -18,6 +18,7 @@
  * Base - Val(444.555)
  * Base - Ref(444.555)
  * Base - Ptr(444.555)
+ * Base - ConstPtrRef(444.555)
  * Base - FullyOverloaded(int 10)
  * Base - FullyOverloaded(bool 1)
  * Base - SemiOverloaded(int -678)
@@ -28,6 +29,7 @@
  * Derived - Val(444.555)
  * Derived - Ref(444.555)
  * Derived - Ptr(444.555)
+ * Derived - ConstPtrRef(444.555)
  * Derived - FullyOverloaded(int 10)
  * Derived - FullyOverloaded(bool 1)
  * Derived - SemiOverloaded(int -678)
@@ -38,6 +40,7 @@
  * DDerived - Val(444.555)
  * DDerived - Ref(444.555)
  * DDerived - Ptr(444.555)
+ * DDerived - ConstPtrRef(444.555)
  * DDerived - FullyOverloaded(int 10)
  * DDerived - FullyOverloaded(bool True)
  * DDerived - SemiOverloaded(-678)
@@ -57,7 +60,7 @@
 import director_classes.DoubleHolder;
 
 void main() {
-  if (PrintDebug) Stdout.formatln("------------ Start ------------ ");
+  if (PrintDebug) Stdout.formatln("------------ Start ------------");
 
   auto myCaller = new Caller();
 
@@ -83,7 +86,7 @@
     makeCalls(myCaller, myBase);
   }
 
-  if (PrintDebug) Stdout.formatln("------------ Finish ------------ ");
+  if (PrintDebug) Stdout.formatln("------------ Finish ------------");
 }
 
 void makeCalls(Caller myCaller, Base myBase) {
@@ -96,6 +99,7 @@
   if (myCaller.ValCall(dh).val != dh.val) throw new Exception("[1] failed");
   if (myCaller.RefCall(dh).val != dh.val) throw new Exception("[2] failed");
   if (myCaller.PtrCall(dh).val != dh.val) throw new Exception("[3] failed");
+  if (myCaller.ConstPtrRefCall(dh).val != dh.val) throw new Exception("[3] failed");
 
   // Fully overloaded method test (all methods in base class are overloaded)
   if (myCaller.FullyOverloadedCall(10) != myBaseType ~ "::FullyOverloaded(int)") throw new Exception("[4] failed");
@@ -136,6 +140,11 @@
     return x;
   }
 
+  public override DoubleHolder ConstPtrRef(DoubleHolder x) {
+    if (PrintDebug) Stdout.formatln("DDerived - ConstPtrRef({0:d3})", x.val);
+    return x;
+  }
+
   public override char[] FullyOverloaded(int x) {
     if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(int {0})", x);
     return "DDerived::FullyOverloaded(int)";
diff --git a/Examples/test-suite/d/director_classes_runme.2.d b/Examples/test-suite/d/director_classes_runme.2.d
index 98e27b3..b16fa54 100644
--- a/Examples/test-suite/d/director_classes_runme.2.d
+++ b/Examples/test-suite/d/director_classes_runme.2.d
@@ -18,6 +18,7 @@
  * Base - Val(444.555)
  * Base - Ref(444.555)
  * Base - Ptr(444.555)
+ * Base - ConstPtrRef(444.555)
  * Base - FullyOverloaded(int 10)
  * Base - FullyOverloaded(bool 1)
  * Base - SemiOverloaded(int -678)
@@ -28,6 +29,7 @@
  * Derived - Val(444.555)
  * Derived - Ref(444.555)
  * Derived - Ptr(444.555)
+ * Derived - ConstPtrRef(444.555)
  * Derived - FullyOverloaded(int 10)
  * Derived - FullyOverloaded(bool 1)
  * Derived - SemiOverloaded(int -678)
@@ -38,6 +40,7 @@
  * DDerived - Val(444.555)
  * DDerived - Ref(444.555)
  * DDerived - Ptr(444.555)
+ * DDerived - ConstPtrRef(444.555)
  * DDerived - FullyOverloaded(int 10)
  * DDerived - FullyOverloaded(bool true)
  * DDerived - SemiOverloaded(-678)
@@ -58,7 +61,7 @@
 import director_classes.DoubleHolder;
 
 void main() {
-  if (PrintDebug) writeln("------------ Start ------------ ");
+  if (PrintDebug) writeln("------------ Start ------------");
 
   auto myCaller = new Caller();
 
@@ -84,7 +87,7 @@
     makeCalls(myCaller, myBase);
   }
 
-  if (PrintDebug) writeln("------------ Finish ------------ ");
+  if (PrintDebug) writeln("------------ Finish ------------");
 }
 
 void makeCalls(Caller myCaller, Base myBase) {
@@ -97,6 +100,7 @@
   enforce(myCaller.ValCall(dh).val == dh.val, "[1] failed");
   enforce(myCaller.RefCall(dh).val == dh.val, "[2] failed");
   enforce(myCaller.PtrCall(dh).val == dh.val, "[3] failed");
+  enforce(myCaller.ConstPtrRefCall(dh).val == dh.val, "[3] failed");
 
   // Fully overloaded method test (all methods in base class are overloaded)
   enforce(myCaller.FullyOverloadedCall(10) == myBaseType ~ "::FullyOverloaded(int)", "[4] failed");
@@ -137,6 +141,11 @@
     return x;
   }
 
+  public override DoubleHolder ConstPtrRef(DoubleHolder x) {
+    if (PrintDebug) writefln("DDerived - ConstPtrRef(%s)", x.val);
+    return x;
+  }
+
   public override string FullyOverloaded(int x) {
     if (PrintDebug) writefln("DDerived - FullyOverloaded(int %s)", x);
     return "DDerived::FullyOverloaded(int)";
diff --git a/Examples/test-suite/d/li_boost_shared_ptr_director_runme.2.d b/Examples/test-suite/d/li_boost_shared_ptr_director_runme.2.d
new file mode 100644
index 0000000..fbcb03f
--- /dev/null
+++ b/Examples/test-suite/d/li_boost_shared_ptr_director_runme.2.d
@@ -0,0 +1,114 @@
+module li_boost_shared_ptr_director_runme;
+
+import std.conv;
+import std.exception;
+import std.stdio;
+import std.string;
+import li_boost_shared_ptr_director.li_boost_shared_ptr_director;
+import li_boost_shared_ptr_director.Base;
+import li_boost_shared_ptr_director.C;
+
+void check(int got, int expected) {
+  enforce(got == expected, "Failed. got: " ~ to!string(got) ~ " Expected: " ~ to!string(expected));
+}
+
+void main() {
+  Derived a = new Derived(false);
+  Derived b = new Derived(true);
+
+  check(call_ret_c_shared_ptr(a),  1);
+  check(call_ret_c_shared_ptr(b), -1);
+  check(call_ret_c_by_value(a),    1);
+
+  check(call_ret_c_shared_ptr(a),  1);
+  check(call_ret_c_shared_ptr(b), -1);
+  check(call_ret_c_by_value(a),    1);
+
+  check(call_take_c_by_value(a),                  5);
+  check(call_take_c_by_ref(a),                    6);
+  check(call_take_c_by_pointer(a),                7);
+  check(call_take_c_by_pointer_ref(a),            8);
+  check(call_take_c_shared_ptr_by_value(a),       9);
+  check(call_take_c_shared_ptr_by_ref(a),         10);
+  check(call_take_c_shared_ptr_by_pointer(a),     11);
+  check(call_take_c_shared_ptr_by_pointer_ref(a), 12);
+
+  check(call_take_c_by_pointer_with_null(a),                -2);
+  check(call_take_c_by_pointer_ref_with_null(a),            -3);
+  check(call_take_c_shared_ptr_by_value_with_null(a),       -4);
+  check(call_take_c_shared_ptr_by_ref_with_null(a),         -5);
+  check(call_take_c_shared_ptr_by_pointer_with_null(a),     -6);
+  check(call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7);
+}
+
+public class Derived : Base {
+
+  private bool return_none;
+
+  public this(bool flag) {
+    super();
+    this.return_none = flag;
+  }
+
+  public override C ret_c_shared_ptr() {
+    if (this.return_none)
+      return null;
+    else
+      return new C();
+  }
+
+  public override C ret_c_by_value() {
+    return new C();
+  }
+
+  public override int take_c_by_value(C c) {
+    return c.get_m();
+  }
+
+  public override int take_c_by_ref(C c) {
+      return c.get_m();
+  }
+
+  public override int take_c_by_pointer(C c) {
+    if (c !is null)
+      return c.get_m();
+    else
+      return -2;
+  }
+
+  public override int take_c_by_pointer_ref(C c) {
+    if (c !is null)
+      return c.get_m();
+    else
+      return -3;
+  }
+
+  public override int take_c_shared_ptr_by_value(C c) {
+    if (c !is null)
+      return c.get_m();
+    else
+      return -4;
+  }
+
+  public override int take_c_shared_ptr_by_ref(C c) {
+    if (c !is null)
+      return c.get_m();
+    else
+      return -5;
+  }
+
+  public override int take_c_shared_ptr_by_pointer(C c) {
+    if (c !is null)
+      return c.get_m();
+    else
+      return -6;
+  }
+
+  public override int take_c_shared_ptr_by_pointer_ref(C c) {
+    if (c !is null)
+      return c.get_m();
+    else
+      return -7;
+  }
+
+}
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_classes.i b/Examples/test-suite/director_classes.i
index 98c29e8..8b54d8b 100644
--- a/Examples/test-suite/director_classes.i
+++ b/Examples/test-suite/director_classes.i
@@ -3,6 +3,7 @@
 
 %warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Base::Ref;
 %warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Base::Ptr;
+%warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Base::ConstPtrRef;
 
 %module(directors="1") director_classes
 
@@ -43,6 +44,7 @@
   virtual DoubleHolder Val(DoubleHolder x) { if (PrintDebug) std::cout << "Base - Val(" << x.val << ")" << std::endl; return x; }
   virtual DoubleHolder& Ref(DoubleHolder& x) { if (PrintDebug) std::cout << "Base - Ref(" << x.val << ")" << std::endl; return x; }
   virtual DoubleHolder* Ptr(DoubleHolder* x) { if (PrintDebug) std::cout << "Base - Ptr(" << x->val << ")" << std::endl; return x; }
+  virtual DoubleHolder *const& ConstPtrRef(DoubleHolder *const& cprx) { if (PrintDebug) std::cout << "Base - ConstPtrRef(" << cprx->val << ")" << std::endl; return cprx; }
 
   virtual std::string FullyOverloaded(int x) { if (PrintDebug) std::cout << "Base - FullyOverloaded(int " << x << ")" << std::endl; return "Base::FullyOverloaded(int)"; }
   virtual std::string FullyOverloaded(bool x) { if (PrintDebug) std::cout << "Base - FullyOverloaded(bool " << x << ")" << std::endl; return "Base::FullyOverloaded(bool)"; }
@@ -68,6 +70,7 @@
   virtual DoubleHolder Val(DoubleHolder x) { if (PrintDebug) std::cout << "Derived - Val(" << x.val << ")" << std::endl; return x; }
   virtual DoubleHolder& Ref(DoubleHolder& x) { if (PrintDebug) std::cout << "Derived - Ref(" << x.val << ")" << std::endl; return x; }
   virtual DoubleHolder* Ptr(DoubleHolder* x) { if (PrintDebug) std::cout << "Derived - Ptr(" << x->val << ")" << std::endl; return x; }
+  virtual DoubleHolder *const& ConstPtrRef(DoubleHolder *const& cprx) { if (PrintDebug) std::cout << "Derived - ConstPtrRef(" << cprx->val << ")" << std::endl; return cprx; }
 
   virtual std::string FullyOverloaded(int x) { if (PrintDebug) std::cout << "Derived - FullyOverloaded(int " << x << ")" << std::endl; return "Derived::FullyOverloaded(int)"; }
   virtual std::string FullyOverloaded(bool x) { if (PrintDebug) std::cout << "Derived - FullyOverloaded(bool " << x << ")" << std::endl; return "Derived::FullyOverloaded(bool)"; }
@@ -99,6 +102,7 @@
   DoubleHolder ValCall(DoubleHolder x) { return m_base->Val(x); }
   DoubleHolder& RefCall(DoubleHolder& x) { return m_base->Ref(x); }
   DoubleHolder* PtrCall(DoubleHolder* x) { return m_base->Ptr(x); }
+  DoubleHolder *const& ConstPtrRefCall(DoubleHolder *const& cprx) { return m_base->ConstPtrRef(cprx); }
   std::string FullyOverloadedCall(int x) { return m_base->FullyOverloaded(x); }
   std::string FullyOverloadedCall(bool x) { return m_base->FullyOverloaded(x); }
   std::string SemiOverloadedCall(int x) { return m_base->SemiOverloaded(x); }
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_classes_runme.java b/Examples/test-suite/java/director_classes_runme.java
index 5fbb9ea..5992b5d 100644
--- a/Examples/test-suite/java/director_classes_runme.java
+++ b/Examples/test-suite/java/director_classes_runme.java
@@ -16,6 +16,7 @@
 Base - Val(444.555)
 Base - Ref(444.555)
 Base - Ptr(444.555)
+Base - ConstPtrRef(444.555)
 Base - FullyOverloaded(int 10)
 Base - FullyOverloaded(bool 1)
 Base - SemiOverloaded(int -678)
@@ -26,6 +27,7 @@
 Derived - Val(444.555)
 Derived - Ref(444.555)
 Derived - Ptr(444.555)
+Derived - ConstPtrRef(444.555)
 Derived - FullyOverloaded(int 10)
 Derived - FullyOverloaded(bool 1)
 Derived - SemiOverloaded(int -678)
@@ -36,6 +38,7 @@
 JavaDerived - Val(444.555)
 JavaDerived - Ref(444.555)
 JavaDerived - Ptr(444.555)
+JavaDerived - ConstPtrRef(444.555)
 JavaDerived - FullyOverloaded(int 10)
 JavaDerived - FullyOverloaded(bool True)
 JavaDerived - SemiOverloaded(-678)
@@ -67,7 +70,7 @@
 
   void run()
   {
-    if (director_classes.getPrintDebug()) System.out.println("------------ Start ------------ ");
+    if (director_classes.getPrintDebug()) System.out.println("------------ Start ------------");
 
     Caller myCaller = new Caller();
 
@@ -96,7 +99,7 @@
       myBase.delete();
     }
 
-    if (director_classes.getPrintDebug()) System.out.println("------------ Finish ------------ ");
+    if (director_classes.getPrintDebug()) System.out.println("------------ Finish ------------");
   }
 
   void makeCalls(Caller myCaller, Base myBase)
@@ -111,6 +114,7 @@
     if (myCaller.ValCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
     if (myCaller.RefCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
     if (myCaller.PtrCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
+    if (myCaller.ConstPtrRefCall(dh).getVal() != dh.getVal()) throw new RuntimeException("failed");
 
     // Fully overloaded method test (all methods in base class are overloaded)
     if (!myCaller.FullyOverloadedCall(10).equals(baseSimpleName + "::FullyOverloaded(int)")) {
@@ -170,6 +174,11 @@
     if (director_classes.getPrintDebug()) System.out.println("JavaDerived - Ptr(" + x.getVal() + ")");
     return x;
   }
+  public DoubleHolder ConstPtrRef(DoubleHolder x)
+  {
+    if (director_classes.getPrintDebug()) System.out.println("JavaDerived - ConstPtrRef(" + x.getVal() + ")");
+    return x;
+  }
   public String FullyOverloaded(int x)
   {
     if (director_classes.getPrintDebug()) System.out.println("JavaDerived - FullyOverloaded(int " + x + ")");
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/li_boost_shared_ptr_director_runme.java b/Examples/test-suite/java/li_boost_shared_ptr_director_runme.java
index 904eab3..9349c62 100644
--- a/Examples/test-suite/java/li_boost_shared_ptr_director_runme.java
+++ b/Examples/test-suite/java/li_boost_shared_ptr_director_runme.java
@@ -1,60 +1,129 @@
-public class li_boost_shared_ptr_runme {
+import li_boost_shared_ptr_director.*;
+
+public class li_boost_shared_ptr_director_runme {
 
   static {
     try {
-      System.loadLibrary("li_boost_shared_ptr");
+      System.loadLibrary("li_boost_shared_ptr_director");
     } catch (UnsatisfiedLinkError e) {
       System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
       System.exit(1);
     }
   }
 
-  private static void check(String got, String expected) {
-    if (!got.equals(expected))
+  private static void check(int got, int expected) {
+    if (got != expected)
       throw new RuntimeException("Failed, got: " + got + " expected: " + expected);
   }
 
   public static void main(String argv[]) {
-    li_boost_shared_ptr_director_Derived a = li_boost_shared_ptr_director_Derived.new(false);
-    li_boost_shared_ptr_director_Derived b = li_boost_shared_ptr_director_Derived.new(true);
+    li_boost_shared_ptr_director_Derived a = new li_boost_shared_ptr_director_Derived(false);
+    li_boost_shared_ptr_director_Derived b = new li_boost_shared_ptr_director_Derived(true);
 
-    check(call_ret_c_shared_ptr(a) ==  1);
-    check(call_ret_c_shared_ptr(b) == -1);
-    check(call_ret_c_by_value(a)   ==  1);
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a),  1);
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
+    check(li_boost_shared_ptr_director.call_ret_c_by_value(a),    1);
 
-    check(call_take_c_by_value(a)                  == 5);
-    check(call_take_c_shared_ptr_by_value(a)       == 6);
-    check(call_take_c_shared_ptr_by_ref(a)         == 7);
-    check(call_take_c_shared_ptr_by_pointer(a)     == 8);
-    check(call_take_c_shared_ptr_by_pointer_ref(a) == 9);
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(a),  1);
+    check(li_boost_shared_ptr_director.call_ret_c_shared_ptr(b), -1);
+    check(li_boost_shared_ptr_director.call_ret_c_by_value(a),    1);
 
-    check(call_take_c_shared_ptr_by_value_with_null(a)       == -2);
-    check(call_take_c_shared_ptr_by_ref_with_null(a)         == -3);
-    check(call_take_c_shared_ptr_by_pointer_with_null(a)     == -4);
-    check(call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -5);
+    check(li_boost_shared_ptr_director.call_take_c_by_value(a),                  5);
+    check(li_boost_shared_ptr_director.call_take_c_by_ref(a),                    6);
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer(a),                7);
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref(a),            8);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value(a),       9);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref(a),         10);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer(a),     11);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref(a), 12);
 
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer_with_null(a),                -2);
+    check(li_boost_shared_ptr_director.call_take_c_by_pointer_ref_with_null(a),            -3);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_value_with_null(a),       -4);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_ref_with_null(a),         -5);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_with_null(a),     -6);
+    check(li_boost_shared_ptr_director.call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7);
   }
 }
 
-class li_boost_shared_ptr_director_Derived extends li_boost_shared_ptr_director.Base {
+class li_boost_shared_ptr_director_Derived extends Base {
 
-  @Override
-  public String ping() {
-    return "li_boost_shared_ptr_director_MyBarFoo.ping()";
+  private boolean return_none;
+
+  li_boost_shared_ptr_director_Derived(boolean flag) {
+    super();
+    this.return_none = flag;
   }
 
   @Override
-  public String pong() {
-    return "li_boost_shared_ptr_director_MyBarFoo.pong();" + ping();
+  public C ret_c_shared_ptr() {
+    if (this.return_none)
+      return null;
+    else
+      return new C();
   }
 
   @Override
-  public String upcall(li_boost_shared_ptr_director.FooBar fooBarPtr) {
-    return "override;" + fooBarPtr.FooBarDo();
+  public C ret_c_by_value() {
+    return new C();
   }
 
   @Override
-  public li_boost_shared_ptr_director.Foo makeFoo() {
-    return new li_boost_shared_ptr_director.Foo();
+  public int take_c_by_value(C c) {
+      return c.get_m();
   }
+
+  @Override
+  public int take_c_by_ref(C c) {
+      return c.get_m();
+  }
+
+  @Override
+  public int take_c_by_pointer(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -2;
+  }
+
+  @Override
+  public int take_c_by_pointer_ref(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -3;
+  }
+
+  @Override
+  public int take_c_shared_ptr_by_value(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -4;
+  }
+
+  @Override
+  public int take_c_shared_ptr_by_ref(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -5;
+  }
+
+  @Override
+  public int take_c_shared_ptr_by_pointer(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -6;
+  }
+
+  @Override
+  public int take_c_shared_ptr_by_pointer_ref(C c) {
+    if (c != null)
+      return c.get_m();
+    else
+      return -7;
+  }
+
 }
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_boost_shared_ptr_director.i b/Examples/test-suite/li_boost_shared_ptr_director.i
index 8f36bf3..b2d9fc1 100644
--- a/Examples/test-suite/li_boost_shared_ptr_director.i
+++ b/Examples/test-suite/li_boost_shared_ptr_director.i
@@ -4,7 +4,13 @@
 #include <boost/shared_ptr.hpp>
 %}
 
-%include "boost_shared_ptr.i";
+#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGD) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGR)
+#define SHARED_PTR_WRAPPERS_IMPLEMENTED
+#endif
+
+#if defined(SHARED_PTR_WRAPPERS_IMPLEMENTED)
+
+%include <boost_shared_ptr.i>
 %shared_ptr(C);
 %feature("director") Base;
 
@@ -13,6 +19,7 @@
   C() : m(1) {}
   C(int n) : m(n) {}
   int get_m() { return m; }
+private:
   int m;
 };
 
@@ -21,10 +28,23 @@
   virtual boost::shared_ptr<C> ret_c_shared_ptr() = 0;
   virtual C ret_c_by_value() = 0;
   virtual int take_c_by_value(C c) = 0;
+  virtual int take_c_by_ref(C& c) = 0;
+  virtual int take_c_by_pointer(C* c) = 0;
+  virtual int take_c_by_pointer_ref(C*const& c) = 0;
   virtual int take_c_shared_ptr_by_value(boost::shared_ptr<C> c) = 0;
   virtual int take_c_shared_ptr_by_ref(boost::shared_ptr<C>& c) = 0;
   virtual int take_c_shared_ptr_by_pointer(boost::shared_ptr<C>* c) = 0;
   virtual int take_c_shared_ptr_by_pointer_ref(boost::shared_ptr<C>*const&c) = 0;
+  virtual int take_many_args(
+    C v1, C v2,
+    C &r1, C &r2,
+    C *p1, C *p2,
+    C *const& cr1, C *const& cr2,
+    boost::shared_ptr<C> sv1, boost::shared_ptr<C> sv2,
+    boost::shared_ptr<C> &sr1, boost::shared_ptr<C> &sr2,
+    boost::shared_ptr<C> *sp1, boost::shared_ptr<C> *sp2,
+    boost::shared_ptr<C> *const& spr1, boost::shared_ptr<C> *const& spr2
+  ) = 0;
   virtual ~Base() {}
 };
 
@@ -47,8 +67,34 @@
   return b->take_c_by_value(c);
 }
 
+int call_take_c_by_ref(Base* b) {
+  C c(6);
+  return b->take_c_by_ref(c);
+}
+
+int call_take_c_by_pointer(Base* b) {
+  C c(7);
+  return b->take_c_by_pointer(&c);
+}
+
+int call_take_c_by_pointer_ref(Base* b) {
+  C c(8);
+  C* p(&c);
+  return b->take_c_by_pointer_ref(p);
+}
+
+int call_take_c_by_pointer_with_null(Base* b) {
+  C* p = NULL;
+  return b->take_c_by_pointer(p);
+}
+
+int call_take_c_by_pointer_ref_with_null(Base* b) {
+  C* p = NULL;
+  return b->take_c_by_pointer_ref(p);
+}
+
 int call_take_c_shared_ptr_by_value(Base* b) {
-  boost::shared_ptr<C> ptr(new C(6));
+  boost::shared_ptr<C> ptr(new C(9));
   return b->take_c_shared_ptr_by_value(ptr);
 }
 
@@ -58,7 +104,7 @@
 }
 
 int call_take_c_shared_ptr_by_ref(Base* b) {
-  boost::shared_ptr<C> ptr(new C(7));
+  boost::shared_ptr<C> ptr(new C(10));
   return b->take_c_shared_ptr_by_ref(ptr);
 }
 
@@ -68,7 +114,7 @@
 }
 
 int call_take_c_shared_ptr_by_pointer(Base* b) {
-  boost::shared_ptr<C> ptr(new C(8));
+  boost::shared_ptr<C> ptr(new C(11));
   return b->take_c_shared_ptr_by_pointer(&ptr);
 }
 
@@ -78,7 +124,7 @@
 }
 
 int call_take_c_shared_ptr_by_pointer_ref(Base* b) {
-  boost::shared_ptr<C> *ptr = new boost::shared_ptr<C>(new C(9));
+  boost::shared_ptr<C> *ptr = new boost::shared_ptr<C>(new C(12));
   return b->take_c_shared_ptr_by_pointer_ref(ptr);
 }
 
@@ -88,3 +134,5 @@
 }
 
 %}
+
+#endif
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/perl5/director_classes_runme.pl b/Examples/test-suite/perl5/director_classes_runme.pl
index a4fddee..5e72703 100644
--- a/Examples/test-suite/perl5/director_classes_runme.pl
+++ b/Examples/test-suite/perl5/director_classes_runme.pl
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 29;
+use Test::More tests => 32;
 BEGIN { use_ok 'director_classes' }
 require_ok 'director_classes';
 
@@ -10,6 +10,7 @@
   sub Val { $_[1] }
   sub Ref { $_[1] }
   sub Ptr { $_[1] }
+  sub ConstPtrRef { $_[1] }
   sub FullyOverloaded {
     my $rv = shift->SUPER::FullyOverloaded(@_);
     $rv =~ s/Base/__PACKAGE__/sge;
@@ -45,6 +46,7 @@
   is($caller->ValCall($dh)->{val}, $dh->{val}, "$bname.Val");
   is($caller->RefCall($dh)->{val}, $dh->{val}, "$bname.Ref");
   is($caller->PtrCall($dh)->{val}, $dh->{val}, "$bname.Ptr");
+  is($caller->ConstPtrRefCall($dh)->{val}, $dh->{val}, "$bname.ConstPtrRef");
   is($caller->FullyOverloadedCall(1),
       "${bname}::FullyOverloaded(int)",
       "$bname.FullyOverloaded(int)");
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_boost_shared_ptr_director_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
new file mode 100644
index 0000000..52868ea
--- /dev/null
+++ b/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
@@ -0,0 +1,80 @@
+from li_boost_shared_ptr_director import *
+
+class Derived(Base):
+    def __init__(self, flag):
+        self.return_none = flag
+        Base.__init__(self)
+
+    def ret_c_shared_ptr(self):
+        if self.return_none:
+            return None
+        else:
+            return C()
+
+    def ret_c_by_value(self):
+        return C()
+
+    def take_c_by_value(self,c):
+        return c.get_m()
+
+    def take_c_by_ref(self,c):
+        return c.get_m()
+
+    def take_c_by_pointer(self,c):
+        if c:
+            return c.get_m()
+        else:
+            return -2
+
+    def take_c_by_pointer_ref(self,c):
+        if c:
+            return c.get_m()
+        else:
+            return -3
+
+    def take_c_shared_ptr_by_value(self,c):
+        if c:
+            return c.get_m()
+        else:
+            return -4
+
+    def take_c_shared_ptr_by_ref(self,c):
+        if c:
+            return c.get_m()
+        else:
+            return -5
+
+    def take_c_shared_ptr_by_pointer(self,c):
+        if c:
+            return c.get_m()
+        else:
+            return -6
+
+    def take_c_shared_ptr_by_pointer_ref(self,c):
+        if c:
+            return c.get_m()
+        else:
+            return -7
+
+a = Derived(False)
+b = Derived(True)
+
+assert call_ret_c_shared_ptr(a) ==  1
+assert call_ret_c_shared_ptr(b) == -1
+assert call_ret_c_by_value(a)   ==  1
+
+assert call_take_c_by_value(a)                  == 5
+assert call_take_c_by_ref(a)                    == 6
+assert call_take_c_by_pointer(a)                == 7
+assert call_take_c_by_pointer_ref(a)            == 8
+assert call_take_c_shared_ptr_by_value(a)       == 9
+assert call_take_c_shared_ptr_by_ref(a)         == 10
+assert call_take_c_shared_ptr_by_pointer(a)     == 11
+assert call_take_c_shared_ptr_by_pointer_ref(a) == 12
+
+assert call_take_c_by_pointer_with_null(a)                == -2
+assert call_take_c_by_pointer_ref_with_null(a)            == -3
+assert call_take_c_shared_ptr_by_value_with_null(a)       == -4
+assert call_take_c_shared_ptr_by_ref_with_null(a)         == -5
+assert call_take_c_shared_ptr_by_pointer_with_null(a)     == -6
+assert call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -7
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/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in
index 03eb239..292244a 100644
--- a/Examples/test-suite/ruby/Makefile.in
+++ b/Examples/test-suite/ruby/Makefile.in
@@ -11,7 +11,6 @@
 top_builddir = @top_builddir@
 
 CPP_TEST_CASES = \
-	li_boost_shared_ptr_director \
 	li_cstring \
 	li_factory \
 	li_std_functors \
diff --git a/Examples/test-suite/ruby/li_boost_shared_ptr_director_runme.rb b/Examples/test-suite/ruby/li_boost_shared_ptr_director_runme.rb
index 0f7f14b..55c1cbe 100644
--- a/Examples/test-suite/ruby/li_boost_shared_ptr_director_runme.rb
+++ b/Examples/test-suite/ruby/li_boost_shared_ptr_director_runme.rb
@@ -25,7 +25,11 @@
     c.get_m
   end
 
-  def take_c_shared_ptr_by_value(c)
+  def take_c_by_ref(c)
+    c.get_m
+  end
+
+  def take_c_by_pointer(c)
     if c
       c.get_m
     else
@@ -33,7 +37,7 @@
     end
   end
 
-  def take_c_shared_ptr_by_ref(c)
+  def take_c_by_pointer_ref(c)
     if c
       c.get_m
     else
@@ -41,7 +45,7 @@
     end
   end
 
-  def take_c_shared_ptr_by_pointer(c)
+  def take_c_shared_ptr_by_value(c)
     if c
       c.get_m
     else
@@ -49,7 +53,7 @@
     end
   end
 
-  def take_c_shared_ptr_by_pointer_ref(c)
+  def take_c_shared_ptr_by_ref(c)
     if c
       c.get_m
     else
@@ -57,6 +61,22 @@
     end
   end
 
+  def take_c_shared_ptr_by_pointer(c)
+    if c
+      c.get_m
+    else
+      -6
+    end
+  end
+
+  def take_c_shared_ptr_by_pointer_ref(c)
+    if c
+      c.get_m
+    else
+      -7
+    end
+  end
+
 end
 
 a = Derived.new(false)
@@ -67,13 +87,17 @@
 raise unless call_ret_c_by_value(a)   ==  1
 
 raise unless call_take_c_by_value(a)                  == 5
-raise unless call_take_c_shared_ptr_by_value(a)       == 6
-raise unless call_take_c_shared_ptr_by_ref(a)         == 7
-raise unless call_take_c_shared_ptr_by_pointer(a)     == 8
-raise unless call_take_c_shared_ptr_by_pointer_ref(a) == 9
+raise unless call_take_c_by_ref(a)                    == 6
+raise unless call_take_c_by_pointer(a)                == 7
+raise unless call_take_c_by_pointer_ref(a)            == 8
+raise unless call_take_c_shared_ptr_by_value(a)       == 9
+raise unless call_take_c_shared_ptr_by_ref(a)         == 10
+raise unless call_take_c_shared_ptr_by_pointer(a)     == 11
+raise unless call_take_c_shared_ptr_by_pointer_ref(a) == 12
 
-raise unless call_take_c_shared_ptr_by_value_with_null(a)       == -2
-raise unless call_take_c_shared_ptr_by_ref_with_null(a)         == -3
-raise unless call_take_c_shared_ptr_by_pointer_with_null(a)     == -4
-raise unless call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -5
-
+raise unless call_take_c_by_pointer_with_null(a)                == -2
+raise unless call_take_c_by_pointer_ref_with_null(a)            == -3
+raise unless call_take_c_shared_ptr_by_value_with_null(a)       == -4
+raise unless call_take_c_shared_ptr_by_ref_with_null(a)         == -5
+raise unless call_take_c_shared_ptr_by_pointer_with_null(a)     == -6
+raise unless call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -7
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/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i
index 699d058..73212dd 100644
--- a/Lib/csharp/boost_shared_ptr.i
+++ b/Lib/csharp/boost_shared_ptr.i
@@ -31,6 +31,18 @@
 %typemap(out) CONST TYPE
 %{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
 
+%typemap(directorin) CONST TYPE
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+
+%typemap(directorout) CONST TYPE
+%{ if (!$input) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null $1_type", 0);
+    return $null;
+  }
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input;
+  $result = *smartarg->get();
+%}
+
 // plain pointer
 %typemap(in, canthrow=1) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
   smartarg = (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input;
@@ -39,6 +51,13 @@
   $result = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner) : 0;
 %}
 
+%typemap(directorin) CONST TYPE *
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0; %}
+
+%typemap(directorout) CONST TYPE * %{
+#error "typemaps for $1_type not available"
+%}
+
 // plain reference
 %typemap(in, canthrow=1) CONST TYPE & %{
   $1 = ($1_ltype)(((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input) ? ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input)->get() : 0);
@@ -49,6 +68,13 @@
 %typemap(out, fragment="SWIG_null_deleter") CONST TYPE &
 %{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner); %}
 
+%typemap(directorin) CONST TYPE &
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (&$1 SWIG_NO_NULL_DELETER_0); %}
+
+%typemap(directorout) CONST TYPE & %{
+#error "typemaps for $1_type not available"
+%}
+
 // plain pointer by reference
 %typemap(in) TYPE *CONST& ($*1_ltype temp = 0)
 %{ temp = (TYPE *)(((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input) ? ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input)->get() : 0);
@@ -56,18 +82,42 @@
 %typemap(out, fragment="SWIG_null_deleter") TYPE *CONST&
 %{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner); %}
 
+%typemap(directorin) TYPE *CONST&
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0; %}
+
+%typemap(directorout) TYPE *CONST& %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by value
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
 %{ if ($input) $1 = *($&1_ltype)$input; %}
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
 %{ $result = $1 ? new $1_ltype($1) : 0; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
+%{ if ($input) {
+    SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input;
+    $result = *smartarg;
+  }
+%}
+
 // shared_ptr by reference
 %typemap(in, canthrow=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & ($*1_ltype tempnull)
 %{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &
 %{ $result = *$1 ? new $*1_ltype(*$1) : 0; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
 %{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
@@ -75,6 +125,13 @@
 %{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
    if ($owner) delete $1; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
+%{ $input = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempnull, $*1_ltype temp = 0)
 %{ temp = $input ? *($1_ltype)&$input : &tempnull;
@@ -82,6 +139,13 @@
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
 %{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
+%{ $input = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "typemaps for $1_type not available"
+%}
+
 // various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug
 %typemap(in) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{
 #error "typemaps for $1_type not available"
@@ -175,6 +239,18 @@
       return ret;
     } %}
 
+%typemap(csdirectorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > "$typemap(cstype, TYPE).getCPtr($cscall).Handle"
+
+%typemap(csdirectorin) CONST TYPE,
+                       CONST TYPE *,
+                       CONST TYPE &,
+                       TYPE *CONST& "($iminput == global::System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)($iminput, true)"
+
+%typemap(csdirectorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
+                       SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+                       SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+                       SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "($iminput == global::System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)($iminput, true)"
+
 
 // Proxy classes (base classes, ie, not derived classes)
 %typemap(csbody) TYPE %{
@@ -247,4 +323,3 @@
 
 %template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
 %enddef
-
diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg
index bf1e126..e1554dc 100644
--- a/Lib/csharp/csharp.swg
+++ b/Lib/csharp/csharp.swg
@@ -855,6 +855,14 @@
    $1 = ($1_ltype)&temp; %}
 %typemap(out) SWIGTYPE *const&
 %{ $result = (void *)*$1; %} 
+%typemap(directorin) SWIGTYPE *const&
+%{ $input = (void *) $1; %}
+%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"
 
 /* Marshal C/C++ pointer to global::System.IntPtr */
 %typemap(ctype) void *VOID_INT_PTR "void *"
diff --git a/Lib/d/boost_shared_ptr.i b/Lib/d/boost_shared_ptr.i
index 5ee9284..4a220a5 100644
--- a/Lib/d/boost_shared_ptr.i
+++ b/Lib/d/boost_shared_ptr.i
@@ -1,7 +1,9 @@
 %include <shared_ptr.i>
 
+// Language specific macro implementing all the customisations for handling the smart pointer
 %define SWIG_SHARED_PTR_TYPEMAPS(CONST, TYPE...)
 
+// %naturalvar is as documented for member variables
 %naturalvar TYPE;
 %naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
 
@@ -10,6 +12,7 @@
 //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter<SWIG_null_deleter>(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ((*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\"))) << \"]\" << endl << flush; }\n"
                                "(void)arg1; delete smartarg1;"
 
+// Typemap customisations...
 
 // plain value
 %typemap(in, canthrow=1) CONST TYPE ($&1_type argp = 0) %{
@@ -22,6 +25,18 @@
 %typemap(out) CONST TYPE
 %{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
 
+%typemap(directorin) CONST TYPE
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+
+%typemap(directorout) CONST TYPE
+%{ if (!$input) {
+    SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Attempt to dereference null $1_type");
+    return $null;
+  }
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input;
+  $result = *smartarg->get();
+%}
+
 // plain pointer
 %typemap(in, canthrow=1) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
   smartarg = (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input;
@@ -30,6 +45,13 @@
   $result = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner) : 0;
 %}
 
+%typemap(directorin) CONST TYPE *
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0; %}
+
+%typemap(directorout) CONST TYPE * %{
+#error "typemaps for $1_type not available"
+%}
+
 // plain reference
 %typemap(in, canthrow=1) CONST TYPE & %{
   $1 = ($1_ltype)(((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input) ? ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input)->get() : 0);
@@ -40,6 +62,13 @@
 %typemap(out, fragment="SWIG_null_deleter") CONST TYPE &
 %{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner); %}
 
+%typemap(directorin) CONST TYPE &
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (&$1 SWIG_NO_NULL_DELETER_0); %}
+
+%typemap(directorout) CONST TYPE & %{
+#error "typemaps for $1_type not available"
+%}
+
 // plain pointer by reference
 %typemap(in) TYPE *CONST& ($*1_ltype temp = 0)
 %{ temp = (TYPE *)(((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input) ? ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input)->get() : 0);
@@ -47,18 +76,42 @@
 %typemap(out, fragment="SWIG_null_deleter") TYPE *CONST&
 %{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner); %}
 
+%typemap(directorin) TYPE *CONST&
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0; %}
+
+%typemap(directorout) TYPE *CONST& %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by value
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
 %{ if ($input) $1 = *($&1_ltype)$input; %}
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
 %{ $result = $1 ? new $1_ltype($1) : 0; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
+%{ if ($input) {
+    SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input;
+    $result = *smartarg;
+  }
+%}
+
 // shared_ptr by reference
 %typemap(in, canthrow=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & ($*1_ltype tempnull)
 %{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &
 %{ $result = *$1 ? new $*1_ltype(*$1) : 0; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &
+%{ $input = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
 %{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
@@ -66,6 +119,13 @@
 %{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
    if ($owner) delete $1; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
+%{ $input = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempnull, $*1_ltype temp = 0)
 %{ temp = $input ? *($1_ltype)&$input : &tempnull;
@@ -73,6 +133,13 @@
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
 %{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %}
 
+%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
+%{ $input = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0; %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "typemaps for $1_type not available"
+%}
+
 // various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug
 %typemap(in) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{
 #error "typemaps for $1_type not available"
@@ -96,9 +163,22 @@
                   SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(dtype, TYPE)"
 
 %typemap(din) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
-               SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
-               SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
-               SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(dtype, TYPE).swigGetCPtr($dinput)"
+              SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+              SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+              SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(dtype, TYPE).swigGetCPtr($dinput)"
+
+%typemap(ddirectorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > "$typemap(dtype, TYPE).swigGetCPtr($dcall)"
+
+%typemap(ddirectorin) CONST TYPE,
+                      CONST TYPE *,
+                      CONST TYPE &,
+                      TYPE *CONST& "($winput is null) ? null : new $typemap(dtype, TYPE)($winput, true)"
+
+%typemap(ddirectorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
+                      SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+                      SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+                      SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "($winput is null) ? null : new $typemap(dtype, TYPE)($winput, true)"
+
 
 %typemap(dout, excode=SWIGEXCODE) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > {
   void* cPtr = $imcall;
@@ -141,8 +221,7 @@
   return ret;
 }
 
-// For shared pointers, both the derived and the base class have to »own« their
-// pointer; otherwise the reference count is not decreased properly on destruction.
+// Proxy classes (base classes, ie, not derived classes)
 %typemap(dbody) SWIGTYPE %{
 private void* swigCPtr;
 private bool swigCMemOwn;
@@ -157,6 +236,7 @@
 }
 %}
 
+// Derived proxy classes
 %typemap(dbody_derived) SWIGTYPE %{
 private void* swigCPtr;
 private bool swigCMemOwn;
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index 5043741..f0d604b 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -182,3 +182,16 @@
   $*dclassname ret = (cPtr is null) ? null : new $*dclassname(cPtr, $owner);$excode
   return ret;
 }
+%typemap(directorin) SWIGTYPE *const&
+  "$input = (void *) $1;"
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const&
+%{ 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)"
+%typemap(ddirectorout,
+  nativepointer="cast(void*)$dcall"
+) SWIGTYPE *const& "$*dclassname.swigGetCPtr($dcall)"
+
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/boost_shared_ptr.i b/Lib/java/boost_shared_ptr.i
index 6a5e0b2..325a683 100644
--- a/Lib/java/boost_shared_ptr.i
+++ b/Lib/java/boost_shared_ptr.i
@@ -31,6 +31,19 @@
 %typemap(out) CONST TYPE
 %{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
 
+%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") CONST TYPE
+%{ $input = 0;
+  *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+
+%typemap(directorout) CONST TYPE
+%{ if (!$input) {
+    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type");
+    return $null;
+  }
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input;
+  $result = *smartarg->get();
+  %}
+
 // plain pointer
 %typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
   smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input;
@@ -39,6 +52,16 @@
   *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner) : 0;
 %}
 
+%typemap(directorin,descriptor="L$packagepath/$javaclassname;") CONST TYPE *
+%{ $input = 0;
+  if ($1) {
+    *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ($1 SWIG_NO_NULL_DELETER_0);
+  } %}
+
+%typemap(directorout) CONST TYPE * %{
+#error "typemaps for $1_type not available"
+%}
+
 // plain reference
 %typemap(in) CONST TYPE & %{
   $1 = ($1_ltype)((*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) ? (*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input)->get() : 0);
@@ -49,6 +72,14 @@
 %typemap(out, fragment="SWIG_null_deleter") CONST TYPE &
 %{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner); %}
 
+%typemap(directorin,descriptor="L$packagepath/$javaclassname;") CONST TYPE &
+%{ $input = 0;
+  *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (&$1 SWIG_NO_NULL_DELETER_0); %}
+
+%typemap(directorout) CONST TYPE & %{
+#error "typemaps for $1_type not available"
+%}
+
 // plain pointer by reference
 %typemap(in) TYPE *CONST& ($*1_ltype temp = 0)
 %{ temp = (TYPE *)((*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) ? (*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input)->get() : 0);
@@ -56,6 +87,16 @@
 %typemap(out, fragment="SWIG_null_deleter") TYPE *CONST&
 %{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner); %}
 
+%typemap(directorin,descriptor="L$packagepath/$*javaclassname;") TYPE *CONST&
+%{ $input = 0;
+  if ($1) {
+    *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ($1 SWIG_NO_NULL_DELETER_0);
+ } %}
+
+%typemap(directorout) TYPE *CONST& %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by value
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ($&1_type argp)
 %{ argp = *($&1_ltype*)&$input;
@@ -63,12 +104,34 @@
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
 %{ *($&1_ltype*)&$result = $1 ? new $1_ltype($1) : 0; %}
 
+%typemap(directorin,descriptor="L$packagepath/$typemap(jstype, TYPE);") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
+%{ $input = 0;
+  if ($1) {
+    *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1);
+  } %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
+%{ if ($input) {
+    $&1_type smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input;
+    $result = *smartarg;
+  } %}
+
 // shared_ptr by reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & ($*1_ltype tempnull)
 %{ $1 = $input ? *($&1_ltype)&$input : &tempnull; %}
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &
 %{ *($&1_ltype)&$result = *$1 ? new $*1_ltype(*$1) : 0; %}
 
+%typemap(directorin,descriptor="L$packagepath/$typemap(jstype, TYPE);") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &
+%{ $input = 0;
+  if ($1) {
+    *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1);
+  } %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
 %{ $1 = $input ? *($&1_ltype)&$input : &tempnull; %}
@@ -76,6 +139,16 @@
 %{ *($&1_ltype)&$result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
    if ($owner) delete $1; %}
 
+%typemap(directorin,descriptor="L$packagepath/$typemap(jstype, TYPE);") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
+%{ $input = 0;
+  if ($1 && *$1) {
+    *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1);
+  } %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "typemaps for $1_type not available"
+%}
+
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempnull, $*1_ltype temp = 0)
 %{ temp = $input ? *($1_ltype)&$input : &tempnull;
@@ -83,6 +156,16 @@
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
 %{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %}
 
+%typemap(directorin,descriptor="L$packagepath/$typemap(jstype, TYPE);") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
+%{ $input = 0;
+  if ($1 && *$1) {
+    *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1);
+  } %}
+
+%typemap(directorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "typemaps for $1_type not available"
+%}
+
 // various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug
 %typemap(in) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{
 #error "typemaps for $1_type not available"
@@ -143,6 +226,18 @@
     return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
   }
 
+%typemap(javadirectorout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > "$typemap(jstype, TYPE).getCPtr($javacall)"
+
+%typemap(javadirectorin) CONST TYPE,
+                         CONST TYPE *,
+                         CONST TYPE &,
+                         TYPE *CONST& "($jniinput == 0) ? null : new $typemap(jstype, TYPE)($jniinput, true)"
+
+%typemap(javadirectorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
+                         SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+                         SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+                         SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "($jniinput == 0) ? null : new $typemap(jstype, TYPE)($jniinput, true)"
+
 // Base proxy classes
 %typemap(javabody) TYPE %{
   private transient long swigCPtr;
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 b49826b..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 */
 
@@ -1173,6 +1181,14 @@
    $1 = ($1_ltype)&temp; %}
 %typemap(out) SWIGTYPE *const&
 %{ *($1_ltype)&$result = *$1; %} 
+%typemap(directorin,descriptor="L$packagepath/$*javaclassname;") SWIGTYPE *const&
+%{ *(($1_ltype)&$input) = ($*1_ltype) $1; %}
+%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)"
 
 /* Typemaps used for the generation of proxy and type wrapper class code */
 %typemap(javabase)             SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
diff --git a/Lib/octave/boost_shared_ptr.i b/Lib/octave/boost_shared_ptr.i
index 68bd950..668bf43 100644
--- a/Lib/octave/boost_shared_ptr.i
+++ b/Lib/octave/boost_shared_ptr.i
@@ -1,5 +1,11 @@
 %include <shared_ptr.i>
 
+// Set SHARED_PTR_DISOWN to $disown if required, for example
+// #define SHARED_PTR_DISOWN $disown
+#if !defined(SHARED_PTR_DISOWN)
+#define SHARED_PTR_DISOWN 0
+#endif
+
 // Language specific macro implementing all the customisations for handling the smart pointer
 %define SWIG_SHARED_PTR_TYPEMAPS(CONST, TYPE...)
 
@@ -52,11 +58,29 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (!swig_argp) {
+    %dirout_nullref("$type");
+  } else {
+    $result = *(%reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)->get());
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *);
+  }
+}
+
 // plain pointer
-// Note: $disown not implemented as it will lead to a memory leak of the shared_ptr instance
+// Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) CONST TYPE * (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) {
   int newmem = 0;
-  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem);
   if (!SWIG_IsOK(res)) {
     %argument_fail(res, "$type", $symname, $argnum);
   }
@@ -69,6 +93,7 @@
     $1 = %const_cast((smartarg ? smartarg->get() : 0), $1_ltype);
   }
 }
+
 %typemap(out, fragment="SWIG_null_deleter") CONST TYPE * {
   SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), $owner | SWIG_POINTER_OWN));
@@ -97,6 +122,14 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE * %{
+#error "directorout typemap for plain pointer not implemented"
+%}
+
 // plain reference
 %typemap(in) CONST TYPE & (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
   int newmem = 0;
@@ -142,11 +175,19 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(&$1 SWIG_NO_NULL_DELETER_0);
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE & %{
+#error "directorout typemap for plain reference not implemented"
+%}
+
 // plain pointer by reference
-// Note: $disown not implemented as it will lead to a memory leak of the shared_ptr instance
+// Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) TYPE *CONST& (void  *argp = 0, int res = 0, $*1_ltype temp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
   int newmem = 0;
-  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem);
   if (!SWIG_IsOK(res)) {
     %argument_fail(res, "$type", $symname, $argnum);
   }
@@ -160,7 +201,7 @@
   $1 = &temp;
 }
 %typemap(out, fragment="SWIG_null_deleter") TYPE *CONST& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner);
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -171,6 +212,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") TYPE *CONST& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+   smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) TYPE *CONST& %{
+#error "directorout typemap for plain pointer by reference not implemented"
+%}
+
 // shared_ptr by value
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *argp, int res = 0) {
   int newmem = 0;
@@ -201,6 +250,22 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (swig_argp) {
+    $result = *(%reinterpret_cast(swig_argp, $&ltype));
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, $&ltype);
+  }
+}
+
 // shared_ptr by reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -228,6 +293,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "directorout typemap for shared_ptr ref not implemented"
+%}
+
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -244,7 +317,7 @@
   }
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 && *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
   if ($owner) delete $1;
 }
@@ -256,6 +329,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "directorout typemap for pointer to shared_ptr not implemented"
+%}
+
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (void *argp, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, $*1_ltype temp = 0) {
   int newmem = 0;
@@ -269,7 +350,7 @@
   $1 = &temp;
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 && **$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -280,6 +361,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "directorout typemap for pointer ref to shared_ptr not implemented"
+%}
+
 // Typecheck typemaps
 // Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
 // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
@@ -307,5 +396,6 @@
 
 
 %template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
-%enddef
 
+
+%enddef
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/boost_shared_ptr.i b/Lib/python/boost_shared_ptr.i
index 83a2635..a4cde25 100644
--- a/Lib/python/boost_shared_ptr.i
+++ b/Lib/python/boost_shared_ptr.i
@@ -62,6 +62,24 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (!swig_argp) {
+    %dirout_nullref("$type");
+  } else {
+    $result = *(%reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)->get());
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *);
+  }
+}
+
 // plain pointer
 // Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) CONST TYPE * (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) {
@@ -108,6 +126,14 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter_python") CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE * %{
+#error "directorout typemap for plain pointer not implemented"
+%}
+
 // plain reference
 %typemap(in) CONST TYPE & (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
   int newmem = 0;
@@ -153,6 +179,14 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter_python") CONST TYPE & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(&$1 SWIG_NO_NULL_DELETER_0);
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE & %{
+#error "directorout typemap for plain reference not implemented"
+%}
+
 // plain pointer by reference
 // Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) TYPE *CONST& (void  *argp = 0, int res = 0, $*1_ltype temp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
@@ -171,7 +205,7 @@
   $1 = &temp;
 }
 %typemap(out, fragment="SWIG_null_deleter_python") TYPE *CONST& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner);
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -182,6 +216,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter_python") TYPE *CONST& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+   smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) TYPE *CONST& %{
+#error "directorout typemap for plain pointer by reference not implemented"
+%}
+
 // shared_ptr by value
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *argp, int res = 0) {
   int newmem = 0;
@@ -212,6 +254,22 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (swig_argp) {
+    $result = *(%reinterpret_cast(swig_argp, $&ltype));
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, $&ltype);
+  }
+}
+
 // shared_ptr by reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -239,6 +297,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "directorout typemap for shared_ptr ref not implemented"
+%}
+
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -255,7 +321,7 @@
   }
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 && *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
   if ($owner) delete $1;
 }
@@ -267,6 +333,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "directorout typemap for pointer to shared_ptr not implemented"
+%}
+
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (void *argp, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, $*1_ltype temp = 0) {
   int newmem = 0;
@@ -280,7 +354,7 @@
   $1 = &temp;
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 && **$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -291,6 +365,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "directorout typemap for pointer ref to shared_ptr not implemented"
+%}
+
 // Typecheck typemaps
 // Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
 // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
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/boost_shared_ptr.i b/Lib/r/boost_shared_ptr.i
index a7b0df1..668bf43 100644
--- a/Lib/r/boost_shared_ptr.i
+++ b/Lib/r/boost_shared_ptr.i
@@ -1,5 +1,11 @@
 %include <shared_ptr.i>
 
+// Set SHARED_PTR_DISOWN to $disown if required, for example
+// #define SHARED_PTR_DISOWN $disown
+#if !defined(SHARED_PTR_DISOWN)
+#define SHARED_PTR_DISOWN 0
+#endif
+
 // Language specific macro implementing all the customisations for handling the smart pointer
 %define SWIG_SHARED_PTR_TYPEMAPS(CONST, TYPE...)
 
@@ -29,7 +35,8 @@
   }
 }
 %typemap(out) CONST TYPE {
-  %set_output(SWIG_NewPointerObj(new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
 %typemap(varin) CONST TYPE {
@@ -47,14 +54,33 @@
   }
 }
 %typemap(varout) CONST TYPE {
-  %set_varoutput(SWIG_NewPointerObj(new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
+}
+
+%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (!swig_argp) {
+    %dirout_nullref("$type");
+  } else {
+    $result = *(%reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)->get());
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *);
+  }
 }
 
 // plain pointer
-// Note: $disown not implemented as it will lead to a memory leak of the shared_ptr instance
+// Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) CONST TYPE * (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) {
   int newmem = 0;
-  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem);
   if (!SWIG_IsOK(res)) {
     %argument_fail(res, "$type", $symname, $argnum);
   }
@@ -67,8 +93,9 @@
     $1 = %const_cast((smartarg ? smartarg->get() : 0), $1_ltype);
   }
 }
+
 %typemap(out, fragment="SWIG_null_deleter") CONST TYPE * {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), $owner | SWIG_POINTER_OWN));
 }
 
@@ -95,6 +122,14 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE * %{
+#error "directorout typemap for plain pointer not implemented"
+%}
+
 // plain reference
 %typemap(in) CONST TYPE & (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
   int newmem = 0;
@@ -140,11 +175,19 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(&$1 SWIG_NO_NULL_DELETER_0);
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE & %{
+#error "directorout typemap for plain reference not implemented"
+%}
+
 // plain pointer by reference
-// Note: $disown not implemented as it will lead to a memory leak of the shared_ptr instance
+// Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) TYPE *CONST& (void  *argp = 0, int res = 0, $*1_ltype temp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
   int newmem = 0;
-  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem);
   if (!SWIG_IsOK(res)) {
     %argument_fail(res, "$type", $symname, $argnum);
   }
@@ -158,7 +201,7 @@
   $1 = &temp;
 }
 %typemap(out, fragment="SWIG_null_deleter") TYPE *CONST& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner);
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -169,6 +212,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") TYPE *CONST& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+   smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) TYPE *CONST& %{
+#error "directorout typemap for plain pointer by reference not implemented"
+%}
+
 // shared_ptr by value
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *argp, int res = 0) {
   int newmem = 0;
@@ -199,6 +250,22 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (swig_argp) {
+    $result = *(%reinterpret_cast(swig_argp, $&ltype));
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, $&ltype);
+  }
+}
+
 // shared_ptr by reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -226,6 +293,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "directorout typemap for shared_ptr ref not implemented"
+%}
+
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -242,7 +317,7 @@
   }
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 && *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
   if ($owner) delete $1;
 }
@@ -254,6 +329,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "directorout typemap for pointer to shared_ptr not implemented"
+%}
+
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (void *argp, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, $*1_ltype temp = 0) {
   int newmem = 0;
@@ -267,7 +350,7 @@
   $1 = &temp;
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 && **$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -278,6 +361,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "directorout typemap for pointer ref to shared_ptr not implemented"
+%}
+
 // Typecheck typemaps
 // Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
 // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
@@ -305,5 +396,6 @@
 
 
 %template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
-%enddef
 
+
+%enddef
diff --git a/Lib/r/rrun.swg b/Lib/r/rrun.swg
index 63b7ecc..8067f0a 100644
--- a/Lib/r/rrun.swg
+++ b/Lib/r/rrun.swg
@@ -213,17 +213,15 @@
   return;
 }
 
-typedef enum {R_SWIG_EXTERNAL, R_SWIG_OWNER } R_SWIG_Owner;
-
 SWIGRUNTIME SEXP
-SWIG_MakePtr(void *ptr, const char *typeName, R_SWIG_Owner owner)
+SWIG_MakePtr(void *ptr, const char *typeName, int flags)
 {
   SEXP external, r_obj;
 
   Rf_protect(external = R_MakeExternalPtr(ptr, Rf_install(typeName), R_NilValue));
   Rf_protect(r_obj = NEW_OBJECT(MAKE_CLASS((char *) typeName)));
 
-  if(owner)
+  if (flags & SWIG_POINTER_OWN)
     R_RegisterCFinalizer(external, R_SWIG_ReferenceFinalizer);
 
   r_obj = SET_SLOT(r_obj, Rf_mkString((char *) "ref"), external);
@@ -262,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/boost_shared_ptr.i b/Lib/ruby/boost_shared_ptr.i
index 77dcece..9676bf9 100644
--- a/Lib/ruby/boost_shared_ptr.i
+++ b/Lib/ruby/boost_shared_ptr.i
@@ -58,23 +58,23 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
-%typemap(directorout,noblock=1) CONST TYPE (void *argp, int res = 0) {
+%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
   swig_ruby_owntype newmem = {0, 0};
-  res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
-  if (!SWIG_IsOK(res)) {
-    %dirout_fail(res, "$type");
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
   }
-  if (!argp) {
+  if (!swig_argp) {
     %dirout_nullref("$type");
   } else {
-    $result = *(%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)->get());
-    if (newmem.own & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *);
+    $result = *(%reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)->get());
+    if (newmem.own & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *);
   }
 }
-%typemap(directorin,noblock=1) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
-  $input = SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
-}
 
 // plain pointer
 // Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
@@ -122,8 +122,9 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
-%typemap(directorin,noblock=1) CONST TYPE * %{
-#error "directorin typemap for plain pointer not implemented"
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) CONST TYPE * %{
 #error "directorout typemap for plain pointer not implemented"
@@ -174,8 +175,9 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
-%typemap(directorin,noblock=1) CONST TYPE & %{
-#error "directorin typemap for plain reference not implemented"
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(&$1 SWIG_NO_NULL_DELETER_0);
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) CONST TYPE & %{
 #error "directorout typemap for plain reference not implemented"
@@ -199,7 +201,7 @@
   $1 = &temp;
 }
 %typemap(out, fragment="SWIG_null_deleter") TYPE *CONST& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner);
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -210,8 +212,9 @@
 #error "varout typemap not implemented"
 %}
 
-%typemap(directorin,noblock=1) TYPE *CONST& %{
-#error "directorin typemap for plain pointer by reference not implemented"
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") TYPE *CONST& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+   smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) TYPE *CONST& %{
 #error "directorout typemap for plain pointer by reference not implemented"
@@ -247,23 +250,19 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
-%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > {
-  if ($1) {
-    SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1);
-    $input = SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
-  } else {
-    $input = Qnil;
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *swig_argp, int swig_res = 0) {
+  swig_ruby_owntype newmem = {0, 0};
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
   }
-}
-%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void * swig_argp, int swig_res = 0) {
-  if (NIL_P($input)) {
-    $result = $ltype();
-  } else {
-    swig_res = SWIG_ConvertPtr($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags);
-    if (!SWIG_IsOK(swig_res)) {
-      %dirout_fail(swig_res,"$type");
-    }
+  if (swig_argp) {
     $result = *(%reinterpret_cast(swig_argp, $&ltype));
+    if (newmem.own & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, $&ltype);
   }
 }
 
@@ -294,13 +293,13 @@
 #error "varout typemap not implemented"
 %}
 
-%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & {
-  if ($1) {
-    $input = SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %newpointer_flags);
-  } else {
-    $input = Qnil;
-  }
-}
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "directorout typemap for shared_ptr ref not implemented"
+%}
 
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (void *argp, int res = 0, $*1_ltype tempshared) {
@@ -318,7 +317,7 @@
   }
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 && *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
   if ($owner) delete $1;
 }
@@ -330,13 +329,13 @@
 #error "varout typemap not implemented"
 %}
 
-%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *const& {
-  if ($1 && *$1) {
-    $input = SWIG_NewPointerObj(%as_voidptr($1), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %newpointer_flags);
-  } else {
-    $input = Qnil;
-  }
-}
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "directorout typemap for pointer to shared_ptr not implemented"
+%}
 
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (void *argp, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, $*1_ltype temp = 0) {
@@ -351,7 +350,7 @@
   $1 = &temp;
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 && **$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -362,6 +361,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "directorout typemap for pointer ref to shared_ptr not implemented"
+%}
+
 // Typecheck typemaps
 // Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
 // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
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/boost_shared_ptr.i b/Lib/scilab/boost_shared_ptr.i
index 33132f8..668bf43 100644
--- a/Lib/scilab/boost_shared_ptr.i
+++ b/Lib/scilab/boost_shared_ptr.i
@@ -58,6 +58,24 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (!swig_argp) {
+    %dirout_nullref("$type");
+  } else {
+    $result = *(%reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)->get());
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *);
+  }
+}
+
 // plain pointer
 // Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) CONST TYPE * (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) {
@@ -104,6 +122,14 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE * %{
+#error "directorout typemap for plain pointer not implemented"
+%}
+
 // plain reference
 %typemap(in) CONST TYPE & (void  *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
   int newmem = 0;
@@ -149,6 +175,14 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") CONST TYPE & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(&$1 SWIG_NO_NULL_DELETER_0);
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) CONST TYPE & %{
+#error "directorout typemap for plain reference not implemented"
+%}
+
 // plain pointer by reference
 // Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance
 %typemap(in) TYPE *CONST& (void  *argp = 0, int res = 0, $*1_ltype temp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) {
@@ -167,7 +201,7 @@
   $1 = &temp;
 }
 %typemap(out, fragment="SWIG_null_deleter") TYPE *CONST& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner);
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -178,6 +212,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1, fragment="SWIG_null_deleter") TYPE *CONST& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+   smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) TYPE *CONST& %{
+#error "directorout typemap for plain pointer by reference not implemented"
+%}
+
 // shared_ptr by value
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *argp, int res = 0) {
   int newmem = 0;
@@ -208,6 +250,22 @@
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *swig_argp, int swig_res = 0) {
+  int newmem = 0;
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res, "$type");
+  }
+  if (swig_argp) {
+    $result = *(%reinterpret_cast(swig_argp, $&ltype));
+    if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(swig_argp, $&ltype);
+  }
+}
+
 // shared_ptr by reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -235,6 +293,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & %{
+#error "directorout typemap for shared_ptr ref not implemented"
+%}
+
 // shared_ptr by pointer
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (void *argp, int res = 0, $*1_ltype tempshared) {
   int newmem = 0;
@@ -251,7 +317,7 @@
   }
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = $1 && *$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
   if ($owner) delete $1;
 }
@@ -263,6 +329,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * %{
+#error "directorout typemap for pointer to shared_ptr not implemented"
+%}
+
 // shared_ptr by pointer reference
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (void *argp, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, $*1_ltype temp = 0) {
   int newmem = 0;
@@ -276,7 +350,7 @@
   $1 = &temp;
 }
 %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = *$1 && **$1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0;
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -287,6 +361,14 @@
 #error "varout typemap not implemented"
 %}
 
+%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
+  smartarg = ($1 && *$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1) : 0;
+  $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
+%}
+%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& %{
+#error "directorout typemap for pointer ref to shared_ptr not implemented"
+%}
+
 // Typecheck typemaps
 // Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting
 // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain.
@@ -317,4 +399,3 @@
 
 
 %enddef
-
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 b21240a..723dc08 100644
--- a/Lib/typemaps/swigtype.swg
+++ b/Lib/typemaps/swigtype.swg
@@ -410,12 +410,16 @@
 
 /* directorin */
 
-%typemap(directorin,noblock=1) SWIGTYPE *, SWIGTYPE *const& {
+%typemap(directorin,noblock=1) SWIGTYPE {
+  $input = SWIG_NewPointerObj(%as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
+}
+
+%typemap(directorin,noblock=1) SWIGTYPE * {
   $input = SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags);
 }
 
-%typemap(directorin,noblock=1) SWIGTYPE {
-  $input = SWIG_NewPointerObj(%as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
+%typemap(directorin,noblock=1) SWIGTYPE *const& {
+  $input = SWIG_NewPointerObj(%as_voidptr($1), $*descriptor, %newpointer_flags);
 }
 
 %typemap(directorin,noblock=1) SWIGTYPE & {
@@ -427,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);
@@ -462,6 +467,22 @@
 }
 
 %typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) 
+  SWIGTYPE *const&(void *swig_argp, int swig_res, swig_owntype own) {
+  swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $*descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own);
+  if (!SWIG_IsOK(swig_res)) {
+    %dirout_fail(swig_res,"$type");
+  }
+  $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) {
+    SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr(*$input)));
+  }
+}
+
+%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) 
   SWIGTYPE &(void *swig_argp, int swig_res, swig_owntype own) {
   swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own);
   if (!SWIG_IsOK(swig_res)) {
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/csharp.cxx b/Source/Modules/csharp.cxx
index 7b1fca0..9b28829 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -3811,15 +3811,17 @@
 	    /* If returning a reference, initialize the pointer to a sane
 	       default - if a C# exception occurs, then the pointer returns
 	       something other than a NULL-initialized reference. */
-	    String *non_ref_type = Copy(returntype);
+	    SwigType *noref_type = SwigType_del_reference(Copy(returntype));
+	    String *noref_ltype = SwigType_lstr(noref_type, 0);
+	    String *return_ltype = SwigType_lstr(returntype, 0);
 
-	    /* Remove reference and const qualifiers */
-	    Replaceall(non_ref_type, "r.", "");
-	    Replaceall(non_ref_type, "q(const).", "");
-	    Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
-	    Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
-
-	    Delete(non_ref_type);
+	    Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
+	    Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
+	    Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
+	    Printf(w->code, "c_result = &result_default;\n");
+	    Delete(return_ltype);
+	    Delete(noref_ltype);
+	    Delete(noref_type);
 	  }
 
 	  Delete(base_typename);
@@ -3881,7 +3883,7 @@
     Swig_typemap_attach_parms("ctype", l, 0);
     Swig_typemap_attach_parms("imtype", l, 0);
     Swig_typemap_attach_parms("cstype", l, 0);
-    Swig_typemap_attach_parms("directorin", l, 0);
+    Swig_typemap_attach_parms("directorin", l, w);
     Swig_typemap_attach_parms("csdirectorin", l, 0);
     Swig_typemap_attach_parms("directorargout", l, w);
 
@@ -4062,11 +4064,11 @@
     /* header declaration, start wrapper definition */
     String *target;
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -4283,7 +4285,7 @@
       /* constructor */
       {
 	String *basetype = Getattr(parent, "classtype");
-	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
 	String *call = Swig_csuperclass_call(0, basetype, superparms);
 
 	Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
@@ -4296,7 +4298,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx
index 9a64543..451f449 100644
--- a/Source/Modules/d.cxx
+++ b/Source/Modules/d.cxx
@@ -1995,15 +1995,17 @@
 	    /* If returning a reference, initialize the pointer to a sane
 	       default - if a D exception occurs, then the pointer returns
 	       something other than a NULL-initialized reference. */
-	    String *non_ref_type = Copy(returntype);
+	    SwigType *noref_type = SwigType_del_reference(Copy(returntype));
+	    String *noref_ltype = SwigType_lstr(noref_type, 0);
+	    String *return_ltype = SwigType_lstr(returntype, 0);
 
-	    /* Remove reference and const qualifiers */
-	    Replaceall(non_ref_type, "r.", "");
-	    Replaceall(non_ref_type, "q(const).", "");
-	    Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
-	    Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
-
-	    Delete(non_ref_type);
+	    Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
+	    Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
+	    Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
+	    Printf(w->code, "c_result = &result_default;\n");
+	    Delete(return_ltype);
+	    Delete(noref_ltype);
+	    Delete(noref_type);
 	  }
 
 	  Delete(base_typename);
@@ -2058,7 +2060,7 @@
     Swig_typemap_attach_parms("ctype", l, 0);
     Swig_typemap_attach_parms("imtype", l, 0);
     Swig_typemap_attach_parms("dtype", l, 0);
-    Swig_typemap_attach_parms("directorin", l, 0);
+    Swig_typemap_attach_parms("directorin", l, w);
     Swig_typemap_attach_parms("ddirectorin", l, 0);
     Swig_typemap_attach_parms("directorargout", l, w);
 
@@ -2212,11 +2214,11 @@
     /* header declaration, start wrapper definition */
     String *target;
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -2436,7 +2438,7 @@
       /* constructor */
       {
 	String *basetype = Getattr(parent, "classtype");
-	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
 	String *call = Swig_csuperclass_call(0, basetype, superparms);
 	String *classtype = SwigType_namestr(Getattr(n, "name"));
 
@@ -2451,7 +2453,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx
index 2fdda5a..a91d5fd 100644
--- a/Source/Modules/directors.cxx
+++ b/Source/Modules/directors.cxx
@@ -15,12 +15,12 @@
 
 #include "swigmod.h"
 
-/* Swig_csuperclass_call()
+/* -----------------------------------------------------------------------------
+ * Swig_csuperclass_call()
  *
  * Generates a fully qualified method call, including the full parameter list.
  * e.g. "base::method(i, j)"
- *
- */
+ * ----------------------------------------------------------------------------- */
 
 String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
   String *call = NewString("");
@@ -44,12 +44,12 @@
   return call;
 }
 
-/* Swig_class_declaration()
+/* -----------------------------------------------------------------------------
+ * Swig_class_declaration()
  *
  * Generate the start of a class/struct declaration.
  * e.g. "class myclass"
- *
- */
+ * ----------------------------------------------------------------------------- */
 
 String *Swig_class_declaration(Node *n, String *name) {
   if (!name) {
@@ -61,18 +61,22 @@
   return result;
 }
 
+/* -----------------------------------------------------------------------------
+ * Swig_class_name()
+ * ----------------------------------------------------------------------------- */
+
 String *Swig_class_name(Node *n) {
   String *name;
   name = Copy(Getattr(n, "sym:name"));
   return name;
 }
 
-/* Swig_director_declaration()
+/* -----------------------------------------------------------------------------
+ * Swig_director_declaration()
  *
  * Generate the full director class declaration, complete with base classes.
  * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
- *
- */
+ * ----------------------------------------------------------------------------- */
 
 String *Swig_director_declaration(Node *n) {
   String *classname = Swig_class_name(n);
@@ -87,6 +91,10 @@
 }
 
 
+/* -----------------------------------------------------------------------------
+ * Swig_method_call()
+ * ----------------------------------------------------------------------------- */
+
 String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
   String *func;
   int i = 0;
@@ -115,153 +123,67 @@
   return func;
 }
 
-/* Swig_method_decl
+/* -----------------------------------------------------------------------------
+ * Swig_method_decl()
  *
- * Misnamed and misappropriated!  Taken from SWIG's type string manipulation utilities
- * and modified to generate full (or partial) type qualifiers for method declarations,
- * local variable declarations, and return value casting.  More importantly, it merges
- * parameter type information with actual parameter names to produce a complete method
- * declaration that fully mirrors the original method declaration.
- *
- * There is almost certainly a saner way to do this.
- *
- * This function needs to be cleaned up and possibly split into several smaller 
- * functions.  For instance, attaching default names to parameters should be done in a 
- * separate function.
- *
- */
+ * Return a stringified version of a C/C++ declaration.
+ * ----------------------------------------------------------------------------- */
 
-String *Swig_method_decl(SwigType *rettype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values) {
-  String *result;
-  List *elements;
-  String *element = 0, *nextelement;
-  int is_const = 0;
-  int nelements, i;
-  int is_func = 0;
+String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args) {
+  String *result = NewString("");
+  bool conversion_operator = Strstr(id, "operator ") != 0 && !return_base_type;
+
+  Parm *parm = args;
   int arg_idx = 0;
-
-  if (id) {
-    result = NewString(Char(id));
-  } else {
-    result = NewString("");
-  }
-
-  elements = SwigType_split(decl);
-  nelements = Len(elements);
-  if (nelements > 0) {
-    element = Getitem(elements, 0);
-  }
-  for (i = 0; i < nelements; i++) {
-    if (i < (nelements - 1)) {
-      nextelement = Getitem(elements, i + 1);
-    } else {
-      nextelement = 0;
+  while (parm) {
+    String *type = Getattr(parm, "type");
+    String *name = Getattr(parm, "name");
+    if (!name && Cmp(type, "void")) {
+      name = NewString("");
+      Printf(name, "arg%d", arg_idx++);
+      Setattr(parm, "name", name);
     }
-    if (SwigType_isqualifier(element)) {
-      int skip = 0;
-      DOH *q = 0;
-      if (!strip) {
-	q = SwigType_parm(element);
-	if (!Cmp(q, "const")) {
-	  is_const = 1;
-	  is_func = SwigType_isfunction(nextelement);
-	  if (is_func)
-	    skip = 1;
-	  skip = 1;
-	}
-	if (!skip) {
-	  Insert(result, 0, " ");
-	  Insert(result, 0, q);
-	}
-	Delete(q);
-      }
-    } else if (SwigType_isfunction(element)) {
-      Parm *parm;
-      String *p;
-      Append(result, "(");
-      parm = args;
-      while (parm != 0) {
-	String *type = Getattr(parm, "type");
-	String *name = Getattr(parm, "name");
-	if (!name && Cmp(type, "void")) {
-	  name = NewString("");
-	  Printf(name, "arg%d", arg_idx++);
-	  Setattr(parm, "name", name);
-	}
-	if (!name) {
-	  name = NewString("");
-	}
-	p = SwigType_str(type, name);
-	Append(result, p);
-	String *value = Getattr(parm, "value");
-	if (values && (value != 0)) {
-	  Printf(result, " = %s", value);
-	}
-	parm = nextSibling(parm);
-	if (parm != 0)
-	  Append(result, ", ");
-      }
-      Append(result, ")");
-    } else if (rettype) { // This check is intended for conversion operators to a pointer/reference which needs the pointer/reference ignoring in the declaration
-      if (SwigType_ispointer(element)) {
-	Insert(result, 0, "*");
-	if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
-	  Insert(result, 0, "(");
-	  Append(result, ")");
-	}
-      } else if (SwigType_ismemberpointer(element)) {
-	String *q;
-	q = SwigType_parm(element);
-	Insert(result, 0, "::*");
-	Insert(result, 0, q);
-	if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
-	  Insert(result, 0, "(");
-	  Append(result, ")");
-	}
-	Delete(q);
-      } else if (SwigType_isreference(element)) {
-	Insert(result, 0, "&");
-      } else if (SwigType_isarray(element)) {
-	DOH *size;
-	Append(result, "[");
-	size = SwigType_parm(element);
-	Append(result, size);
-	Append(result, "]");
-	Delete(size);
-      } else {
-	if (Strcmp(element, "v(...)") == 0) {
-	  Insert(result, 0, "...");
-	} else {
-	  String *bs = SwigType_namestr(element);
-	  Insert(result, 0, " ");
-	  Insert(result, 0, bs);
-	  Delete(bs);
-	}
-      }
-    }
-    element = nextelement;
+    parm = nextSibling(parm);
   }
 
-  Delete(elements);
+  String *rettype = Copy(decl);
+  String *quals = SwigType_pop_function_qualifiers(rettype);
+  String *qualifiers = 0;
+  if (quals)
+    qualifiers = SwigType_str(quals, 0);
 
-  if (is_const) {
-    if (is_func) {
-      Append(result, " ");
-      Append(result, "const");
-    } else {
-      Insert(result, 0, "const ");
-    }
-  }
+  String *popped_decl = SwigType_pop_function(rettype);
+  if (return_base_type)
+    Append(rettype, return_base_type);
 
-  Chop(result);
-
-  if (rettype) {
-    Insert(result, 0, " ");
+  if (!conversion_operator) {
+    SwigType *rettype_stripped = SwigType_strip_qualifiers(rettype);
     String *rtype = SwigType_str(rettype, 0);
-    Insert(result, 0, rtype);
+    Append(result, rtype);
+    if (SwigType_issimple(rettype_stripped) && return_base_type)
+      Append(result, " ");
     Delete(rtype);
+    Delete(rettype_stripped);
   }
 
+  if (id)
+    Append(result, id);
+
+  String *args_string = default_args ? ParmList_str_defaultargs(args) : ParmList_str(args);
+  Printv(result, "(", args_string, ")", NIL);
+
+  if (qualifiers)
+    Printv(result, " ", qualifiers, NIL);
+
+  // Reformat result to how it has been historically
+  Replaceall(result, ",", ", ");
+  Replaceall(result, "=", " = ");
+
+  Delete(args_string);
+  Delete(popped_decl);
+  Delete(qualifiers);
+  Delete(quals);
+  Delete(rettype);
   return result;
 }
 
@@ -272,6 +194,7 @@
  * to add an extra dynamic_cast to call the public C++ wrapper in the director class. 
  * Also for non-static protected members when the allprotected option is on.
  * ----------------------------------------------------------------------------- */
+
 void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
   // TODO: why is the storage element removed in staticmemberfunctionHandler ??
   if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) || 
@@ -290,13 +213,13 @@
   }
 }
 
-/* ------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  * Swig_director_parms_fixup()
  *
  * For each parameter in the C++ member function, copy the parameter name
  * to its "lname"; this ensures that Swig_typemap_attach_parms() will do
  * the right thing when it sees strings like "$1" in "directorin" typemaps.
- * ------------------------------------------------------------ */
+ * ----------------------------------------------------------------------------- */
 
 void Swig_director_parms_fixup(ParmList *parms) {
   Parm *p;
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 9160304..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.
@@ -3857,12 +3863,11 @@
     String *cxx_director_name = NewString("SwigDirector_");
     Append(cxx_director_name, class_name);
 
-    String *decl = Swig_method_decl(NULL, Getattr(n, "decl"),
-				    cxx_director_name, first_parm, 0, 0);
+    String *decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
     Printv(f_c_directors_h, "  ", decl, ";\n", NULL);
     Delete(decl);
 
-    decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0, 0);
+    decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
     Printv(f_c_directors, cxx_director_name, "::", decl, "\n", NULL);
     Delete(decl);
 
@@ -4587,7 +4592,7 @@
 	  Append(upcall_method_name, overname);
 	}
 	SwigType *rtype = Getattr(n, "classDirectorMethods:type");
-	String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0, 0);
+	String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0);
 	Printv(f_c_directors_h, "  ", upcall_decl, " {\n", NULL);
 	Delete(upcall_decl);
 
@@ -5035,13 +5040,13 @@
       // Declare the method for the director class.
 
       SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-      String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0, 0);
+      String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0);
       Printv(f_c_directors_h, "  virtual ", decl, NULL);
       Delete(decl);
 
       String *qname = NewString("");
       Printv(qname, "SwigDirector_", class_name, "::", Getattr(n, "name"), NULL);
-      decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0, 0);
+      decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0);
       Printv(w->def, decl, NULL);
       Delete(decl);
       Delete(qname);
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index 351870c..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);
@@ -3945,15 +3948,17 @@
 	    /* If returning a reference, initialize the pointer to a sane
 	       default - if a Java exception occurs, then the pointer returns
 	       something other than a NULL-initialized reference. */
-	    String *non_ref_type = Copy(returntype);
+	    SwigType *noref_type = SwigType_del_reference(Copy(returntype));
+	    String *noref_ltype = SwigType_lstr(noref_type, 0);
+	    String *return_ltype = SwigType_lstr(returntype, 0);
 
-	    /* Remove reference and const qualifiers */
-	    Replaceall(non_ref_type, "r.", "");
-	    Replaceall(non_ref_type, "q(const).", "");
-	    Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
-	    Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
-
-	    Delete(non_ref_type);
+	    Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
+	    Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
+	    Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
+	    Printf(w->code, "c_result = &result_default;\n");
+	    Delete(return_ltype);
+	    Delete(noref_ltype);
+	    Delete(noref_type);
 	  }
 
 	  Delete(base_typename);
@@ -4044,7 +4049,7 @@
     Swig_typemap_attach_parms("out", l, 0);
     Swig_typemap_attach_parms("jni", l, 0);
     Swig_typemap_attach_parms("jtype", l, 0);
-    Swig_typemap_attach_parms("directorin", l, 0);
+    Swig_typemap_attach_parms("directorin", l, w);
     Swig_typemap_attach_parms("javadirectorin", l, 0);
     Swig_typemap_attach_parms("directorargout", l, w);
 
@@ -4243,11 +4248,11 @@
     /* header declaration, start wrapper definition */
     String *target;
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -4461,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 {
@@ -4562,7 +4567,7 @@
       /* constructor */
       {
 	String *basetype = Getattr(parent, "classtype");
-	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
 	String *call = Swig_csuperclass_call(0, basetype, superparms);
 	String *classtype = SwigType_namestr(Getattr(n, "name"));
 
@@ -4576,7 +4581,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
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/ocaml.cxx b/Source/Modules/ocaml.cxx
index 15a13f5..d42bd46 100644
--- a/Source/Modules/ocaml.cxx
+++ b/Source/Modules/ocaml.cxx
@@ -1416,12 +1416,12 @@
     String *pclassname = NewStringf("SwigDirector_%s", classname);
     String *qualified_name = NewStringf("%s::%s", pclassname, name);
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s {", target);
     Delete(qualified_name);
     Delete(target);
     /* header declaration */
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s;", target);
     Delete(target);
 
@@ -1463,7 +1463,7 @@
       Swig_director_parms_fixup(l);
 
       Swig_typemap_attach_parms("in", l, 0);
-      Swig_typemap_attach_parms("directorin", l, 0);
+      Swig_typemap_attach_parms("directorin", l, w);
       Swig_typemap_attach_parms("directorargout", l, w);
 
       Parm *p;
@@ -1716,7 +1716,7 @@
 	Wrapper *w = NewWrapper();
 	String *call;
 	String *basetype = Getattr(parent, "classtype");
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, classname, parms, 0);
 	call = Swig_csuperclass_call(0, basetype, superparms);
 	Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
 	Delete(target);
@@ -1727,7 +1727,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, classname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx
index e64a077..0d71682 100644
--- a/Source/Modules/octave.cxx
+++ b/Source/Modules/octave.cxx
@@ -1234,7 +1234,7 @@
         Wrapper *w = NewWrapper();
         String *call;
         String *basetype = Getattr(parent, "classtype");
-        String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+        String *target = Swig_method_decl(0, decl, classname, parms, 0);
         call = Swig_csuperclass_call(0, basetype, superparms);
         Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
         Append(w->def, "}\n");
@@ -1246,7 +1246,7 @@
 
       // constructor header
       {
-        String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+        String *target = Swig_method_decl(0, decl, classname, parms, 1);
         Printf(f_directors_h, "    %s;\n", target);
         Delete(target);
       }
@@ -1310,13 +1310,13 @@
     String *pclassname = NewStringf("SwigDirector_%s", classname);
     String *qualified_name = NewStringf("%s::%s", pclassname, name);
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
 
     // header declaration
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -1393,7 +1393,7 @@
       Swig_director_parms_fixup(l);
 
       Swig_typemap_attach_parms("in", l, 0);
-      Swig_typemap_attach_parms("directorin", l, 0);
+      Swig_typemap_attach_parms("directorin", l, w);
       Swig_typemap_attach_parms("directorargout", l, w);
 
       Parm *p;
diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx
index e467610..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 */
@@ -2018,7 +2027,7 @@
 	Wrapper *w = NewWrapper();
 	String *call;
 	String *basetype = Getattr(parent, "classtype");
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, classname, parms, 0);
 	call = Swig_csuperclass_call(0, basetype, superparms);
 	Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
 	Printf(w->def, "   SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
@@ -2031,7 +2040,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, classname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
@@ -2080,12 +2089,12 @@
     String *pclassname = NewStringf("SwigDirector_%s", classname);
     String *qualified_name = NewStringf("%s::%s", pclassname, name);
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
     /* header declaration */
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -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) {
@@ -2172,7 +2180,7 @@
 
       /* remove the wrapper 'w' since it was producing spurious temps */
       Swig_typemap_attach_parms("in", l, 0);
-      Swig_typemap_attach_parms("directorin", l, 0);
+      Swig_typemap_attach_parms("directorin", l, w);
       Swig_typemap_attach_parms("directorargout", l, w);
 
       Wrapper_add_local(w, "SP", "dSP");
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index e8a7502..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.
@@ -2478,7 +2478,7 @@
 	String *call;
 	String *basetype = Getattr(parent, "classtype");
 
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, classname, parms, 0);
 	call = Swig_csuperclass_call(0, basetype, superparms);
 	Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call);
 	Append(w->def, "}");
@@ -2490,7 +2490,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, classname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
@@ -2534,12 +2534,12 @@
     String *pclassname = NewStringf("SwigDirector_%s", classname);
     String *qualified_name = NewStringf("%s::%s", pclassname, name);
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
     /* header declaration */
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -2618,7 +2618,7 @@
 
       /* remove the wrapper 'w' since it was producing spurious temps */
       Swig_typemap_attach_parms("in", l, 0);
-      Swig_typemap_attach_parms("directorin", l, 0);
+      Swig_typemap_attach_parms("directorin", l, w);
       Swig_typemap_attach_parms("directorargout", l, w);
 
       Parm *p;
diff --git a/Source/Modules/php5.cxx b/Source/Modules/php5.cxx
index d9cc7b4..4710aa0 100644
--- a/Source/Modules/php5.cxx
+++ b/Source/Modules/php5.cxx
@@ -2466,7 +2466,7 @@
 
 	// We put TSRMLS_DC after the self parameter in order to cope with
 	// any default parameters.
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, classname, parms, 0);
 	const char * p = Char(target);
 	const char * comma = strchr(p, ',');
 	int ins = comma ? (int)(comma - p) : Len(target) - 1;
@@ -2485,7 +2485,7 @@
       {
 	// We put TSRMLS_DC after the self parameter in order to cope with
 	// any default parameters.
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, classname, parms, 1);
 	const char * p = Char(target);
 	const char * comma = strchr(p, ',');
 	int ins = comma ? (int)(comma - p) : Len(target) - 1;
@@ -2534,12 +2534,12 @@
     String *pclassname = NewStringf("SwigDirector_%s", classname);
     String *qualified_name = NewStringf("%s::%s", pclassname, name);
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
     /* header declaration */
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -2620,7 +2620,7 @@
 
       /* remove the wrapper 'w' since it was producing spurious temps */
       Swig_typemap_attach_parms("in", l, 0);
-      Swig_typemap_attach_parms("directorin", l, 0);
+      Swig_typemap_attach_parms("directorin", l, w);
       Swig_typemap_attach_parms("directorargout", l, w);
 
       Parm *p;
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 55f1e38..4a1b475 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -3733,7 +3733,7 @@
 	Wrapper *w = NewWrapper();
 	String *call;
 	String *basetype = Getattr(parent, "classtype");
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, classname, parms, 0);
 	call = Swig_csuperclass_call(0, basetype, superparms);
 	Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
 	Printf(w->def, "   SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
@@ -3746,7 +3746,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, classname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
@@ -5362,12 +5362,12 @@
   String *pclassname = NewStringf("SwigDirector_%s", classname);
   String *qualified_name = NewStringf("%s::%s", pclassname, name);
   SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-  target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+  target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
   Printf(w->def, "%s", target);
   Delete(qualified_name);
   Delete(target);
   /* header declaration */
-  target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+  target = Swig_method_decl(rtype, decl, name, l, 1);
   Printf(declaration, "    virtual %s", target);
   Delete(target);
 
@@ -5451,7 +5451,7 @@
 
     /* remove the wrapper 'w' since it was producing spurious temps */
     Swig_typemap_attach_parms("in", l, 0);
-    Swig_typemap_attach_parms("directorin", l, 0);
+    Swig_typemap_attach_parms("directorin", l, w);
     Swig_typemap_attach_parms("directorargout", l, w);
 
     Parm *p;
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index bd3395a..0fe730c 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -637,7 +637,7 @@
       Replaceall(tm, "$1", name);
       Replaceall(tm, "$result", "r_tmp");
       replaceRClass(tm, Getattr(p,"type"));
-      Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+      Replaceall(tm,"$owner", "0");
       Delete(lstr);
     } 
     
@@ -697,7 +697,7 @@
       Replaceall(tm,"$input", "r_swig_cb_data->retValue");
       Replaceall(tm,"$target", Swig_cresult_name());
       replaceRClass(tm, rettype);
-      Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+      Replaceall(tm,"$owner", "0");
       Replaceall(tm,"$disown","0");
       Printf(f->code, "%s\n", tm);
     }
@@ -2062,7 +2062,7 @@
       Replaceall(tm,"$n", pos); // The position into which to store the answer.
       Replaceall(tm,"$arg", Getattr(p, "emit:input"));
       Replaceall(tm,"$input", Getattr(p, "emit:input"));
-      Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+      Replaceall(tm,"$owner", "0");
 
 
       Printf(outargs, "%s\n", tm);
@@ -2087,9 +2087,9 @@
     replaceRClass(tm, retType);
 
     if (GetFlag(n,"feature:new")) {
-      Replaceall(tm, "$owner", "R_SWIG_OWNER");
+      Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
     } else {
-      Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+      Replaceall(tm,"$owner", "0");
     }
 
 #if 0
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
index 25988d6..69a849d 100644
--- a/Source/Modules/ruby.cxx
+++ b/Source/Modules/ruby.cxx
@@ -2925,7 +2925,7 @@
 	Wrapper *w = NewWrapper();
 	String *call;
 	String *basetype = Getattr(parent, "classtype");
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+	String *target = Swig_method_decl(0, decl, classname, parms, 0);
 	call = Swig_csuperclass_call(0, basetype, superparms);
 	Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
 	Delete(target);
@@ -2936,7 +2936,7 @@
 
       /* constructor header */
       {
-	String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+	String *target = Swig_method_decl(0, decl, classname, parms, 1);
 	Printf(f_directors_h, "    %s;\n", target);
 	Delete(target);
       }
@@ -3102,12 +3102,12 @@
     String *pclassname = NewStringf("SwigDirector_%s", classname);
     String *qualified_name = NewStringf("%s::%s", pclassname, name);
     SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
-    target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+    target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
     Printf(w->def, "%s", target);
     Delete(qualified_name);
     Delete(target);
     /* header declaration */
-    target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+    target = Swig_method_decl(rtype, decl, name, l, 1);
     Printf(declaration, "    virtual %s", target);
     Delete(target);
 
@@ -3188,7 +3188,7 @@
       Swig_director_parms_fixup(l);
 
       Swig_typemap_attach_parms("in", l, 0);
-      Swig_typemap_attach_parms("directorin", l, 0);
+      Swig_typemap_attach_parms("directorin", l, w);
       Swig_typemap_attach_parms("directorargout", l, w);
 
       char source[256];
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index 34763cc..31b506f 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -385,7 +385,7 @@
 String *Swig_class_declaration(Node *n, String *name);
 String *Swig_class_name(Node *n);
 String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms);
-String *Swig_method_decl(SwigType *rtype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values);
+String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args);
 String *Swig_director_declaration(Node *n);
 void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
 void Swig_director_parms_fixup(ParmList *parms);
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
index 409e28f..a99a795 100644
--- a/Source/Swig/typesys.c
+++ b/Source/Swig/typesys.c
@@ -1542,7 +1542,7 @@
 	}
       } else {
 	if (SwigType_issimple(td) && SwigType_istemplate(td)) {
-	  use_wrapper = !n || !GetFlag(n, "feature:novaluewrapper");
+	  use_wrapper = 1;
 	}
       }
     }
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