diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8fb86a087412fff33a1aa19867467424e2b29e52..599aa2ec9a9fabaf0a91bb9ecb761978dbb30037 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@ jni# Aparapi jni Changelog
 
 ## 1.3.2
 
+* Fixed local arrays handling 1D and ND, to cope with arrays resizing across kernel executions
+
 ## 1.3.1
 
 * Fixed JVM crash with multi-dimensional arrays in Local memory (2D and 3D local arrays are now supported)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 30c0be3ef09fa7d4df7296f8ec32b765eaead2d0..c3c9e4cd4ad59f1c273ed1a20d690f543d45a4d4 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -27,4 +27,5 @@ Below are some of the specific details of various contributions.
 * Steven Libby and Ryan Lamothe for #10 (Support for OpenMP, major refactoring cleanup and support for multidim arrays) March 28th 2013
 * Paul Miner issue #61 and #115 (JTP Speed up and fixes to explicit puts) June 13th 2013
 & lgalluci for his fix for issue #121 (incorrect toString for 3D ranges) July 6th 2013
-* Luis Mendes Issue #51 JVM crash when using multi-dimensional local arrays (refs #51)
\ No newline at end of file
+* Luis Mendes Issue #51 JVM crash when using multi-dimensional local arrays (refs #51)
+* Luis Mendes submitted local arrays handling 1D and ND, to cope with arrays resizing across kernel executions
\ No newline at end of file
diff --git a/configure.ac b/configure.ac
index e9ce64ef60c584126f38174051b4661779c412dd..ef0d3b9ac8c2a165aabd759f67ff4b5564a56aa0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([libaparapi], [1.2.1], [syncleus@syncleus.com])
+AC_INIT([libaparapi], [1.3.2], [syncleus@syncleus.com])
 AC_ENABLE_SHARED(yes)
 AC_ENABLE_STATIC(no)
 LT_INIT
diff --git a/src/cpp/runKernel/Aparapi.cpp b/src/cpp/runKernel/Aparapi.cpp
index fe6139acabf0afc2164e655ccfaf2beec43ed1e1..c346271d2912e88d11a844fb29cd94d91791a82f 100644
--- a/src/cpp/runKernel/Aparapi.cpp
+++ b/src/cpp/runKernel/Aparapi.cpp
@@ -273,7 +273,7 @@ jint updateNonPrimitiveReferences(JNIEnv *jenv, jobject jobj, JNIContext* jniCon
 
          //this won't be a problem with the aparapi buffers because
          //we need to copy them every time anyway
-         if (!arg->isPrimitive() && !arg->isAparapiBuffer()) {
+         if (!arg->isPrimitive() && !arg->isLocal() && !arg->isAparapiBuffer()) {
             // Following used for all primitive arrays, object arrays and nio Buffers
             jarray newRef = (jarray)jenv->GetObjectField(arg->javaArg, KernelArg::javaArrayFieldID);
             if (config->isVerbose()){
@@ -319,10 +319,10 @@ jint updateNonPrimitiveReferences(JNIEnv *jenv, jobject jobj, JNIContext* jniCon
                }
 
                // Save the lengthInBytes which was set on the java side
-               arg->syncSizeInBytes(jenv);
+               int lengthInBytes = arg->getSizeInBytes(jenv);
 
                if (config->isVerbose()){
-                  fprintf(stderr, "updateNonPrimitiveReferences, args[%d].lengthInBytes=%d\n", i, arg->arrayBuffer->lengthInBytes);
+                  fprintf(stderr, "updateNonPrimitiveReferences, args[%d].lengthInBytes=%d\n", i, lengthInBytes);
                }
             } // object has changed
          }
@@ -371,6 +371,7 @@ void updateArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argP
    else if (arg->isMutableByKernel()) mask |= CL_MEM_WRITE_ONLY;
    arg->arrayBuffer->memMask = mask;
 
+   arg->arrayBuffer->syncMinimalParams(jenv, arg);
    if (config->isVerbose()) {
       strcpy(arg->arrayBuffer->memSpec,"CL_MEM_USE_HOST_PTR");
       if (mask & CL_MEM_READ_WRITE) strcat(arg->arrayBuffer->memSpec,"|CL_MEM_READ_WRITE");
@@ -396,7 +397,6 @@ void updateArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argP
    // Add the array length if needed
    if (arg->usesArrayLength()) {
       argPos++;
-      arg->syncJavaArrayLength(jenv);
 
       status = clSetKernelArg(jniContext->kernel, argPos, sizeof(jint), &(arg->arrayBuffer->length));
       if(status != CL_SUCCESS) throw CLException(status,"clSetKernelArg (array length)");
@@ -644,15 +644,39 @@ void updateWriteEvents(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int
 void processLocalArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argPos, int argIdx) {
 
    cl_int status = CL_SUCCESS;
-   // what if local buffer size has changed?  We need a check for resize here.
-   if (jniContext->firstRun) {
+
+   cl_uint arrayLength;
+   int lengthInBytes;
+
+   arg->arrayBuffer->getMinimalParams(jenv, arg, arrayLength, lengthInBytes);
+
+   if (config->isVerbose()) {
+       fprintf(stderr, "runKernel local array arg %d %s - new[elems: %d, bytes: %d], old[elems: %d, bytes: %d]\n",
+               argIdx, arg->name, arrayLength, lengthInBytes, arg->arrayBuffer->length, arg->arrayBuffer->lengthInBytes);
+   }
+
+   bool changed = false;
+   if (lengthInBytes != arg->arrayBuffer->lengthInBytes) {
+	   changed = true;
+   }
+
+   if (!changed && arg->usesArrayLength() && arrayLength != arg->arrayBuffer->length) {
+       changed = true;
+   }
+
+
+   if (jniContext->firstRun || changed) {
+	  if (config->isVerbose()) {
+		  fprintf(stderr, "runKernel local array arg %d %s resize detected - adjusting args\n", argIdx, arg->name);
+	  }
+
+	  arg->arrayBuffer->syncMinimalParams(jenv, arg);
+
       status = arg->setLocalBufferArg(jenv, argIdx, argPos, config->isVerbose());
       if(status != CL_SUCCESS) throw CLException(status,"clSetKernelArg() (local)");
 
       // Add the array length if needed
       if (arg->usesArrayLength()) {
-         arg->syncJavaArrayLength(jenv);
-
          status = clSetKernelArg(jniContext->kernel, argPos, sizeof(jint), &(arg->arrayBuffer->length));
 
          if (config->isVerbose()){
@@ -660,9 +684,12 @@ void processLocalArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int
          }
 
          if(status != CL_SUCCESS) throw CLException(status,"clSetKernelArg (array length)");
-
       }
    } else {
+      if (config->isVerbose()) {
+         fprintf(stderr, "runKernel local array arg %d %s no resize detected - keeping args\n", argIdx, arg->name);
+      }
+
       // Keep the arg position in sync if no updates were required
       if (arg->usesArrayLength()) {
          argPos++;
@@ -684,14 +711,43 @@ void processLocalArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int
 void processLocalBuffer(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argPos, int argIdx) {
 
    cl_int status = CL_SUCCESS;
+
+   cl_uint numDims;
+   cl_uint dims[3];
+   int lengthInBytes;
+   arg->aparapiBuffer->getMinimalParams(jenv, arg, numDims, dims, lengthInBytes);
+
+   if (config->isVerbose()) {
+       fprintf(stderr, "runKernel local NDarray arg %d %s - new[bytes: %d], old[bytes: %d]\n",
+               argIdx, arg->name, lengthInBytes, arg->aparapiBuffer->lengthInBytes);
+   }
+
+
+   bool changed = false;
+   if (lengthInBytes != arg->aparapiBuffer->lengthInBytes) {
+	   changed = true;
+   }
+
+   if (!changed && arg->usesArrayLength()) {
+	   for (int i = 0; i < numDims; i++) {
+		   if (dims[i] != arg->aparapiBuffer->lens[i]) {
+			   changed = true;
+			   break;
+		   }
+	   }
+   }
+
    // what if local buffer size has changed?  We need a check for resize here.
-   if (jniContext->firstRun) {
+   if (jniContext->firstRun || changed) {
+	  if (config->isVerbose()) {
+		  fprintf(stderr, "runKernel local NDarray arg %d %s resize detected - adjusting args\n", argIdx, arg->name);
+	  }
+
 	  //To retrieve all fields of aparapiBuffer from Java for this local arg.
-	  arg->aparapiBuffer->flatten(jenv,arg);
+	  arg->aparapiBuffer->syncMinimalParams(jenv, arg);
 
       status = arg->setLocalAparapiBufferArg(jenv, argIdx, argPos, config->isVerbose());
       if(status != CL_SUCCESS) {
-    	  arg->aparapiBuffer->deleteBuffer(arg);
     	  throw CLException(status,"clSetKernelArg() (local)");
       }
 
@@ -699,36 +755,20 @@ void processLocalBuffer(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, in
       if (arg->usesArrayLength()) {
          for(int i = 0; i < arg->aparapiBuffer->numDims; i++)
          {
-        	 if (arg->aparapiBuffer->lens == NULL) {
-				 std::string str = "runKernel arg " + patch::to_string(argIdx) + " " + arg->name +
-				 " - AparapiBuffer lens field is NULL at dim " + patch::to_string(i+1) + " of " +
-				 patch::to_string(arg->aparapiBuffer->numDims) + "\n";
-				 arg->aparapiBuffer->deleteBuffer(arg);
-				 throw CLException(CL_INVALID_VALUE, str.c_str());
-			  }
 			  int length = arg->aparapiBuffer->lens[i];
 			  argPos++;
 			  status = clSetKernelArg(jniContext->kernel, argPos, sizeof(cl_uint), &length);
 			  if(status != CL_SUCCESS) {
-				  arg->aparapiBuffer->deleteBuffer(arg);
 				  throw CLException(status,"clSetKernelArg (buffer length)");
 			  }
 			  if (config->isVerbose()){
 				 fprintf(stderr, "runKernel arg %d %s, length = %d\n", argIdx, arg->name, length);
 			  }
 
-			  if (arg->aparapiBuffer->offsets == NULL) {
-				 std::string str = "runKernel arg " + patch::to_string(argIdx) + " " + arg->name +
-				 " - AparapiBuffer offsets field is NULL at dim " + patch::to_string(i+1) + " of " +
-				 patch::to_string(arg->aparapiBuffer->numDims) + "\n";
-				 arg->aparapiBuffer->deleteBuffer(arg);
-				 throw CLException(CL_INVALID_VALUE, str.c_str());
-			  }
 			  int offset = arg->aparapiBuffer->offsets[i];
 			  argPos++;
 			  status = clSetKernelArg(jniContext->kernel, argPos, sizeof(cl_uint), &offset);
 			  if(status != CL_SUCCESS) {
-				  arg->aparapiBuffer->deleteBuffer(arg);
 				  throw CLException(status,"clSetKernelArg (buffer offset)");
 			  }
 			  if (config->isVerbose()){
@@ -736,10 +776,14 @@ void processLocalBuffer(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, in
 			  }
          }
       }
-   } else {
+  } else {
+	  if (config->isVerbose()) {
+		  fprintf(stderr, "runKernel local NDarray arg %d %s no resize detected - keeping args\n", argIdx, arg->name);
+	  }
+
       // Keep the arg position in sync if no updates were required
       if (arg->usesArrayLength()) {
-         argPos += arg->aparapiBuffer->numDims;
+         argPos += arg->aparapiBuffer->numDims*2;
       }
    }
 }
@@ -985,14 +1029,6 @@ int getReadEvents(JNIEnv* jenv, JNIContext* jniContext) {
    for (int i=0; i< jniContext->argc; i++) {
       KernelArg *arg = jniContext->args[i];
 
-      if (arg->isLocal() && arg->isAparapiBuffer()) {
-    	  if (config->isVerbose()) {
-    		  fprintf(stderr, "Freeing local aparapi buffer for arg %d", arg->name);
-    	  }
-    	  arg->aparapiBuffer->deleteBuffer(arg);
-    	  continue;
-      }
-
       if (arg->needToEnqueueRead()){
          if (arg->isConstant()){
             fprintf(stderr, "reading %s\n", arg->name);
diff --git a/src/cpp/runKernel/AparapiBuffer.cpp b/src/cpp/runKernel/AparapiBuffer.cpp
index 1776a8aa0b644f1ededce69fd637ab738f074dff..93ab2a7a5f3efbbdc78d2a8cfba449286f357fb3 100644
--- a/src/cpp/runKernel/AparapiBuffer.cpp
+++ b/src/cpp/runKernel/AparapiBuffer.cpp
@@ -21,34 +21,34 @@
    following conditions are met:
 
    Redistributions of source code must retain the above copyright notice, this list of conditions and the following
-   disclaimer.
+   disclaimer. 
 
    Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
-   disclaimer in the documentation and/or other materials provided with the distribution.
+   disclaimer in the documentation and/or other materials provided with the distribution. 
 
    Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
-   derived from this software without specific prior written permission.
+   derived from this software without specific prior written permission. 
 
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
    If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export
-   laws, including but not limited to the U.S. Export Administration Regulations ("EAR"), (15 C.F.R. Sections 730
+   laws, including but not limited to the U.S. Export Administration Regulations ("EAR"), (15 C.F.R. Sections 730 
    through 774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000.  Further, pursuant to Section 740.6 of
    the EAR, you hereby certify that, except pursuant to a license granted by the United States Department of Commerce
-   Bureau of Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export
-   Administration Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in
-   Country Groups D:1, E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2)
+   Bureau of Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export 
+   Administration Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in 
+   Country Groups D:1, E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) 
    export to Country Groups D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced
-   direct product is subject to national security controls as identified on the Commerce Control List (currently
-   found in Supplement 1 to Part 774 of EAR).  For the most current Country Group listings, or for additional
+   direct product is subject to national security controls as identified on the Commerce Control List (currently 
+   found in Supplement 1 to Part 774 of EAR).  For the most current Country Group listings, or for additional 
    information about the EAR or your obligations under those regulations, please refer to the U.S. Bureau of Industry
-   and Security?s website at http://www.bis.doc.gov/.
+   and Security?s website at http://www.bis.doc.gov/. 
    */
 #define APARAPIBUFFER_SOURCE
 #include "AparapiBuffer.h"
@@ -57,35 +57,67 @@
 AparapiBuffer::AparapiBuffer():
    javaObject((jobject) 0),
    numDims(0),
-   offsets(NULL),
    lengthInBytes(0),
    mem((cl_mem) 0),
    data(NULL),
    memMask((cl_uint)0) {
+      for (int i = 0; i < MAX_ND_DIMS; i++) {
+    	  lens[i] = (cl_uint)0;
+    	  offsets[i] = (cl_uint)0;
+      }
    }
 
 AparapiBuffer::AparapiBuffer(void* _data, cl_uint* _lens, cl_uint _numDims, long _lengthInBytes, jobject _javaObject) :
    data(_data),
-   lens(_lens),
    numDims(_numDims),
    lengthInBytes(_lengthInBytes),
    javaObject(_javaObject),
    mem((cl_mem) 0),
    memMask((cl_uint)0)
 {
-   offsets = new cl_uint[_numDims];
    for(int i = 0; i < _numDims; i++) {
-      offsets[i] = 1;
-      for(int j = i+1; j < _numDims; j++) {
-         offsets[i] *= lens[j];
-      }
+	   lens[i] = _lens[i];
+   }
+   computeOffsets();
+}
+
+void AparapiBuffer::computeOffsets() {
+   for(int i = 0; i < numDims; i++) {
+	  offsets[i] = 1;
+	  for(int j = i+1; j < numDims; j++) {
+		 offsets[i] *= lens[j];
+	  }
    }
 }
 
-jobject AparapiBuffer::getJavaObject(JNIEnv* env, KernelArg* arg) {
+jobject AparapiBuffer::getJavaObject(JNIEnv* env, KernelArg* arg) const {
    return JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
 }
 
+void AparapiBuffer::getMinimalParams(JNIEnv *env, KernelArg* arg, cl_uint &numDims, cl_uint dims[], int &lengthInBytes) const {
+	numDims = JNIHelper::getInstanceField<jint>(env, arg->javaArg, "numDims", IntArg);
+	jobjectArray jObjArray = (jobjectArray)getJavaObject(env, arg);
+	for (int i = 0; i < numDims; i++) {
+		dims[i] = env->GetArrayLength((jobjectArray)jObjArray);
+		if (i < numDims - 1) {
+			jObjArray = (jobjectArray)env->GetObjectArrayElement(jObjArray, 0);
+		}
+	}
+	lengthInBytes = env->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+}
+
+void AparapiBuffer::syncMinimalParams(JNIEnv *env, KernelArg* arg) {
+	numDims = JNIHelper::getInstanceField<jint>(env, arg->javaArg, "numDims", IntArg);
+	jobjectArray jObjArray = (jobjectArray)getJavaObject(env, arg);
+	for (int i = 0; i < numDims; i++) {
+		lens[i] = env->GetArrayLength((jobjectArray)jObjArray);
+		if (i < numDims - 1) {
+			jObjArray = (jobjectArray)env->GetObjectArrayElement(jObjArray, 0);
+		}
+	}
+	lengthInBytes = env->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+	computeOffsets();
+}
 
 void AparapiBuffer::flatten(JNIEnv* env, KernelArg* arg) {
    int numDims = JNIHelper::getInstanceField<jint>(env, arg->javaArg, "numDims", IntArg);
@@ -125,24 +157,20 @@ void AparapiBuffer::flatten(JNIEnv* env, KernelArg* arg) {
 
 void AparapiBuffer::buildBuffer(void* _data, cl_uint* _dims, cl_uint _numDims, long _lengthInBytes, jobject _javaObject) {
    data = _data;
-   lens = _dims;
    numDims = _numDims;
    lengthInBytes = _lengthInBytes;
    javaObject = _javaObject;
-   offsets = new cl_uint[_numDims];
    for(int i = 0; i < _numDims; i++) {
-      offsets[i] = 1;
-      for(int j = i+1; j < _numDims; j++) {
-         offsets[i] *= lens[j];
-      }
+	  lens[i] = _dims[i];
    }
+   computeOffsets();
 }
 
 
 void AparapiBuffer::flattenBoolean2D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[2];
+   cl_uint dims[2];
    dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
    dims[1] = env->GetArrayLength((jbooleanArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
    int totalSize = dims[0] * dims[1];
@@ -183,14 +211,14 @@ void AparapiBuffer::flattenBoolean2D(JNIEnv* env, KernelArg* arg) {
       // Does DeleteLocalRef required?
       // env->DeleteLocalRef(jArray);
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenByte2D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[2];
+   cl_uint dims[2];
    dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
    dims[1] = env->GetArrayLength((jbyteArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
    int totalSize = dims[0] * dims[1];
@@ -229,14 +257,14 @@ void AparapiBuffer::flattenByte2D(JNIEnv* env, KernelArg* arg) {
       }
       env->ReleaseByteArrayElements(jArray, elems, 0);
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenShort2D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[2];
+   cl_uint dims[2];
    dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
    dims[1] = env->GetArrayLength((jshortArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
    int totalSize = dims[0] * dims[1];
@@ -275,14 +303,14 @@ void AparapiBuffer::flattenShort2D(JNIEnv* env, KernelArg* arg) {
       }
       env->ReleaseShortArrayElements(jArray, elems, 0);
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenInt2D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[2];
+   cl_uint dims[2];
    dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
    dims[1] = env->GetArrayLength((jintArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
    int totalSize = dims[0] * dims[1];
@@ -321,14 +349,14 @@ void AparapiBuffer::flattenInt2D(JNIEnv* env, KernelArg* arg) {
       }
       env->ReleaseIntArrayElements(jArray, elems, 0);
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenLong2D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[2];
+   cl_uint dims[2];
    dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
    dims[1] = env->GetArrayLength((jlongArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
    int totalSize = dims[0] * dims[1];
@@ -367,14 +395,14 @@ void AparapiBuffer::flattenLong2D(JNIEnv* env, KernelArg* arg) {
       }
       env->ReleaseLongArrayElements(jArray, elems, 0);
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenFloat2D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[2];
+   cl_uint dims[2];
    dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
    dims[1] = env->GetArrayLength((jfloatArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
    int totalSize = dims[0] * dims[1];
@@ -413,14 +441,14 @@ void AparapiBuffer::flattenFloat2D(JNIEnv* env, KernelArg* arg) {
       }
       env->ReleaseFloatArrayElements(jArray, elems, 0);
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenDouble2D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[2];
+   cl_uint dims[2];
    dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
    dims[1] = env->GetArrayLength((jdoubleArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
    int totalSize = dims[0] * dims[1];
@@ -459,15 +487,15 @@ void AparapiBuffer::flattenDouble2D(JNIEnv* env, KernelArg* arg) {
       }
       env->ReleaseDoubleArrayElements(jArray, elems, 0);
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
 }
 
 
 void AparapiBuffer::flattenBoolean3D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[3];
+   cl_uint dims[3];
    jobjectArray j0 = (jobjectArray)javaBuffer;
    jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
    jbooleanArray j2 = (jbooleanArray)env->GetObjectArrayElement(j1, 0);
@@ -524,14 +552,14 @@ void AparapiBuffer::flattenBoolean3D(JNIEnv* env, KernelArg* arg) {
          env->ReleaseBooleanArrayElements(jArray, elems, 0);
       }
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenByte3D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[3];
+   cl_uint dims[3];
    jobjectArray j0 = (jobjectArray)javaBuffer;
    jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
    jbyteArray j2 = (jbyteArray)env->GetObjectArrayElement(j1, 0);
@@ -588,14 +616,14 @@ void AparapiBuffer::flattenByte3D(JNIEnv* env, KernelArg* arg) {
          env->ReleaseByteArrayElements(jArray, elems, 0);
       }
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenShort3D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[3];
+   cl_uint dims[3];
    jobjectArray j0 = (jobjectArray)javaBuffer;
    jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
    jshortArray j2 = (jshortArray)env->GetObjectArrayElement(j1, 0);
@@ -652,14 +680,14 @@ void AparapiBuffer::flattenShort3D(JNIEnv* env, KernelArg* arg) {
          env->ReleaseShortArrayElements(jArray, elems, 0);
       }
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenInt3D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[3];
+   cl_uint dims[3];
    jobjectArray j0 = (jobjectArray)javaBuffer;
    jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
    jintArray j2 = (jintArray)env->GetObjectArrayElement(j1, 0);
@@ -716,14 +744,14 @@ void AparapiBuffer::flattenInt3D(JNIEnv* env, KernelArg* arg) {
          env->ReleaseIntArrayElements(jArray, elems, 0);
       }
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenLong3D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[3];
+   cl_uint dims[3];
    jobjectArray j0 = (jobjectArray)javaBuffer;
    jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
    jlongArray j2 = (jlongArray)env->GetObjectArrayElement(j1, 0);
@@ -780,14 +808,14 @@ void AparapiBuffer::flattenLong3D(JNIEnv* env, KernelArg* arg) {
          env->ReleaseLongArrayElements(jArray, elems, 0);
       }
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenFloat3D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[3];
+   cl_uint dims[3];
    jobjectArray j0 = (jobjectArray)javaBuffer;
    jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
    jfloatArray j2 = (jfloatArray)env->GetObjectArrayElement(j1, 0);
@@ -844,14 +872,14 @@ void AparapiBuffer::flattenFloat3D(JNIEnv* env, KernelArg* arg) {
          env->ReleaseFloatArrayElements(jArray, elems, 0);
       }
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 void AparapiBuffer::flattenDouble3D(JNIEnv* env, KernelArg* arg) {
 
    jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
-   cl_uint* dims = new cl_uint[3];
+   cl_uint dims[3];
    jobjectArray j0 = (jobjectArray)javaBuffer;
    jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
    jdoubleArray j2 = (jdoubleArray)env->GetObjectArrayElement(j1, 0);
@@ -908,8 +936,8 @@ void AparapiBuffer::flattenDouble3D(JNIEnv* env, KernelArg* arg) {
          env->ReleaseDoubleArrayElements(jArray, elems, 0);
       }
    }
-
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+  
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 
@@ -953,7 +981,7 @@ void AparapiBuffer::inflate(JNIEnv* env, KernelArg* arg) {
 
 
 void AparapiBuffer::inflateBoolean2D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jboolean* array = (jboolean*)data;
    /*
@@ -990,7 +1018,7 @@ void AparapiBuffer::inflateBoolean2D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateByte2D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jbyte* array = (jbyte*)data;
    /*
@@ -1027,7 +1055,7 @@ void AparapiBuffer::inflateByte2D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateShort2D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jshort* array = (jshort*)data;
    /*
@@ -1064,7 +1092,7 @@ void AparapiBuffer::inflateShort2D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateInt2D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jint* array = (jint*)data;
    /*
@@ -1101,7 +1129,7 @@ void AparapiBuffer::inflateInt2D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateLong2D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jlong* array = (jlong*)data;
    /*
@@ -1138,7 +1166,7 @@ void AparapiBuffer::inflateLong2D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateFloat2D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jfloat* array = (jfloat*)data;
    /*
@@ -1175,7 +1203,7 @@ void AparapiBuffer::inflateFloat2D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateDouble2D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jdouble* array = (jdouble*)data;
    /*
@@ -1213,7 +1241,7 @@ void AparapiBuffer::inflateDouble2D(JNIEnv *env, KernelArg* arg) {
 
 
 void AparapiBuffer::inflateBoolean3D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jboolean* array = (jboolean*)data;
    /*
@@ -1264,7 +1292,7 @@ void AparapiBuffer::inflateBoolean3D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateByte3D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jbyte* array = (jbyte*)data;
    /*
@@ -1315,7 +1343,7 @@ void AparapiBuffer::inflateByte3D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateShort3D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jshort* array = (jshort*)data;
    /*
@@ -1366,7 +1394,7 @@ void AparapiBuffer::inflateShort3D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateInt3D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jint* array = (jint*)data;
    /*
@@ -1417,7 +1445,7 @@ void AparapiBuffer::inflateInt3D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateLong3D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jlong* array = (jlong*)data;
    /*
@@ -1468,7 +1496,7 @@ void AparapiBuffer::inflateLong3D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateFloat3D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jfloat* array = (jfloat*)data;
    /*
@@ -1519,7 +1547,7 @@ void AparapiBuffer::inflateFloat3D(JNIEnv *env, KernelArg* arg) {
 }
 
 void AparapiBuffer::inflateDouble3D(JNIEnv *env, KernelArg* arg) {
-
+   
    jobjectArray buffer = (jobjectArray)javaObject;
    jdouble* array = (jdouble*)data;
    /*
@@ -1571,8 +1599,6 @@ void AparapiBuffer::inflateDouble3D(JNIEnv *env, KernelArg* arg) {
 
 void AparapiBuffer::deleteBuffer(KernelArg* arg)
 {
-      delete[] offsets;
-      delete[] lens;
    if(arg->isBoolean()) {
       delete[] (jboolean*)data;
    } else if(arg->isByte()) {
diff --git a/src/cpp/runKernel/AparapiBuffer.h b/src/cpp/runKernel/AparapiBuffer.h
index bb11fbada8dd509196512f2e2988b1636c573efb..2429d14b89cc21aafdbebf17b611801b6f0568f8 100644
--- a/src/cpp/runKernel/AparapiBuffer.h
+++ b/src/cpp/runKernel/AparapiBuffer.h
@@ -87,21 +87,29 @@ private:
 
    void buildBuffer(void* _data, cl_uint* _dims, cl_uint _numDims, long _lengthInBytes, jobject _javaObject);
 
+   void computeOffsets();
+
 public:
-      jobject javaObject;       // The java array that this arg is mapped to
-      cl_uint numDims;          // number of dimensions of the object (array lengths for ND arrays)
-      cl_uint* offsets;         // offsets of the next element in ND arrays)
-      cl_uint* lens;            // sizes of dimensions of the object (array lengths for ND arrays)
-      jint lengthInBytes;       // bytes in the array or directBuf
-      cl_mem mem;               // the opencl buffer
-      void *data;               // a copy of the object itself (this is what we pass to OpenCL)
-      cl_uint memMask;          // the mask used for createBuffer
+   	  static int const MAX_ND_DIMS = 3;
+
+      jobject javaObject;           // The java array that this arg is mapped to
+      cl_uint numDims;              // number of dimensions of the object (array lengths for ND arrays)
+      cl_uint offsets[MAX_ND_DIMS]; // offsets of the next element in ND arrays) - Aparapi currently limits ND arrays to 3 dimensions
+      cl_uint lens[MAX_ND_DIMS];    // sizes of dimensions of the object (array lengths for ND arrays)
+      jint lengthInBytes;           // bytes in the array or directBuf
+      cl_mem mem;                   // the opencl buffer
+      void *data;                   // a copy of the object itself (this is what we pass to OpenCL)
+      cl_uint memMask;              // the mask used for createBuffer
       ProfileInfo read;
       ProfileInfo write;
 
       AparapiBuffer();
       AparapiBuffer(void* _data, cl_uint* _dims, cl_uint _numDims, long _lengthInBytes, jobject _javaObject);
 
+      void getMinimalParams(JNIEnv *env, KernelArg* arg, cl_uint &numDims, cl_uint dims[], int &lengthInBytes) const;
+
+      void syncMinimalParams(JNIEnv *env, KernelArg* arg);
+
       void deleteBuffer(KernelArg* arg);
 
       void flatten(JNIEnv *env, KernelArg* arg);
@@ -144,7 +152,7 @@ public:
       void inflateFloat3D(JNIEnv *env, KernelArg* arg);
       void inflateDouble3D(JNIEnv *env, KernelArg* arg);
 
-      jobject getJavaObject(JNIEnv* env, KernelArg* arg);
+      jobject getJavaObject(JNIEnv* env, KernelArg* arg) const;
 };
 
 #endif // ARRAYBUFFER_H
diff --git a/src/cpp/runKernel/ArrayBuffer.cpp b/src/cpp/runKernel/ArrayBuffer.cpp
index 91b4b8e5f021b03fb763ffaf2bc8235de2d69450..42300d57d78ee2e7bee54a05913b7f5ca9ec4420 100644
--- a/src/cpp/runKernel/ArrayBuffer.cpp
+++ b/src/cpp/runKernel/ArrayBuffer.cpp
@@ -52,6 +52,7 @@
    */
 #define ARRAYBUFFER_SOURCE
 #include "ArrayBuffer.h"
+#include "KernelArg.h"
 
 ArrayBuffer::ArrayBuffer():
    javaArray((jobject) 0),
@@ -77,3 +78,13 @@ void ArrayBuffer::pin(JNIEnv *jenv){
    addr = jenv->GetPrimitiveArrayCritical((jarray)javaArray,&isCopy);
    isPinned = JNI_TRUE;
 }
+
+void ArrayBuffer::getMinimalParams(JNIEnv *jenv, KernelArg *arg, cl_uint& arrayElements, int &sizeInBytes) {
+    arrayElements = JNIHelper::getInstanceField<jint>(jenv, arg->javaArg, "numElements", IntArg);
+    sizeInBytes = jenv->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+}
+
+void ArrayBuffer::syncMinimalParams(JNIEnv *jenv, KernelArg *arg) {
+    length = JNIHelper::getInstanceField<jint>(jenv, arg->javaArg, "numElements", IntArg);
+	lengthInBytes = jenv->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+}
diff --git a/src/cpp/runKernel/ArrayBuffer.h b/src/cpp/runKernel/ArrayBuffer.h
index 6b057f9d73d12ad35f478b5154adaadcf40d3771..26cdbe567c1ace9ba48c7ada1017237e871ef21f 100644
--- a/src/cpp/runKernel/ArrayBuffer.h
+++ b/src/cpp/runKernel/ArrayBuffer.h
@@ -56,6 +56,8 @@
 #include "Common.h"
 #include "ProfileInfo.h"
 
+class KernelArg;
+
 class ArrayBuffer{
    public:
       jobject javaArray;        // The java array that this arg is mapped to
@@ -74,6 +76,8 @@ class ArrayBuffer{
       void unpinAbort(JNIEnv *jenv);
       void unpinCommit(JNIEnv *jenv);
       void pin(JNIEnv *jenv);
+      void getMinimalParams(JNIEnv *jenv, KernelArg *arg, cl_uint& arrayElements, int &sizeInBytes);
+      void syncMinimalParams(JNIEnv *jenv, KernelArg *arg);
 };
 
 #endif // ARRAYBUFFER_H
diff --git a/src/cpp/runKernel/KernelArg.h b/src/cpp/runKernel/KernelArg.h
index 64f95bdad989e9a0121e25d34cc68081c9078ded..83a96f5e6948f898f12c9a5ca888c9ed0b5717ed 100644
--- a/src/cpp/runKernel/KernelArg.h
+++ b/src/cpp/runKernel/KernelArg.h
@@ -35,7 +35,7 @@ class KernelArg{
    private:
       static jclass argClazz;
       static jfieldID nameFieldID;
-      static jfieldID typeFieldID;
+      static jfieldID typeFieldID; 
       static jfieldID sizeInBytesFieldID;
       static jfieldID numElementsFieldID;
 
@@ -59,7 +59,7 @@ class KernelArg{
       void getStaticPrimitiveValue(JNIEnv *jenv, jlong *value);
       void getStaticPrimitiveValue(JNIEnv *jenv, jdouble *value);
 
-      template<typename T>
+      template<typename T> 
       void getPrimitive(JNIEnv *jenv, int argIdx, int argPos, bool verbose, T* value) {
          if(isStatic()) {
             getStaticPrimitiveValue(jenv, value);
@@ -77,6 +77,10 @@ class KernelArg{
 
    public:
       static jfieldID javaArrayFieldID;
+
+      static jfieldID getSizeInBytesFieldID(){
+    	  return sizeInBytesFieldID;
+      }
    public:
       JNIContext *jniContext;
       jobject argObj;    // the Java KernelRunner.KernelArg object that we are mirroring. Do not use it outside constructor due to GC. Use javaArg instead.
@@ -189,12 +193,15 @@ class KernelArg{
       void syncType(JNIEnv* jenv){
          type = jenv->GetIntField(javaArg, typeFieldID);
       }
-      void syncSizeInBytes(JNIEnv* jenv){
-         arrayBuffer->lengthInBytes = jenv->GetIntField(javaArg, sizeInBytesFieldID);
+
+      int getSizeInBytes(JNIEnv* jenv){
+    	 return jenv->GetIntField(javaArg, sizeInBytesFieldID);
       }
-      void syncJavaArrayLength(JNIEnv* jenv){
-         arrayBuffer->length = jenv->GetIntField(javaArg, numElementsFieldID);
+
+      cl_uint getJavaArrayLength(JNIEnv* jenv){
+         return jenv->GetIntField(javaArg, numElementsFieldID);
       }
+
       void clearExplicitBufferBit(JNIEnv* jenv){
          type &= ~com_aparapi_internal_jni_KernelRunnerJNI_ARG_EXPLICIT_WRITE;
          jenv->SetIntField(javaArg, typeFieldID,type );