diff --git a/CHANGELOG.md b/CHANGELOG.md
index c18842345c0fcba6b8d4e830188900847d1ebba2..b49633b1f7c930d3c1413018f577572a9dd20fd1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Aparapi jni Change Log
 
+## 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 46e7deb5e5dd3887bd6409c59b9c835fc7cc4bb2..366d523e2e6253784bd3e36a07e6339b8968fe68 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 85ae3a2edad5af5d39c56a2c2af1afacba3fcc68..1e8938bc12d0f008f49871db302e30584df9f0b1 100644
--- a/src/cpp/runKernel/Aparapi.cpp
+++ b/src/cpp/runKernel/Aparapi.cpp
@@ -258,7 +258,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()){
@@ -304,10 +304,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
          }
@@ -356,6 +356,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");
@@ -381,7 +382,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)");
@@ -629,15 +629,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()){
@@ -645,9 +669,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++;
@@ -669,14 +696,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)");
       }
 
@@ -684,36 +740,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()){
@@ -721,10 +761,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;
       }
    }
 }
@@ -970,14 +1014,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 a6c29c784b601742c03f7ac2c81fd6c9adcd41d4..28cb6b2ee3e7daafddee71a259334f3e31e19635 100644
--- a/src/cpp/runKernel/AparapiBuffer.cpp
+++ b/src/cpp/runKernel/AparapiBuffer.cpp
@@ -42,35 +42,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);
@@ -110,24 +142,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];
@@ -169,13 +197,13 @@ void AparapiBuffer::flattenBoolean2D(JNIEnv* env, KernelArg* arg) {
       // 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];
@@ -215,13 +243,13 @@ 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];
@@ -261,13 +289,13 @@ 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];
@@ -307,13 +335,13 @@ 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];
@@ -353,13 +381,13 @@ 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];
@@ -399,13 +427,13 @@ 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];
@@ -445,14 +473,14 @@ 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);
@@ -510,13 +538,13 @@ void AparapiBuffer::flattenBoolean3D(JNIEnv* env, KernelArg* arg) {
       }
    }
   
-   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);
@@ -574,13 +602,13 @@ void AparapiBuffer::flattenByte3D(JNIEnv* env, KernelArg* arg) {
       }
    }
   
-   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);
@@ -638,13 +666,13 @@ void AparapiBuffer::flattenShort3D(JNIEnv* env, KernelArg* arg) {
       }
    }
   
-   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);
@@ -702,13 +730,13 @@ void AparapiBuffer::flattenInt3D(JNIEnv* env, KernelArg* arg) {
       }
    }
   
-   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);
@@ -766,13 +794,13 @@ void AparapiBuffer::flattenLong3D(JNIEnv* env, KernelArg* arg) {
       }
    }
   
-   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);
@@ -830,13 +858,13 @@ void AparapiBuffer::flattenFloat3D(JNIEnv* env, KernelArg* arg) {
       }
    }
   
-   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);
@@ -894,7 +922,7 @@ void AparapiBuffer::flattenDouble3D(JNIEnv* env, KernelArg* arg) {
       }
    }
   
-   buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+   buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
 }
 
 
@@ -1556,8 +1584,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 272cccffe0360bf3951d62b8a44ce583f59f5d4f..65f9a2043ff7412ad89fe3d90fa48a7e5609539e 100644
--- a/src/cpp/runKernel/AparapiBuffer.h
+++ b/src/cpp/runKernel/AparapiBuffer.h
@@ -72,21 +72,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);
@@ -129,7 +137,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 b3947681371e6d756a35dadd94d09b223d215b03..21e11b67ea6c5e1ae1452cc50294b4f263b65d0c 100644
--- a/src/cpp/runKernel/ArrayBuffer.cpp
+++ b/src/cpp/runKernel/ArrayBuffer.cpp
@@ -37,6 +37,7 @@
    */
 #define ARRAYBUFFER_SOURCE
 #include "ArrayBuffer.h"
+#include "KernelArg.h"
 
 ArrayBuffer::ArrayBuffer():
    javaArray((jobject) 0),
@@ -62,3 +63,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 26f702c80f6819e0d544d8a6d831685f917490ba..9aff69813b56fffa71e05f23496c19ac068a5f99 100644
--- a/src/cpp/runKernel/ArrayBuffer.h
+++ b/src/cpp/runKernel/ArrayBuffer.h
@@ -41,6 +41,8 @@
 #include "Common.h"
 #include "ProfileInfo.h"
 
+class KernelArg;
+
 class ArrayBuffer{
    public:
       jobject javaArray;        // The java array that this arg is mapped to 
@@ -59,6 +61,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 9b0e433ea35087d982d2597af84da454583d792b..ed87a1b814e0305bdd04a9937371c5b7dfde07d0 100644
--- a/src/cpp/runKernel/KernelArg.h
+++ b/src/cpp/runKernel/KernelArg.h
@@ -61,7 +61,11 @@ class KernelArg{
 
 
    public:
-      static jfieldID javaArrayFieldID; 
+      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.
@@ -174,12 +178,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 );