diff --git a/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp b/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp
index e1ef0ef4b0a43f2ea5184148a0ef535e3c3fe6d7..e985bd18b5af6fbe988c5009ebb9ea263aaa1f6b 100644
--- a/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp
+++ b/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp
@@ -250,7 +250,14 @@ void getArg(JNIEnv *jenv, cl_context context, cl_command_queue commandQueue, cl_
    }
 }
 
-JNI_JAVA(void, OpenCLJNI, dispose)
+JNI_JAVA(void, OpenCLJNI, disposeProgram)
+   (JNIEnv *jenv, jobject jobj, jobject programInstance) {
+      fprintf(stderr, "dispose program \n");
+      cl_program program = OpenCLProgram::getProgram(jenv, programInstance);
+      clReleaseProgram(program);
+}
+
+JNI_JAVA(void, OpenCLJNI, disposeKernel)
    (JNIEnv *jenv, jobject jobj, jobject kernelInstance) {
       cl_kernel kernel = OpenCLKernel::getKernel(jenv, kernelInstance);
       jobject programInstance = OpenCLKernel::getProgramInstance(jenv, kernelInstance);
@@ -276,6 +283,7 @@ JNI_JAVA(void, OpenCLJNI, dispose)
             }
          }
       }
+      clReleaseKernel(kernel);
    }
 
 /**
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java b/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java
index 6e1cbc13c339dff9e97cc45a60c4ffb855bffa86..ec9bed2fca5865837ce550a38b596ad60b28613b 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java
@@ -104,13 +104,17 @@ public class OpenCLDevice extends Device{
       private final Map<String, OpenCLKernel> map;
 
       private final OpenCLProgram program;
-
+      private boolean disposed = false;
       public OpenCLInvocationHandler(OpenCLProgram _program, Map<String, OpenCLKernel> _map) {
          program = _program;
          map = _map;
+         disposed = false;
       }
 
       @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+         if (disposed){
+            throw new IllegalStateException("bound interface already disposed");
+         }
          if (!isReservedInterfaceMethod(method)) {
             final OpenCLKernel kernel = map.get(method.getName());
             if (kernel != null) {
@@ -171,10 +175,9 @@ public class OpenCLDevice extends Device{
                for (OpenCLKernel k:map.values()){
                    k.dispose();
                }
-              // args =  map.get(method.getName());
-              // for (OpenCLArgDescriptor argDescriptor:args){
-
-              // }
+               program.dispose();
+               map.clear();
+               disposed=true;
             } else if (method.getName().equals("end")) {
                System.out.println("end not implemented");
             }
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java
index 34fd7edcde8e702d56cb02a4a3b3044b88c1facf..b69f5aebbd92d19aa83eb94c2434b4c1c3736d3f 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java
@@ -22,7 +22,9 @@ public abstract class OpenCLJNI{
 
    protected native void invoke(OpenCLKernel openCLKernel, Object[] args);
 
-   protected native void dispose(OpenCLKernel openCLKernel);
+   protected native void disposeKernel(OpenCLKernel openCLKernel);
+
+   protected native void disposeProgram(OpenCLProgram openCLProgram);
 
    protected native void remap(OpenCLProgram program, OpenCLMem mem, long address);
 
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java
index 04a95501b7dd15d36fa32a5161f2e5f9bfedc5d9..19c065927c35121d1a93c81e05f97be9d5b881e2 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java
@@ -58,6 +58,6 @@ public class OpenCLKernel extends OpenCLJNI{
    }
 
    public void dispose(){
-       dispose(this);
+       disposeKernel(this);
    }
 }
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLProgram.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLProgram.java
index 27e0641e9dcaf778cc2ecf25e4c65c7c735060c8..23855513e8921a91d137b19e8c2622fe5f2e7481 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLProgram.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLProgram.java
@@ -84,4 +84,8 @@ public class OpenCLProgram extends OpenCLJNI{
       addressToMem.remove(_oldAddress);
       addressToMem.put(_address, _mem);
    }
+
+   public void dispose(){
+       disposeProgram(this);
+   }
 }
diff --git a/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java b/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java
index cce44e44c90ca8b91f892536c37508082d2263fd..23fc9b86c4032de474ce5de4e9ba0837d52d9d83 100644
--- a/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java
+++ b/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java
@@ -57,20 +57,23 @@ public class SquareExample{
       if (device instanceof OpenCLDevice) {
          final OpenCLDevice openclDevice = (OpenCLDevice) device;
 
+         for (int l=0; l<1000; l++){
+
          final SquarerWithResource squarer = openclDevice.bind(SquarerWithResource.class);
          squarer.square(range, in, squares);
 
          for (int i = 0; i < size; i++) {
-            System.out.println(in[i] + " " + squares[i]);
+            System.out.println(l+" "+in[i] + " " + squares[i]);
          }
 
-         squarer.square(range, squares, quads);
+        // squarer.square(range, squares, quads);
 
-         for (int i = 0; i < size; i++) {
-            System.out.println(in[i] + " " + squares[i] + " " + quads[i]);
-         }
+        // for (int i = 0; i < size; i++) {
+         //   System.out.println(l+" "+ in[i] + " " + squares[i] + " " + quads[i]);
+         //}
 
          squarer.dispose();
+         }
       }
    }
 }