Fix crash Java directors

Further crash fixes when using OUTPUT and INOUT typemaps in typemaps.i and
passing NULL pointers in C++ to director method overloaded and implemented
in Java.

Don't create the one element array in these directorin typemaps if the
input is a NULL pointer, that is, translate a NULL C++ pointer into a
null Java object.

Also add some missing JNI error checks in these typemaps.
diff --git a/CHANGES.current b/CHANGES.current
index 1f25e91..85d1ffe 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@
 Version 4.0.0 (in progress)
 ===========================
 
+2018-08-12: brianhatwood,wsfulton
+            [Java] #1303 #1304 Fix crash in directors when using OUTPUT and INOUT typemaps in typemaps.i and
+            passing NULL pointers in C++ to director method overloaded and implemented in Java.
+
 2018-08-10: wsfulton
             [Python] #1293 Improve TypeError message inconsistencies between default and fastdispatch
             mode when handling overloaded C++ functions. Previously the error message did not always
diff --git a/Examples/test-suite/java/java_director_typemaps_ptr_runme.java b/Examples/test-suite/java/java_director_typemaps_ptr_runme.java
index fdd0bfd..c387270 100644
--- a/Examples/test-suite/java/java_director_typemaps_ptr_runme.java
+++ b/Examples/test-suite/java/java_director_typemaps_ptr_runme.java
@@ -16,8 +16,11 @@
 
 
   public static void main(String argv[]) {
-    Quux quux = new java_director_typemaps_ptr_MyQuux();
+    java_director_typemaps_ptr_MyQuux myquux = new java_director_typemaps_ptr_MyQuux();
+    Quux quux = myquux;
     quux.etest();
+    myquux.testing_nulls = true;
+    quux.nulltest();
   }
 }
 
@@ -25,6 +28,7 @@
   public java_director_typemaps_ptr_MyQuux() {
     super();
   }
+  public boolean testing_nulls = false;
 
   public void director_method_output(
       boolean[] bool_arg,
@@ -47,19 +51,34 @@
       float[] float_arg,
       double[] double_arg)
   {
-    bool_arg[0] = true;
-    signed_char_arg[0] = 1;
-    unsigned_char_arg[0] = 2;
-    short_arg[0] = 3;
-    unsigned_short_arg[0] = 4;
-    int_arg[0] = 5;
-    unsigned_int_arg[0] = 6;
-    long_arg[0] = 7;
-    unsigned_long_arg[0] = 8;
-    long_long_arg[0] = 9;
-    // unsigned_long_long_arg[0] = 10;
-    float_arg[0] = 11;
-    double_arg[0] = 12;
+    if (testing_nulls) {
+      if (bool_arg != null) throw new RuntimeException("not null bool_arg");
+      if (signed_char_arg != null)  throw new RuntimeException("not null signed_char_arg");
+      if (unsigned_char_arg != null)  throw new RuntimeException("not null unsigned_char_arg");
+      if (short_arg != null)  throw new RuntimeException("not null short_arg");
+      if (unsigned_short_arg != null)  throw new RuntimeException("not null unsigned_short_arg");
+      if (int_arg != null)  throw new RuntimeException("not null int_arg");
+      if (unsigned_int_arg != null)  throw new RuntimeException("not null unsigned_int_arg");
+      if (long_arg != null)  throw new RuntimeException("not null long_arg");
+      if (unsigned_long_arg != null)  throw new RuntimeException("not null unsigned_long_arg");
+      if (long_long_arg != null)  throw new RuntimeException("not null long_long_arg");
+      // if (unsigned_long_long_arg != null)  throw new RuntimeException("not null unsigned_long_long_arg");
+      if (float_arg != null)  throw new RuntimeException("not null float_arg");
+      if (double_arg != null)  throw new RuntimeException("not null double_arg");
+    }
+    if (bool_arg != null) bool_arg[0] = true;
+    if (signed_char_arg != null) signed_char_arg[0] = 1;
+    if (unsigned_char_arg != null) unsigned_char_arg[0] = 2;
+    if (short_arg != null) short_arg[0] = 3;
+    if (unsigned_short_arg != null) unsigned_short_arg[0] = 4;
+    if (int_arg != null) int_arg[0] = 5;
+    if (unsigned_int_arg != null) unsigned_int_arg[0] = 6;
+    if (long_arg != null) long_arg[0] = 7;
+    if (unsigned_long_arg != null) unsigned_long_arg[0] = 8;
+    if (long_long_arg != null) long_long_arg[0] = 9;
+    // if (unsigned_long_long_arg != null) unsigned_long_long_arg[0] = 10;
+    if (float_arg != null) float_arg[0] = 11;
+    if (double_arg != null) double_arg[0] = 12;
   }
 
   public void director_method_inout(
@@ -83,34 +102,49 @@
       float[] float_arg,
       double[] double_arg)
   {
-    if (bool_arg[0]) throw new RuntimeException("unexpected value for bool_arg");
+    if (testing_nulls) {
+      if (bool_arg != null) throw new RuntimeException("not null bool_arg");
+      if (signed_char_arg != null)  throw new RuntimeException("not null signed_char_arg");
+      if (unsigned_char_arg != null)  throw new RuntimeException("not null unsigned_char_arg");
+      if (short_arg != null)  throw new RuntimeException("not null short_arg");
+      if (unsigned_short_arg != null)  throw new RuntimeException("not null unsigned_short_arg");
+      if (int_arg != null)  throw new RuntimeException("not null int_arg");
+      if (unsigned_int_arg != null)  throw new RuntimeException("not null unsigned_int_arg");
+      if (long_arg != null)  throw new RuntimeException("not null long_arg");
+      if (unsigned_long_arg != null)  throw new RuntimeException("not null unsigned_long_arg");
+      if (long_long_arg != null)  throw new RuntimeException("not null long_long_arg");
+      // if (unsigned_long_long_arg != null)  throw new RuntimeException("not null unsigned_long_long_arg");
+      if (float_arg != null)  throw new RuntimeException("not null float_arg");
+      if (double_arg != null)  throw new RuntimeException("not null double_arg");
+    } else {
+      if (bool_arg[0]) throw new RuntimeException("unexpected value for bool_arg");
+      if (signed_char_arg[0] != 101)  throw new RuntimeException("unexpected value for signed_char_arg");
+      if (unsigned_char_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_char_arg");
+      if (short_arg[0] != 101)  throw new RuntimeException("unexpected value for short_arg");
+      if (unsigned_short_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_short_arg");
+      if (int_arg[0] != 101)  throw new RuntimeException("unexpected value for int_arg");
+      if (unsigned_int_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_int_arg");
+      if (long_arg[0] != 101)  throw new RuntimeException("unexpected value for long_arg");
+      if (unsigned_long_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_long_arg");
+      if (long_long_arg[0] != 101)  throw new RuntimeException("unexpected value for long_long_arg");
+      // if (unsigned_long_long_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_long_long_arg");
+      if (float_arg[0] != 101)  throw new RuntimeException("unexpected value for float_arg");
+      if (double_arg[0] != 101)  throw new RuntimeException("unexpected value for double_arg");
+    }
 
-    if (signed_char_arg[0] != 101)  throw new RuntimeException("unexpected value for signed_char_arg");
-    if (unsigned_char_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_char_arg");
-    if (short_arg[0] != 101)  throw new RuntimeException("unexpected value for short_arg");
-    if (unsigned_short_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_short_arg");
-    if (int_arg[0] != 101)  throw new RuntimeException("unexpected value for int_arg");
-    if (unsigned_int_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_int_arg");
-    if (long_arg[0] != 101)  throw new RuntimeException("unexpected value for long_arg");
-    if (unsigned_long_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_long_arg");
-    if (long_long_arg[0] != 101)  throw new RuntimeException("unexpected value for long_long_arg");
-    // if (unsigned_long_long_arg[0] != 101)  throw new RuntimeException("unexpected value for unsigned_long_long_arg");
-    if (float_arg[0] != 101)  throw new RuntimeException("unexpected value for float_arg");
-    if (double_arg[0] != 101)  throw new RuntimeException("unexpected value for double_arg");
-
-    bool_arg[0] = false;
-    signed_char_arg[0] = 11;
-    unsigned_char_arg[0] = 12;
-    short_arg[0] = 13;
-    unsigned_short_arg[0] = 14;
-    int_arg[0] = 15;
-    unsigned_int_arg[0] = 16;
-    long_arg[0] = 17;
-    unsigned_long_arg[0] = 18;
-    long_long_arg[0] = 19;
-    // unsigned_long_long_arg[0] = 110;
-    float_arg[0] = 111;
-    double_arg[0] = 112;
+    if (bool_arg != null) bool_arg[0] = false;
+    if (signed_char_arg != null) signed_char_arg[0] = 11;
+    if (unsigned_char_arg != null) unsigned_char_arg[0] = 12;
+    if (short_arg != null) short_arg[0] = 13;
+    if (unsigned_short_arg != null) unsigned_short_arg[0] = 14;
+    if (int_arg != null) int_arg[0] = 15;
+    if (unsigned_int_arg != null) unsigned_int_arg[0] = 16;
+    if (long_arg != null) long_arg[0] = 17;
+    if (unsigned_long_arg != null) unsigned_long_arg[0] = 18;
+    if (long_long_arg != null) long_long_arg[0] = 19;
+    // if (unsigned_long_long_arg != null) unsigned_long_long_arg[0] = 110;
+    if (float_arg != null) float_arg[0] = 111;
+    if (double_arg != null) double_arg[0] = 112;
   }
 
   public void director_method_nameless_args(
@@ -134,18 +168,33 @@
       float[] float_arg,
       double[] double_arg)
   {
-    bool_arg[0] = true;
-    signed_char_arg[0] = 12;
-    unsigned_char_arg[0] = 13;
-    short_arg[0] = 14;
-    unsigned_short_arg[0] = 15;
-    int_arg[0] = 16;
-    unsigned_int_arg[0] = 17;
-    long_arg[0] = 18;
-    unsigned_long_arg[0] = 19;
-    long_long_arg[0] = 20;
-    // unsigned_long_long_arg[0] = 111;
-    float_arg[0] = 112;
-    double_arg[0] = 113;
+    if (testing_nulls) {
+      if (bool_arg != null) throw new RuntimeException("not null bool_arg");
+      if (signed_char_arg != null)  throw new RuntimeException("not null signed_char_arg");
+      if (unsigned_char_arg != null)  throw new RuntimeException("not null unsigned_char_arg");
+      if (short_arg != null)  throw new RuntimeException("not null short_arg");
+      if (unsigned_short_arg != null)  throw new RuntimeException("not null unsigned_short_arg");
+      if (int_arg != null)  throw new RuntimeException("not null int_arg");
+      if (unsigned_int_arg != null)  throw new RuntimeException("not null unsigned_int_arg");
+      if (long_arg != null)  throw new RuntimeException("not null long_arg");
+      if (unsigned_long_arg != null)  throw new RuntimeException("not null unsigned_long_arg");
+      if (long_long_arg != null)  throw new RuntimeException("not null long_long_arg");
+      // if (unsigned_long_long_arg != null)  throw new RuntimeException("not null unsigned_long_long_arg");
+      if (float_arg != null)  throw new RuntimeException("not null float_arg");
+      if (double_arg != null)  throw new RuntimeException("not null double_arg");
+    }
+    if (bool_arg != null) bool_arg[0] = true;
+    if (signed_char_arg != null) signed_char_arg[0] = 12;
+    if (unsigned_char_arg != null) unsigned_char_arg[0] = 13;
+    if (short_arg != null) short_arg[0] = 14;
+    if (unsigned_short_arg != null) unsigned_short_arg[0] = 15;
+    if (int_arg != null) int_arg[0] = 16;
+    if (unsigned_int_arg != null) unsigned_int_arg[0] = 17;
+    if (long_arg != null) long_arg[0] = 18;
+    if (unsigned_long_arg != null) unsigned_long_arg[0] = 19;
+    if (long_long_arg != null) long_long_arg[0] = 20;
+    // if (unsigned_long_long_arg != null) unsigned_long_long_arg[0] = 111;
+    if (float_arg != null) float_arg[0] = 112;
+    if (double_arg != null) double_arg[0] = 113;
   }
 }
diff --git a/Examples/test-suite/java_director_typemaps_ptr.i b/Examples/test-suite/java_director_typemaps_ptr.i
index dcae1d8..578001a 100644
--- a/Examples/test-suite/java_director_typemaps_ptr.i
+++ b/Examples/test-suite/java_director_typemaps_ptr.i
@@ -344,6 +344,71 @@
     verify(floatarg_inout == 112);
     verify(doublearg_inout == 113);
   }
+
+  void nulltest() {
+    director_method_output(
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       // NULL,
+
+       NULL,
+       NULL);
+
+    director_method_inout(
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       // NULL,
+
+       NULL,
+       NULL);
+
+    director_method_nameless_args(
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       NULL,
+
+       NULL,
+       // NULL,
+
+       NULL,
+       NULL);
+  }
 };
 %}
 
diff --git a/Lib/java/typemaps.i b/Lib/java/typemaps.i
index fd7c267..e130c19 100644
--- a/Lib/java/typemaps.i
+++ b/Lib/java/typemaps.i
@@ -212,8 +212,16 @@
   JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &jvalue);
 }
 
-%typemap(directorin,descriptor=JNIDESC) TYPE &OUTPUT, TYPE *OUTPUT %{
+%typemap(directorin,descriptor=JNIDESC) TYPE &OUTPUT %{
   $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+  if (!$input) return $null;
+  Swig::LocalRefGuard $1_refguard(jenv, $input); %}
+
+%typemap(directorin,descriptor=JNIDESC) TYPE *OUTPUT %{
+  if ($1) {
+    $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+    if (!$input) return $null;
+  }
   Swig::LocalRefGuard $1_refguard(jenv, $input); %}
 
 %typemap(directorargout, noblock=1) TYPE &OUTPUT
@@ -225,9 +233,11 @@
 
 %typemap(directorargout, noblock=1) TYPE *OUTPUT
 {
-  JNITYPE $1_jvalue;
-  JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
-  if ($result) *$result = ($*1_ltype)$1_jvalue;
+  if ($result) {
+    JNITYPE $1_jvalue;
+    JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+    *$result = ($*1_ltype)$1_jvalue;
+  }
 }
 
 %typemap(typecheck) TYPE *OUTPUT = TYPECHECKTYPE;
@@ -273,9 +283,11 @@
 
 %typemap(directorargout, noblock=1) bool *OUTPUT
 {
-  jboolean $1_jvalue;
-  JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
-  *$result = $1_jvalue ? true : false;
+  if ($result) {
+    jboolean $1_jvalue;
+    JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+    *$result = $1_jvalue ? true : false;
+  }
 }
 
 
@@ -388,14 +400,18 @@
 
 %typemap(directorin,descriptor=JNIDESC) TYPE &INOUT %{
   $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+  if (!$input) return $null;
   JNITYPE $1_jvalue = (JNITYPE)$1;
   JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
   Swig::LocalRefGuard $1_refguard(jenv, $input); %}
 
 %typemap(directorin,descriptor=JNIDESC) TYPE *INOUT %{
-  $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
-  JNITYPE $1_jvalue = (JNITYPE)*$1;
-  JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+  if ($1) {
+    $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
+    if (!$input) return $null;
+    JNITYPE $1_jvalue = (JNITYPE)*$1;
+    JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+  }
   Swig::LocalRefGuard $1_refguard(jenv, $input); %}
 
 %typemap(directorargout, noblock=1) TYPE &INOUT
@@ -406,8 +422,11 @@
 
 %typemap(directorargout, noblock=1) TYPE *INOUT
 {
-  JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
-  *$result = ($*1_ltype)$1_jvalue;
+  if ($result) {
+    JNITYPE $1_jvalue;
+    JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+    *$result = ($*1_ltype)$1_jvalue;
+  }
 }
 
 %typemap(typecheck) TYPE *INOUT = TYPECHECKTYPE;
@@ -459,8 +478,11 @@
 
 %typemap(directorargout, noblock=1) bool *INOUT
 {
-  JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
-  *$result = $1_jvalue ? true : false;
+  if ($result) {
+    jboolean $1_jvalue;
+    JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
+    *$result = $1_jvalue ? true : false;
+  }
 }