diff --git a/com.amd.aparapi.jni/Aparapi.suo b/com.amd.aparapi.jni/Aparapi.suo
index 79b046879bc8389cd16d5fd8594758cf385c92b2..117d265b9625f6dc443e9f6dde562abcf51f7ded 100644
Binary files a/com.amd.aparapi.jni/Aparapi.suo and b/com.amd.aparapi.jni/Aparapi.suo differ
diff --git a/com.amd.aparapi.jni/Aparapi.vcxproj b/com.amd.aparapi.jni/Aparapi.vcxproj
index 3023d478695b9367099c6c4d1e7208ec9ea26a47..279e7ab82c54c71d6eaf359542c6206b11d3e5b3 100644
--- a/com.amd.aparapi.jni/Aparapi.vcxproj
+++ b/com.amd.aparapi.jni/Aparapi.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
@@ -18,12 +18,12 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
@@ -78,10 +78,10 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="src\cpp\aparapi.cpp" />
     <ClCompile Include="src\cpp\clHelper.cpp" />
     <ClCompile Include="src\cpp\jniHelper.cpp" />
-    <ClCompile Include="src\cpp\opencljni.cpp" />
+    <ClCompile Include="src\cpp\runKernel\Aparapi.cpp" />
+    <ClCompile Include="src\cpp\runKernel\JNIContext.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="include\com_amd_aparapi_KernelRunner.h" />
diff --git a/com.amd.aparapi.jni/Aparapi.vcxproj.filters b/com.amd.aparapi.jni/Aparapi.vcxproj.filters
index 2de182d55c8852a216633202ef8bc6a0e7bfcde5..686086d6bcdcd1ffb4744424ed43c8d02c1fb33b 100644
--- a/com.amd.aparapi.jni/Aparapi.vcxproj.filters
+++ b/com.amd.aparapi.jni/Aparapi.vcxproj.filters
@@ -15,16 +15,16 @@
     </Filter>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="src\cpp\aparapi.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="src\cpp\jniHelper.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="src\cpp\clHelper.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="src\cpp\opencljni.cpp">
+    <ClCompile Include="src\cpp\runKernel\Aparapi.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\cpp\runKernel\JNIContext.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
diff --git a/com.amd.aparapi.jni/build.xml b/com.amd.aparapi.jni/build.xml
index 035bc928bbeb0a01880f7613fa7cc47b23c6534c..de7ee8003bb2bd300667e7fa94aef0e14f5567ef 100644
--- a/com.amd.aparapi.jni/build.xml
+++ b/com.amd.aparapi.jni/build.xml
@@ -14,26 +14,21 @@ First consider editing the properties in build.properties
    <echo>OS Arch:    ${os.arch}</echo>
    <echo>Java Ver:   ${java.version}</echo>
 
-   <!-- Ideally this would be the latest version of Java but not everyone is going to have it installed -->
-   <!-- Additionally we want to avoid "Class not found: javac1.8" errors from old Ant versions (i.e. Eclipse) -->
-   <property name="build.compiler" value="javac1.7"/>
-   <property name="ant.build.javac.source" value="1.7"/>
-   <property name="ant.build.javac.target" value="1.7"/>
-
-   <property name="amd.app.sdk.version" value="2.9-1"/>
-   
+   <!--<property name="build.compiler" value="javac1.6"/>-->
+   <!--  <property name="ant.build.javac.source" value="1.6"/>-->
+   <!-- <property name="ant.build.javac.target" value="1.6"/> -->
+
    <property environment="env" />
-   
-   <!-- Check for AMD APP SDK -->
-   <echo>
-      Note: Since AMD APP SDK 2.9 you can have multiple versions installed/co-exist on same machine, 
-      so AMD introduced a completely new naming convention for their installation directories
-      For example C:/Program Files/AMD APP SDK/2.9-1
-   </echo>
+   <property name="msvc.dir" value="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin" />
+   <!-- we need env.PATH for msvc only -->
+
+   <!-- uncomment this if you want to use mingw! -->
+   <!--<property name="mingw.dir" value="c:\\MinGW"/>-->
 
    <target name="init">
-      <available property="win32.amd.app.sdk.exists" file="C:/Program Files/AMD APP SDK/${amd.app.sdk.version}" type="dir"/>
-      <condition property="amd.app.sdk.dir" value="C:/Program Files/AMD APP SDK/${amd.app.sdk.version}">
+      <available property="win32.amd.app.sdk.exists" file="C:\Program Files (x86)\AMD APP SDK\2.9-1" type="dir"/>
+
+      <condition property="amd.app.sdk.dir" value="C:\Program Files (x86)\AMD APP SDK\2.9-1">
          <and>
             <os family="windows" />
             <isset property="win32.amd.app.sdk.exists" />
@@ -43,8 +38,8 @@ First consider editing the properties in build.properties
          </and>
       </condition>
 
-      <available property="win64.amd.app.sdk.exists" file="C:/Program Files (x86)/AMD APP SDK/${amd.app.sdk.version}" type="dir"/>
-      <condition property="amd.app.sdk.dir" value="C:/Program Files (x86)/AMD APP SDK/${amd.app.sdk.version}">
+      <available property="win64.amd.app.sdk.exists" file="C:\Program Files (x86)\AMD APP SDK\2.9-1" type="dir"/>
+      <condition property="amd.app.sdk.dir" value="C:\Program Files (x86)\AMD APP SDK\2.9-1">
          <and>
             <os family="windows" />
             <isset property="win64.amd.app.sdk.exists" />
@@ -54,8 +49,8 @@ First consider editing the properties in build.properties
          </and>
       </condition>
 
-      <available property="linux.amd.app.sdk.exists" file="/opt/AMDAPPSDK-${amd.app.sdk.version}" type="dir"/>
-      <condition property="amd.app.sdk.dir" value="/opt/AMDAPPSDK-${amd.app.sdk.version}">
+      <available property="linux.amd.app.sdk.exists" file="/opt/AMDAPP" type="dir"/>
+      <condition property="amd.app.sdk.dir" value="/opt/AMDAPP">
          <and>
             <os family="unix" />
             <not>
@@ -71,191 +66,227 @@ First consider editing the properties in build.properties
          </and>
       </condition>
 
-      <echo message="amd.app.sdk.dir ${amd.app.sdk.dir}"/>
+      <echo message=" amd.app.sdk.dir ${amd.app.sdk.dir}"/>
 
-      <available property="linux.intel.app.sdk.exists" file="/opt/intel/opencl" type="dir"/>
-      <condition property="intel.app.sdk.dir" value="/opt/intel/opencl">
+	  <!-- Check for Visual Studio -->
+	  <!-- This needs to be in descending order to properly handle multiple installations -->
+	  
+      <available property="msvc.32.11.0.exists" file="c:/Program Files (x86)/Microsoft Visual Studio 11.0\VC\bin" type="dir"/>
+      <condition property="msvc.dir" value="c:/Program Files (x86)/Microsoft Visual Studio 11.0">
          <and>
-            <os family="unix" />
             <not>
-               <os family="mac" />
+               <or>
+                  <os arch="x86" />
+                  <os arch="i386" />
+               </or>
             </not>
-            <isset property="linux.intel.app.sdk.exists" />
+            <os family="windows" />
+            <isset property="msvc.32.11.0.exists" />
             <not>
-               <isset property="win32.amd.app.sdk.exists" />
+               <isset property="msvc.dir" />
             </not>
             <not>
-               <isset property="win64.amd.app.sdk.exists" />
+               <isset property="mingw.dir" />
             </not>
          </and>
       </condition>
-
-      <echo message=" intel.app.sdk.dir ${intel.app.sdk.dir}"/>
-
-      <condition property="vendor.name" value="amd">
-         <isset property="amd.app.sdk.dir" /> 
-      </condition>
-
-      <condition property="vendor.name" value="intel">
+      
+      <available property="msvc.64.10.0.exists" file="c:/Program Files/Microsoft Visual Studio 10.0\vc\bin" type="dir"/>
+      <condition property="msvc.dir" value="c:/Program Files/Microsoft Visual Studio 10.0">
          <and>
-            <isset property="intel.app.sdk.dir" /> 
+            <or>
+               <os arch="x86" />
+               <os arch="i386" />
+            </or>
+            <os family="windows" />
+            <isset property="msvc.64.10.0.exists" />
             <not>
-                <isset property="amd.app.sdk.dir" /> 
+               <isset property="msvc.dir" />
             </not>
-         </and>
-      </condition>
-
-      <echo message=" vendor.name ${vendor.name}"/>
-  
-      <condition property="app.sdk.dir" value="${amd.app.sdk.dir}">
-         <isset property="amd.app.sdk.dir" /> 
-      </condition>
-
-      <condition property="app.sdk.dir" value="${intel.app.sdk.dir}">
-         <and>
-            <isset property="intel.app.sdk.dir" /> 
             <not>
-                <isset property="app.sdk.dir" /> 
+               <isset property="mingw.dir" />
             </not>
          </and>
       </condition>
-
-      <echo message="app.sdk.dir ${app.sdk.dir}"/>
-
-	  <!-- Check for Visual Studio Compiler -->
-	  <!-- This needs to be in descending order to properly handle multiple installations -->
-	  <available property="msvc.32.12.0.exists" file="C:/Program Files/Microsoft Visual Studio 12.0\VC\bin" type="dir"/>
-      <condition property="msvc.dir" value="c:/Program Files/Microsoft Visual Studio 12.0">
+      
+      <available property="msvc.32.10.0.exists" file="c:/Program Files (x86)/Microsoft Visual Studio 10.0\vc\bin" type="dir"/>
+      <condition property="msvc.dir" value="c:/Program Files (x86)/Microsoft Visual Studio 10.0">
          <and>
-            <os family="windows" />
-            <isset property="msvc.32.12.0.exists" />
             <not>
-               <isset property="msvc.dir" />
+               <or>
+                  <os arch="x86" />
+                  <os arch="i386" />
+               </or>
             </not>
-         </and>
-      </condition>
-      
-      <available property="msvc.64.12.0.exists" file="C:/Program Files (x86)/Microsoft Visual Studio 12.0\VC\bin" type="dir"/>
-      <condition property="msvc.dir" value="c:/Program Files (x86)/Microsoft Visual Studio 12.0">
-         <and>
             <os family="windows" />
-            <isset property="msvc.64.12.0.exists" />
+            <isset property="msvc.32.10.0.exists" />
             <not>
                <isset property="msvc.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
       
-	  <available property="msvc.32.11.0.exists" file="C:/Program Files/Microsoft Visual Studio 11.0\VC\bin" type="dir"/>
-      <condition property="msvc.dir" value="c:/Program Files/Microsoft Visual Studio 11.0">
+      <available property="msvc.32.9.0.exists" file="c:/Program Files/Microsoft Visual Studio 9.0\vc\bin" type="dir"/>
+      <condition property="msvc.dir" value="c:/Program Files/Microsoft Visual Studio 9.0">
          <and>
+            <or>
+               <os arch="x86" />
+               <os arch="i386" />
+            </or>
             <os family="windows" />
-            <isset property="msvc.32.11.0.exists" />
+            <isset property="msvc.32.9.0.exists" />
             <not>
                <isset property="msvc.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
-      
-      <available property="msvc.64.11.0.exists" file="C:/Program Files (x86)/Microsoft Visual Studio 11.0\VC\bin" type="dir"/>
-      <condition property="msvc.dir" value="c:/Program Files (x86)/Microsoft Visual Studio 11.0">
+
+	  <!-- Check for SDKs -->
+	  <!-- This needs to be in descending order to properly handle multiple installations -->
+	  
+      <!-- <available property="msvc.sdk.8.0A.32.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v8.0A" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v8.0A">
          <and>
             <os family="windows" />
-            <isset property="msvc.64.11.0.exists" />
+            <isset property="msvc.sdk.8.0A.32.exists" />
             <not>
-               <isset property="msvc.dir" />
+               <isset property="msvc.sdk.dir" />
+            </not>
+            <not>
+               <isset property="mingw.dir" />
             </not>
          </and>
       </condition>
       
-      <available property="msvc.32.10.0.exists" file="c:/Program Files/Microsoft Visual Studio 10.0\vc\bin" type="dir"/>
-      <condition property="msvc.dir" value="c:/Program Files/Microsoft Visual Studio 10.0">
+      <available property="msvc.sdk.8.0.32.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v8.0" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v8.0">
          <and>
             <os family="windows" />
-            <isset property="msvc.32.10.0.exists" />
+            <isset property="msvc.sdk.8.0.32.exists" />
             <not>
-               <isset property="msvc.dir" />
+               <isset property="msvc.sdk.dir" />
+            </not>
+            <not>
+               <isset property="mingw.dir" />
             </not>
          </and>
-      </condition>
+      </condition> -->
       
-      <available property="msvc.64.10.0.exists" file="c:/Program Files (x86)/Microsoft Visual Studio 10.0\vc\bin" type="dir"/>
-      <condition property="msvc.dir" value="c:/Program Files (x86)/Microsoft Visual Studio 10.0">
+      <available property="msvc.sdk.7.1A.exists" file="C:/Program Files/Microsoft SDKs/Windows/v7.1A" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v7.1A">
          <and>
             <os family="windows" />
-            <isset property="msvc.64.10.0.exists" />
+            <isset property="msvc.sdk.7.1A.exists" />
             <not>
-               <isset property="msvc.dir" />
+               <isset property="msvc.sdk.dir" />
+            </not>
+            <not>
+               <isset property="mingw.dir" />
             </not>
          </and>
       </condition>
-
-	  <!-- Check for SDKs -->
-	  <!-- This needs to be in descending order to properly handle multiple installations -->
-	
-      <available property="msvc.sdk.7.1A.32.exists" file="C:/Program Files/Microsoft SDKs/Windows/v7.1A" type="dir"/>
-      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v7.1A">
+      
+      <available property="msvc.sdk.7.1A.32.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A">
          <and>
             <os family="windows" />
             <isset property="msvc.sdk.7.1A.32.exists" />
             <not>
                <isset property="msvc.sdk.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
       
-      <available property="msvc.sdk.7.1A.64.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A" type="dir"/>
-      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A">
+      <available property="msvc.sdk.7.1.exists" file="C:/Program Files/Microsoft SDKs/Windows/v7.1" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v7.1">
          <and>
             <os family="windows" />
-            <isset property="msvc.sdk.7.1A.64.exists" />
+            <isset property="msvc.sdk.7.1.exists" />
             <not>
                <isset property="msvc.sdk.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
-      
-      <available property="msvc.sdk.7.1.32.exists" file="C:/Program Files/Microsoft SDKs/Windows/v7.1" type="dir"/>
-      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v7.1">
+
+	  <available property="msvc.sdk.7.1.32.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1">
          <and>
             <os family="windows" />
             <isset property="msvc.sdk.7.1.32.exists" />
             <not>
                <isset property="msvc.sdk.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
 
-	  <available property="msvc.sdk.7.1.64.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1" type="dir"/>
-      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1">
+      <available property="msvc.sdk.7.0A.exists" file="C:/Program Files/Microsoft SDKs/Windows/v7.0A" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v7.0A">
          <and>
             <os family="windows" />
-            <isset property="msvc.sdk.7.1.64.exists" />
+            <isset property="msvc.sdk.7.0A.exists" />
             <not>
                <isset property="msvc.sdk.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
 
-      <available property="msvc.sdk.7.0A.32.exists" file="C:/Program Files/Microsoft SDKs/Windows/v7.0A" type="dir"/>
-      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v7.0A">
+      <available property="msvc.sdk.7.0A.32.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A">
          <and>
             <os family="windows" />
             <isset property="msvc.sdk.7.0A.32.exists" />
             <not>
                <isset property="msvc.sdk.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
+         </and>
+      </condition>
+      
+      <available property="msvc.sdk.7.0.exists" file="C:/Program Files/Microsoft SDKs/Windows/v7.0" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v7.0">
+         <and>
+            <os family="windows" />
+            <isset property="msvc.sdk.7.0.exists" />
+            <not>
+               <isset property="msvc.sdk.dir" />
+            </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
 
-      <available property="msvc.sdk.7.0A.64.exists" file="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A" type="dir"/>
-      <condition property="msvc.sdk.dir" value="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A">
+      <available property="msvc.sdk.6.0A.exists" file="C:/Program Files/Microsoft SDKs/Windows/v6.0A" type="dir"/>
+      <condition property="msvc.sdk.dir" value="C:/Program Files/Microsoft SDKs/Windows/v6.0A">
          <and>
             <os family="windows" />
-            <isset property="msvc.sdk.7.0A.64.exists" />
+            <isset property="msvc.sdk.6.0A.exists" />
             <not>
                <isset property="msvc.sdk.dir" />
             </not>
+            <not>
+               <isset property="mingw.dir" />
+            </not>
          </and>
       </condition>
 
@@ -264,6 +295,7 @@ First consider editing the properties in build.properties
    </target>
 
    <target name="check" depends="init">
+
       <fail message="Error:">
          <condition>
             <and>
@@ -275,9 +307,9 @@ First consider editing the properties in build.properties
             </and>
          </condition>
          <![CDATA[
-         You will need to edit com.amd.aparapi.jni/build.xml to compile aparapi JNI code
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
 
-         At present msvc.dir seems to be configured but not msvc.sdk.dir
+         At present msvc.dir seems to be Configured but not msvc.sdk.dir
          ]]>
       </fail>
 
@@ -292,12 +324,11 @@ First consider editing the properties in build.properties
             </and>
          </condition>
          <![CDATA[
-         You will need to edit com.amd.aparapi.jni/build.xml to compile aparapi JNI code
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
 
-         At present msvc.sdk.dir seems to be configured but not msvc.dir
+         At present msvc.sdk.dir seems to be Configured but not msvc.dir
          ]]>
       </fail>
-      
       <available file="${msvc.dir}" type="dir" property="msvc.dir.exists" />
       <available file="${msvc.sdk.dir}" type="dir" property="msvc.sdk.dir.exists" />
 
@@ -312,12 +343,11 @@ First consider editing the properties in build.properties
             </and>
          </condition>
          <![CDATA[
-         You will need to edit com.amd.aparapi.jni/build.xml to compile aparapi JNI code
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
 
          At present msvc.dir is set (to ${msvc.dir}) but that dir does not exist
          ]]>
       </fail>
-      
       <fail message="Error:">
          <condition>
             <and>
@@ -329,12 +359,34 @@ First consider editing the properties in build.properties
             </and>
          </condition>
          <![CDATA[
-         You will need to edit com.amd.aparapi.jni/build.xml to compile aparapi JNI code
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
 
          At present msvc.sdk.dir is set (to ${msvc.sdk.dir}) but that dir does not exist
          ]]>
       </fail>
-      
+
+
+      <available file="${mingw.dir}" type="dir" property="mingw.dir.exists" />
+      <fail message="Error:">
+         <condition>
+            <and>
+               <os family="windows" />
+               <isset property="mingw.dir" />
+               <not>
+                  <isset property="mingw.dir.exists" />
+               </not>
+            </and>
+         </condition>
+         <![CDATA[
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
+
+         At present mingw.dir is set (to ${mingw.dir}) but that dir does not exist
+         ]]>
+      </fail>
+      <echo message="java.home ${java.home}"/>
+      <!--<echo message="msvc.dir.exists ${msvc.dir.exists}"/>-->
+      <!--<echo message="msvc.sdk.dir.exists ${msvc.sdk.dir.exists}"/>-->
+      <!--<echo message="mingw.dir.exists ${mingw.dir.exists}"/>-->
       <condition property="use.msvc">
          <and>
             <os family="windows" />
@@ -342,6 +394,54 @@ First consider editing the properties in build.properties
             <isset property="msvc.sdk.dir.exists" />
          </and>
       </condition>
+      <!--<echo message="use.msvc ${use.msvc}"/>-->
+
+      <condition property="use.mingw">
+         <and>
+            <os family="windows" />
+            <isset property="mingw.dir.exists" />
+         </and>
+      </condition>
+      <!--<echo message="use.mingw ${use.mingw}"/>-->
+
+      <fail message="Error:">
+         <condition>
+            <and>
+               <isset property="use.mingw" />
+               <isset property="use.msvc" />
+            </and>
+         </condition>
+         <![CDATA[
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
+
+         At present ant is Configured for both MinGW AND Microsoft Visual Studio. You need to pick one or the other :) !
+
+         Just comment out the properties for the compiler that you *do not* wish to use.
+         ]]>
+      </fail>
+
+      <fail message="Error:">
+         <condition>
+            <and>
+               <os family="windows" />
+               <not>
+                  <or>
+                     <isset property="use.mingw" />
+                     <isset property="use.msvc" />
+                  </or>
+               </not>
+            </and>
+         </condition>
+         <![CDATA[
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
+
+         This looks like a windows machine so you probably need to Configure either:-
+
+         * msvc.dir and msvc.sdk.dir if you wish to use Microsoft Visual Studio compiler
+
+         * mingw.dir if you prefer if you prefer to use MinGW 
+         ]]>
+      </fail>
 
       <condition property="use.gcc">
          <and>
@@ -364,25 +464,24 @@ First consider editing the properties in build.properties
       </condition>
 
       <condition property="optional.amd64.subdir" value="" else="amd64\">
-         <equals arg1="${x86_or_x86_64}" arg2="x86"/>
+         <or>
+            <os arch="x86" />
+            <os arch="i386" />
+         </or>
       </condition>
 
       <condition property="optional.x64.subdir" value="" else="x64\">
-        <equals arg1="${x86_or_x86_64}" arg2="x86"/>
+         <or>
+            <os arch="x86" />
+            <os arch="i386" />
+         </or>
       </condition>
 
 
-      <condition property="optional.app.sdk.lib.subdir" value="lib\" else="lib64\">
-        <equals arg1="${x86_or_x86_64}" arg2="x86"/>
-
-     </condition>
-      
-      <condition property="gcc.m.value" value="32" else="64">
-        <equals arg1="${x86_or_x86_64}" arg2="x86"/>
-      </condition>
-
-      <available file="${msvc.dir}\vc\bin\${optional.amd64.subdir}cl.exe" type="file" property="cl.exists" />
+      <available file="${msvc.dir}\${optional.amd64.subdir}cl.exe" type="file" property="cl.exists" />
 
+	  <echo message="${msvc.dir}\${optional.amd64.subdir}cl.exe"/>
+	  
       <fail message="Error:">
          <condition>
             <and>
@@ -393,10 +492,12 @@ First consider editing the properties in build.properties
             </and>
          </condition>
          <![CDATA[
-         You will need to edit com.amd.aparapi.jni/build.xml to compile aparapi JNI code
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
 
-         Could not find vc\bin\${optional.amd64.subdir}cl under configured msvc.dir. Check if msvc.dir is pointing
-         to a valid Visual Studio installation
+		 
+		 
+         Could not find vc\bin\${optional.amd64.subdir}cl under Configured msvc.dir. Check if msvc.dir is pointing
+         to a valid visual studio installation
          ]]>
       </fail>
 
@@ -407,18 +508,17 @@ First consider editing the properties in build.properties
                   <os family="mac" />
                </not>
                <not>
-                  <isset property="app.sdk.dir" />
+                  <isset property="amd.app.sdk.dir" />
                </not>
             </and>
          </condition>
          <![CDATA[
-         You will need to edit com.amd.aparapi.jni/build.xml to compile aparapi JNI code
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
 
-         You need to set app.sdk.dir to point to the location where OpenCL SDK is installed
+         You need to set amd.app.sdk.dir to point to the location where AMD APP SDK is installed
          ]]>
       </fail>
-      
-      <available file="${app.sdk.dir}" type="dir" property="app.sdk.dir.exists" />
+      <available file="${amd.app.sdk.dir}" type="dir" property="amd.app.sdk.dir.exists" />
 
       <fail message="Error:">
          <condition>
@@ -427,14 +527,14 @@ First consider editing the properties in build.properties
                   <os family="mac" />
                </not>
                <not>
-                  <isset property="app.sdk.dir.exists" />
+                  <isset property="amd.app.sdk.dir.exists" />
                </not>
             </and>
          </condition>
          <![CDATA[
-         You will need to edit com.amd.aparapi.jni/build.xml to compile aparapi JNI code
+         You will need to edit com.amd.aparapi.jni/build.properties to compile aparapi JNI code
 
-         At present app.sdk.dir is set (to ${app.sdk.dir}) but that dir does not exist
+         At present amd.app.sdk.dir is set (to ${amd.app.sdk.dir}) but that dir does not exist
          ]]>
       </fail>
    </target>
@@ -501,11 +601,11 @@ First consider editing the properties in build.properties
       </javah>
    </target>
 
+
    <target name="gcc" if="use.gcc">
       <mkdir dir="${basedir}/dist"/>
       <echo message="linuxcc ${os.arch}" />
-      <exec executable="g++" failonerror="true">
-         <arg value="-m${gcc.m.value}" />
+      <exec executable="g++">
          <arg value="-O3" />
          <arg value="-g" />
          <arg value="-fPIC" />
@@ -513,7 +613,7 @@ First consider editing the properties in build.properties
          <arg value="-I${java.home}/../include" />
          <arg value="-I${java.home}/../include/linux" />
          <arg value="-Iinclude" />
-         <arg value="-I${app.sdk.dir}/include" />
+         <arg value="-I${amd.app.sdk.dir}/include" />
          <arg value="-Isrc/cpp" />
          <arg value="-Isrc/cpp/runKernel" />
          <arg value="-Isrc/cpp/invoke" />
@@ -535,8 +635,7 @@ First consider editing the properties in build.properties
          <arg value="src/cpp/classtools.cpp" />
          <arg value="src/cpp/JNIHelper.cpp" />
          <arg value="src/cpp/agent.cpp" />
-         <arg value="-L${app.sdk.dir}/lib/${x86_or_x86_64}" />
-         <arg value="-L${app.sdk.dir}/${optional.app.sdk.lib.subdir}" />
+         <arg value="-L${amd.app.sdk.dir}/lib/${x86_or_x86_64}" />
          <arg value="-lOpenCL" />
       </exec>
    </target>
@@ -544,7 +643,7 @@ First consider editing the properties in build.properties
    <target name="gcc_mac" if="use.gcc_mac">
       <mkdir dir="${basedir}/dist"/>
       <echo message="gcc ${os.arch}" />
-      <exec executable="g++" failonerror="true">
+      <exec executable="g++">
          <arg value="-O3" />
          <arg value="-g" />
          <arg value="-fPIC" />
@@ -552,9 +651,9 @@ First consider editing the properties in build.properties
          <arg value="-DCL_USE_DEPRECATED_OPENCL_1_1_APIS"/>
          <!-- JDK 6 -->
          <arg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" />
-         <!-- LATEST JDK 7 without JDK 6 -->
-         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_67.jdk/Contents/Home/include/" />
-         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_67.jdk/Contents/Home/include/darwin/" />
+         <!-- JDK 7u51 without JDK 6 -->
+         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk/Contents/Home/include/" />
+         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_12.jdk/Contents/Home/include/darwin/" />
          <arg value="-Iinclude" />
          <arg value="-Isrc/cpp" />
          <arg value="-Isrc/cpp/runKernel" />
@@ -586,7 +685,7 @@ First consider editing the properties in build.properties
    <target name="msvc" if="use.msvc">
       <mkdir dir="${basedir}\dist"/>
       <echo message="msvc ${os.arch}" />
-      <exec executable="${msvc.dir}\vc\bin\${optional.amd64.subdir}cl.exe" failonerror="true">
+      <exec executable="${msvc.dir}\${optional.amd64.subdir}cl.exe">
          <env key="PATH" path="${env.PATH};${msvc.dir}\\Common7\\IDE" />
          <arg value="/nologo" />
          <arg value="/TP" />
@@ -599,9 +698,10 @@ First consider editing the properties in build.properties
          <arg value="/I${java.home}\..\include" />
          <arg value="/I${java.home}\..\include\win32" />
          <arg value="/Iinclude" />
-	     <arg value="/I${app.sdk.dir}\include" />
+	 <arg value="/I${amd.app.sdk.dir}\include" />
          <arg value="/IC:\Program Files (x86)\Windows Kits\8.0\Include\shared" />
          <arg value="/IC:\Program Files (x86)\Windows Kits\8.0\Include\um" />
+	 
          <arg value="/Isrc/cpp" />
          <arg value="/Isrc/cpp/runKernel" />
          <arg value="/Isrc/cpp/invoke" />
@@ -624,20 +724,58 @@ First consider editing the properties in build.properties
          <arg value="/link" />
          <arg value="/libpath:${msvc.dir}\vc\lib\${optional.amd64.subdir}" />
          <arg value="/libpath:${msvc.sdk.dir}\lib\${optional.x64.subdir}" />
-	 <arg value="/libpath:${app.sdk.dir}\lib\${x86_or_x86_64}" />
-	 <arg value="/libpath:${app.sdk.dir}\${optional.app.sdk.lib.subdir}" />
+	 <arg value="/libpath:${amd.app.sdk.dir}\lib\${x86_or_x86_64}" />
          <arg value="/libpath:C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64" />
-         <arg value="OpenCL.lib" />
+         <arg value="C:\Program Files (x86)\AMD APP SDK\2.9-1\lib\x86\OpenCL.lib" />
          <arg value="/out:${basedir}\dist\aparapi_${x86_or_x86_64}.dll" />
       </exec>
    </target>
 
-   <target name="build" depends="clean, javah, msvc, gcc, gcc_mac" />
+   <target name="mingw" if="use.mingw">
+      <mkdir dir="${basedir}\dist"/>
+      <echo message="mingw ${os.arch}" /> 
+      <exec executable="${mingw.dir}/bin/g++">
+         <env key="PATH" path="${env.PATH};${mingw.dir}/bin" />
+         <arg value="-Wall" />
+         <arg value="-O3" />
+         <arg value="-Wl,--kill-at" />
+         <arg value="-DCL_USE_DEPRECATED_OPENCL_1_1_APIS"/>
+         <arg value="-I${java.home}\..\include" />
+         <arg value="-I${java.home}\..\include\win32" />
+         <arg value="-Iinclude" />
+         <arg value="-I${amd.app.sdk.dir}\include" />
+         <arg value="-Isrc/cpp" />
+         <arg value="-Isrc/cpp/runKernel" />
+         <arg value="-Isrc/cpp/invoke" />
+         <arg value="-shared" />
+         <arg value="-o" />
+         <arg value="${basedir}\dist\aparapi_${x86_or_x86_64}.dll" />
+         <arg value="src/cpp/runKernel/Aparapi.cpp" />
+         <arg value="src/cpp/runKernel/ArrayBuffer.cpp" />
+         <arg value="src/cpp/runKernel/AparapiBuffer.cpp" />
+         <arg value="src/cpp/runKernel/Config.cpp" />
+         <arg value="src/cpp/runKernel/JNIContext.cpp" />
+         <arg value="src/cpp/runKernel/KernelArg.cpp" />
+         <arg value="src/cpp/runKernel/ProfileInfo.cpp" />
+         <arg value="src/cpp/runKernel/Range.cpp" />
+         <arg value="src/cpp/invoke/OpenCLJNI.cpp" />
+         <arg value="src/cpp/invoke/OpenCLArgDescriptor.cpp" />
+         <arg value="src/cpp/invoke/OpenCLMem.cpp" />
+         <arg value="src/cpp/CLHelper.cpp" />
+         <arg value="src/cpp/classtools.cpp" />
+         <arg value="src/cpp/JNIHelper.cpp" />
+         <arg value="src/cpp/agent.cpp" />
+         <arg value="-L${amd.app.sdk.dir}\lib\${x86_or_x86_64}" />
+         <arg value="-lOpenCL" />
+      </exec>
+   </target>
+
+   <target name="build" depends="clean, javah, msvc, mingw, gcc, gcc_mac" />
 
    <target name="msvc_cltest" if="use.msvc">
       <mkdir dir="${basedir}\dist"/>
       <echo message="msvc_cltest ${os.arch}" />
-      <exec executable="${msvc.dir}\vc\bin\${optional.amd64.subdir}cl.exe" failonerror="true">
+      <exec executable="${msvc.dir}\vc\bin\${optional.amd64.subdir}cl.exe">
          <env key="PATH" path="${env.PATH};${msvc.dir}\\Common7\\IDE" />
          <arg value="/nologo" />
          <arg value="/TP" />
@@ -645,7 +783,7 @@ First consider editing the properties in build.properties
          <arg value="-DCL_USE_DEPRECATED_OPENCL_1_1_APIS"/>
          <arg value="/I${msvc.dir}\vc\include" />
          <arg value="/I${msvc.sdk.dir}\include" />
-         <arg value="/I${app.sdk.dir}\include" />
+         <arg value="/I${amd.app.sdk.dir}\include" />
          <arg value="/Isrc/cpp" />
          <arg value="/Isrc/cpp/runKernel" />
          <arg value="/Isrc/cpp/invoke" />
@@ -653,8 +791,7 @@ First consider editing the properties in build.properties
          <arg value="/link" />
          <arg value="/libpath:${msvc.dir}\vc\lib\${optional.amd64.subdir}" />
          <arg value="/libpath:${msvc.sdk.dir}\lib\${optional.x64.subdir}" />
-         <arg value="/libpath:${app.sdk.dir}\lib\${x86_or_x86_64}" />
-         <arg value="/libpath:${app.sdk.dir}\${optional.app.sdk.lib.subdir}" />
+         <arg value="/libpath:${amd.app.sdk.dir}\lib\${x86_or_x86_64}" />
          <arg value="OpenCL.lib" />
          <arg value="/out:${basedir}/dist/cltest_${x86_or_x86_64}.exe" />
       </exec>
@@ -663,16 +800,16 @@ First consider editing the properties in build.properties
    <target name="mac_cltest" if="use.gcc_mac">
       <mkdir dir="${basedir}/dist"/>
       <echo message="gcc cltest ${os.arch}" />
-      <exec executable="g++" failonerror="true">
+      <exec executable="g++">
          <arg value="-O3" />
          <arg value="-g" />
          <arg value="-fPIC" />
          <arg value="-DCL_USE_DEPRECATED_OPENCL_1_1_APIS"/>
          <!-- JDK 6 -->
          <arg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" />
-         <!-- Latest JDK 7 without JDK 6 -->
-         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_67.jdk/Contents/Home/include/" />
-         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_67.jdk/Contents/Home/include/darwin/" />
+         <!-- JDK 7u51 without JDK 6 -->
+         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include/" />
+         <arg value="-I/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include/darwin/" />
          <arg value="-Iinclude" />
          <arg value="-Isrc/cpp" />
          <arg value="-Isrc/cpp/runKernel" />
@@ -688,17 +825,16 @@ First consider editing the properties in build.properties
    <target name="gcc_cltest" if="use.gcc">
       <mkdir dir="${basedir}/dist"/>
       <echo message="gcc cltest ${os.arch}" />
-      <exec executable="g++" failonerror="true">
+      <exec executable="g++">
          <arg value="-O3" />
          <arg value="-g" />
          <arg value="-fPIC" />
          <arg value="-DCL_USE_DEPRECATED_OPENCL_1_1_APIS"/>
          <arg value="-I${java.home}/../include" />
          <arg value="-I${java.home}/../include/linux" />
-         <arg value="-I${app.sdk.dir}/include" />
+         <arg value="-I${amd.app.sdk.dir}/include" />
          <arg value="src/cpp/cltest.cpp" />
-         <arg value="-L${app.sdk.dir}/lib/${x86_or_x86_64}" />
-         <arg value="-L${app.sdk.dir}/${optional.app.sdk.lib.subdir}" />
+         <arg value="-L${amd.app.sdk.dir}/lib/${x86_or_x86_64}" />
          <arg value="-lOpenCL" />
          <arg value="-o" />
          <arg value="${basedir}/cltest_${x86_or_x86_64}" />
@@ -708,7 +844,7 @@ First consider editing the properties in build.properties
    <target name="gcc_clt" if="use.gcc">
       <mkdir dir="${basedir}/dist"/>
       <echo message="gcc cltest ${os.arch}" />
-      <exec executable="g++" failonerror="true">
+      <exec executable="g++">
          <arg value="-O3" />
          <arg value="-g" />
          <arg value="-fPIC" />
@@ -719,10 +855,11 @@ First consider editing the properties in build.properties
       </exec>
   </target>
 
+
    <target name="mac_clt" if="use.gcc_mac">
       <mkdir dir="${basedir}/dist"/>
       <echo message="gcc clt ${os.arch}" />
-      <exec executable="g++" failonerror="true">
+      <exec executable="g++">
          <arg value="-O3" />
          <arg value="-g" />
          <arg value="-fPIC" />
diff --git a/com.amd.aparapi.jni/src/cpp/runKernel/Aparapi.cpp b/com.amd.aparapi.jni/src/cpp/runKernel/Aparapi.cpp
index cbad7e81539f48989f847e32edc5ebf643f2b413..d9c969705e2aa8d2fe814f54fde8f1a5a5db48c9 100644
--- a/com.amd.aparapi.jni/src/cpp/runKernel/Aparapi.cpp
+++ b/com.amd.aparapi.jni/src/cpp/runKernel/Aparapi.cpp
@@ -52,7 +52,7 @@
 
 static const int PASS_ID_PREPARING_EXECUTION = -2;
 static const int PASS_ID_COMPLETED_EXECUTION = -1;
-static const int CANCEL_STATUS_FALSE = 0;
+static const int CANCEL_STATUS_FALSE = 0;
 static const int CANCEL_STATUS_TRUE = 1;
 
 //compiler dependant code
@@ -141,10 +141,10 @@ jint writeProfileInfo(JNIContext* jniContext){
          fprintf(jniContext->profileFile, "%d write %s,", pos++, arg->name);
 
          fprintf(jniContext->profileFile, "%lu,%lu,%lu,%lu,",  
-        	(unsigned long)(arg->arrayBuffer->write.queued - currSampleBaseTime)/1000,
-        	(unsigned long)(arg->arrayBuffer->write.submit - currSampleBaseTime)/1000,
-        	(unsigned long)(arg->arrayBuffer->write.start - currSampleBaseTime)/1000,
-        	(unsigned long)(arg->arrayBuffer->write.end - currSampleBaseTime)/1000);
+           (unsigned long)(arg->arrayBuffer->write.queued - currSampleBaseTime)/1000,
+           (unsigned long)(arg->arrayBuffer->write.submit - currSampleBaseTime)/1000,
+           (unsigned long)(arg->arrayBuffer->write.start - currSampleBaseTime)/1000,
+           (unsigned long)(arg->arrayBuffer->write.end - currSampleBaseTime)/1000);
       }
    }
 
@@ -181,10 +181,10 @@ jint writeProfileInfo(JNIContext* jniContext){
             fprintf(jniContext->profileFile, "%d read %s,", pos++, arg->name);
 
             fprintf(jniContext->profileFile, "%lu,%lu,%lu,%lu,",  
-            	(unsigned long)(arg->arrayBuffer->read.queued - currSampleBaseTime)/1000,
-            	(unsigned long)(arg->arrayBuffer->read.submit - currSampleBaseTime)/1000,
-            	(unsigned long)(arg->arrayBuffer->read.start - currSampleBaseTime)/1000,
-            	(unsigned long)(arg->arrayBuffer->read.end - currSampleBaseTime)/1000);
+               (unsigned long)(arg->arrayBuffer->read.queued - currSampleBaseTime)/1000,
+               (unsigned long)(arg->arrayBuffer->read.submit - currSampleBaseTime)/1000,
+               (unsigned long)(arg->arrayBuffer->read.start - currSampleBaseTime)/1000,
+               (unsigned long)(arg->arrayBuffer->read.end - currSampleBaseTime)/1000);
          }
       }
    }
@@ -789,15 +789,15 @@ void enqueueKernel(JNIContext* jniContext, Range& range, int passes, int argPos,
 
    cl_int status = CL_SUCCESS;
    for (int passid=0; passid < passes; passid++) {
-	   
-	   int cancelCode = kernelInBytesAsInts[0];
-	   kernelOutBytesAsInts[0] = passid;
+      
+      int cancelCode = kernelInBytesAsInts[0];
+      kernelOutBytesAsInts[0] = passid;
 
-	   if (cancelCode == CANCEL_STATUS_TRUE) {
-		   fprintf(stderr, "received cancellation, aborting at pass %d\n", passid);
-		   kernelOutBytes[0] = -1;
-		   break;
-	   }
+      if (cancelCode == CANCEL_STATUS_TRUE) {
+         fprintf(stderr, "received cancellation, aborting at pass %d\n", passid);
+         kernelOutBytes[0] = -1;
+         break;
+      }
 
       //size_t offset = 1; // (size_t)((range.globalDims[0]/jniContext->deviceIdc)*dev);
       status = clSetKernelArg(jniContext->kernel, argPos, sizeof(passid), &(passid));
@@ -1079,16 +1079,16 @@ JNI_JAVA(jint, KernelRunnerJNI, runKernelJNI)
 
       cl_int status = CL_SUCCESS;
       JNIContext* jniContext = JNIContext::getJNIContext(jniContextHandle);
-	  jniContext->runKernelInBytes = (jbyte*)jenv->GetDirectBufferAddress(inBuffer);
-	  jniContext->runKernelOutBytes = (jbyte*)jenv->GetDirectBufferAddress(outBuffer);
+      jniContext->runKernelInBytes = (jbyte*)jenv->GetDirectBufferAddress(inBuffer);
+      jniContext->runKernelOutBytes = (jbyte*)jenv->GetDirectBufferAddress(outBuffer);
 
-	  jbyte* kernelInBytes = jniContext->runKernelInBytes;
-	  int* kernelInBytesAsInts = reinterpret_cast<int*>(kernelInBytes);
-	  kernelInBytesAsInts[0] = CANCEL_STATUS_FALSE;
+      jbyte* kernelInBytes = jniContext->runKernelInBytes;
+      int* kernelInBytesAsInts = reinterpret_cast<int*>(kernelInBytes);
+      kernelInBytesAsInts[0] = CANCEL_STATUS_FALSE;
 
-	  jbyte* kernelOutBytes = jniContext->runKernelOutBytes;
-	  int* kernelOutBytesAsInts = reinterpret_cast<int*>(kernelOutBytes);
-	  kernelOutBytesAsInts[0] = PASS_ID_PREPARING_EXECUTION;
+      jbyte* kernelOutBytes = jniContext->runKernelOutBytes;
+      int* kernelOutBytesAsInts = reinterpret_cast<int*>(kernelOutBytes);
+      kernelOutBytesAsInts[0] = PASS_ID_PREPARING_EXECUTION;
 
       if (jniContext->firstRun && config->isProfilingEnabled()){
          try {
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelDeviceProfile.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelDeviceProfile.java
index 87e221ef9060e348a9126c53d1590ff4b3b2eee4..577c13d93e6e5f97740591c1005c4a27ce5921d4 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelDeviceProfile.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelDeviceProfile.java
@@ -1,193 +1,193 @@
-package com.amd.aparapi.internal.kernel;
-
-import com.amd.aparapi.*;
-import com.amd.aparapi.device.*;
-
-import java.text.*;
-import java.util.*;
-import java.util.logging.*;
-
-/**
- * Created by Barney on 02/09/2015.
- */
-public class KernelDeviceProfile {
-
-   private static Logger logger = Logger.getLogger(Config.getLoggerName());
-   private static final double MILLION = 1000 * 1000;
-   private static final int TABLE_COLUMN_HEADER_WIDTH = 21;
-   private static final int TABLE_COLUMN_COUNT_WIDTH = 8;
-   private static final int TABLE_COLUMN_WIDTH;
-   private final Class<? extends Kernel> kernel;
-   private final Device device;
-   private long[] currentTimes = new long[ProfilingEvent.values().length];
-   private long[] accumulatedTimes = new long[ProfilingEvent.values().length];
-   private ProfilingEvent lastEvent = null;
-   private final DecimalFormat format;
-   private long invocationCount = 0;
-
-   static {
-      assert ProfilingEvent.START.ordinal() == 0 : "ProfilingEvent.START.ordinal() != 0";
-      int max = 0;
-      for (ProfilingEvent event : ProfilingEvent.values()) {
-         max = Math.max(max, event.name().length());
-      }
-      TABLE_COLUMN_WIDTH = max + 1;
-   }
-
-   public KernelDeviceProfile(Class<? extends Kernel> kernel, Device device) {
-      this.kernel = kernel;
-      this.device = device;
-      this.format = (DecimalFormat) DecimalFormat.getNumberInstance();
-      format.setMinimumFractionDigits(3);
-      format.setMaximumFractionDigits(3);
-   }
-
-   public void onEvent(ProfilingEvent event) {
-      if (event == ProfilingEvent.START) {
-         if (lastEvent != null) {
-            logger.log(Level.SEVERE, "ProfilingEvent.START encountered without ProfilingEvent.EXECUTED");
-         } else if (lastEvent == ProfilingEvent.START) {
-            logger.log(Level.SEVERE, "Duplicate event ProfilingEvent.START");
-         }
-         Arrays.fill(currentTimes, 0L);
-         ++invocationCount;
-      } else {
-         if (lastEvent == null) {
-            if (event != ProfilingEvent.EXECUTED) {
-               logger.log(Level.SEVERE, "ProfilingEvent.START was not invoked prior to ProfilingEvent." + event);
-            }
-         } else {
-            for (int i = lastEvent.ordinal() + 1; i < event.ordinal(); ++i) {
-               currentTimes[i] = currentTimes[i - 1];
-            }
-         }
-      }
-      currentTimes[event.ordinal()] = System.nanoTime();
-      if (event == ProfilingEvent.EXECUTED) {
-         for (int i = 1; i < currentTimes.length; ++i) {
-            long elapsed = currentTimes[i] - currentTimes[i - 1];
-            if (elapsed < 0) {
-               logger.log(Level.SEVERE, "negative elapsed time for event " + event);
-               break;
-            }
-            accumulatedTimes[i] += elapsed;
-         }
-      }
-      lastEvent = event;
-      if (event == ProfilingEvent.EXECUTED) {
-         lastEvent = null;
-      }
-   }
-
-   /** Elapsed time for a single event only, i.e. since the previous stage rather than from the start. */
-   public double getLastElapsedTime(ProfilingEvent stage) {
-      if (stage == ProfilingEvent.START) {
-         return 0;
-      }
-      return (currentTimes[stage.ordinal()] - currentTimes[stage.ordinal() - 1]) / MILLION;
-   }
-
-   /** Elapsed time for all events {@code from} through {@code to}.*/
-   public double getLastElapsedTime(ProfilingEvent from, ProfilingEvent to) {
-      return (currentTimes[to.ordinal()] - currentTimes[from.ordinal()]) / MILLION;
-   }
-
-   /** Elapsed time for a single event only, i.e. since the previous stage rather than from the start, summed over all executions. */
-   public double getCumulativeElapsedTime(ProfilingEvent stage) {
-      return (accumulatedTimes[stage.ordinal()]) / MILLION;
-   }
-
-   /** Elapsed time of entire execution, summed over all executions. */
-   public double getCumulativeElapsedTimeAll() {
-      double sum = 0;
-      for (int i = 1; i <= ProfilingEvent.EXECUTED.ordinal(); ++i) {
-         sum += accumulatedTimes[i];
-      }
-      return sum;
-   }
-
-   public static String getTableHeader() {
-      int length = ProfilingEvent.values().length;
-      StringBuilder builder = new StringBuilder(150);
-      appendRowHeaders(builder, "Device", "Count");
-      for (int i = 1; i < length; ++i) {
-         ProfilingEvent stage = ProfilingEvent.values()[i];
-         String heading = stage.name();
-         appendCell(builder, heading);
-      }
-      builder.append("  ").append("Total");
-      return builder.toString();
-   }
-
-   public String getLastAsTableRow() {
-      double total = 0;
-      StringBuilder builder = new StringBuilder(150);
-      appendRowHeaders(builder, device.getShortDescription(), String.valueOf(invocationCount));
-      for (int i = 1; i < currentTimes.length; ++i) {
-         ProfilingEvent stage = ProfilingEvent.values()[i];
-         double time = getLastElapsedTime(stage);
-         total += time;
-         String formatted = format.format(time);
-         appendCell(builder, formatted);
-      }
-      builder.append("  ").append(format.format(total));
-      return builder.toString();
-   }
-
-   public String getCumulativeAsTableRow() {
-      return internalCumulativeAsTableRow(false);
-   }
-
-   public String getAverageAsTableRow() {
-      return internalCumulativeAsTableRow(true);
-   }
-
-   private String internalCumulativeAsTableRow(boolean mean) {
-      double total = 0;
-      double count = mean ? invocationCount : 1;
-      StringBuilder builder = new StringBuilder(150);
-      appendRowHeaders(builder, device.getShortDescription(), String.valueOf(invocationCount));
-      for (int i = 1; i < currentTimes.length; ++i) {
-         ProfilingEvent stage = ProfilingEvent.values()[i];
-         double time = getCumulativeElapsedTime(stage);
-         if (mean) {
-            time /= count;
-         }
-         total += time;
-         String formatted = format.format(time);
-         appendCell(builder, formatted);
-      }
-      builder.append("  ").append(format.format(total));
-      return builder.toString();
-   }
-
-   private static void appendRowHeaders(StringBuilder builder, String device, String count) {
-      if (device.length() > TABLE_COLUMN_HEADER_WIDTH - 1) {
-         device = device.substring(0, TABLE_COLUMN_HEADER_WIDTH - 1);
-      }
-      builder.append(device);
-      int padding = TABLE_COLUMN_HEADER_WIDTH - device.length();
-      for (int i = 0; i < padding; ++i) {
-         builder.append(' ');
-      }
-
-      builder.append(count);
-      padding = TABLE_COLUMN_COUNT_WIDTH - count.length();
-      for (int i = 0; i < padding; ++i) {
-         builder.append(' ');
-      }
-   }
-
-   private static void appendCell(StringBuilder builder, String cell) {
-      int padding = TABLE_COLUMN_WIDTH - cell.length();
-      for (int paddingIndex = 0; paddingIndex < padding; ++paddingIndex) {
-         builder.append(' ');
-      }
-      builder.append(cell);
-   }
-
-   @Override
-   public String toString() {
-      return "KernelDeviceProfile{" + kernel.toString() + ", " + device.getShortDescription() + "}";
-   }
-}
+package com.amd.aparapi.internal.kernel;
+
+import com.amd.aparapi.*;
+import com.amd.aparapi.device.*;
+
+import java.text.*;
+import java.util.*;
+import java.util.logging.*;
+
+/**
+ * Created by Barney on 02/09/2015.
+ */
+public class KernelDeviceProfile {
+
+   private static Logger logger = Logger.getLogger(Config.getLoggerName());
+   private static final double MILLION = 1000 * 1000;
+   private static final int TABLE_COLUMN_HEADER_WIDTH = 21;
+   private static final int TABLE_COLUMN_COUNT_WIDTH = 8;
+   private static final int TABLE_COLUMN_WIDTH;
+   private final Class<? extends Kernel> kernel;
+   private final Device device;
+   private long[] currentTimes = new long[ProfilingEvent.values().length];
+   private long[] accumulatedTimes = new long[ProfilingEvent.values().length];
+   private ProfilingEvent lastEvent = null;
+   private final DecimalFormat format;
+   private long invocationCount = 0;
+
+   static {
+      assert ProfilingEvent.START.ordinal() == 0 : "ProfilingEvent.START.ordinal() != 0";
+      int max = 0;
+      for (ProfilingEvent event : ProfilingEvent.values()) {
+         max = Math.max(max, event.name().length());
+      }
+      TABLE_COLUMN_WIDTH = max + 1;
+   }
+
+   public KernelDeviceProfile(Class<? extends Kernel> kernel, Device device) {
+      this.kernel = kernel;
+      this.device = device;
+      this.format = (DecimalFormat) DecimalFormat.getNumberInstance();
+      format.setMinimumFractionDigits(3);
+      format.setMaximumFractionDigits(3);
+   }
+
+   public void onEvent(ProfilingEvent event) {
+      if (event == ProfilingEvent.START) {
+         if (lastEvent != null) {
+            logger.log(Level.SEVERE, "ProfilingEvent.START encountered without ProfilingEvent.EXECUTED");
+         } else if (lastEvent == ProfilingEvent.START) {
+            logger.log(Level.SEVERE, "Duplicate event ProfilingEvent.START");
+         }
+         Arrays.fill(currentTimes, 0L);
+         ++invocationCount;
+      } else {
+         if (lastEvent == null) {
+            if (event != ProfilingEvent.EXECUTED) {
+               logger.log(Level.SEVERE, "ProfilingEvent.START was not invoked prior to ProfilingEvent." + event);
+            }
+         } else {
+            for (int i = lastEvent.ordinal() + 1; i < event.ordinal(); ++i) {
+               currentTimes[i] = currentTimes[i - 1];
+            }
+         }
+      }
+      currentTimes[event.ordinal()] = System.nanoTime();
+      if (event == ProfilingEvent.EXECUTED) {
+         for (int i = 1; i < currentTimes.length; ++i) {
+            long elapsed = currentTimes[i] - currentTimes[i - 1];
+            if (elapsed < 0) {
+               logger.log(Level.SEVERE, "negative elapsed time for event " + event);
+               break;
+            }
+            accumulatedTimes[i] += elapsed;
+         }
+      }
+      lastEvent = event;
+      if (event == ProfilingEvent.EXECUTED) {
+         lastEvent = null;
+      }
+   }
+
+   /** Elapsed time for a single event only, i.e. since the previous stage rather than from the start. */
+   public double getLastElapsedTime(ProfilingEvent stage) {
+      if (stage == ProfilingEvent.START) {
+         return 0;
+      }
+      return (currentTimes[stage.ordinal()] - currentTimes[stage.ordinal() - 1]) / MILLION;
+   }
+
+   /** Elapsed time for all events {@code from} through {@code to}.*/
+   public double getLastElapsedTime(ProfilingEvent from, ProfilingEvent to) {
+      return (currentTimes[to.ordinal()] - currentTimes[from.ordinal()]) / MILLION;
+   }
+
+   /** Elapsed time for a single event only, i.e. since the previous stage rather than from the start, summed over all executions. */
+   public double getCumulativeElapsedTime(ProfilingEvent stage) {
+      return (accumulatedTimes[stage.ordinal()]) / MILLION;
+   }
+
+   /** Elapsed time of entire execution, summed over all executions. */
+   public double getCumulativeElapsedTimeAll() {
+      double sum = 0;
+      for (int i = 1; i <= ProfilingEvent.EXECUTED.ordinal(); ++i) {
+         sum += accumulatedTimes[i];
+      }
+      return sum;
+   }
+
+   public static String getTableHeader() {
+      int length = ProfilingEvent.values().length;
+      StringBuilder builder = new StringBuilder(150);
+      appendRowHeaders(builder, "Device", "Count");
+      for (int i = 1; i < length; ++i) {
+         ProfilingEvent stage = ProfilingEvent.values()[i];
+         String heading = stage.name();
+         appendCell(builder, heading);
+      }
+      builder.append("  ").append("Total");
+      return builder.toString();
+   }
+
+   public String getLastAsTableRow() {
+      double total = 0;
+      StringBuilder builder = new StringBuilder(150);
+      appendRowHeaders(builder, device.getShortDescription(), String.valueOf(invocationCount));
+      for (int i = 1; i < currentTimes.length; ++i) {
+         ProfilingEvent stage = ProfilingEvent.values()[i];
+         double time = getLastElapsedTime(stage);
+         total += time;
+         String formatted = format.format(time);
+         appendCell(builder, formatted);
+      }
+      builder.append("  ").append(format.format(total));
+      return builder.toString();
+   }
+
+   public String getCumulativeAsTableRow() {
+      return internalCumulativeAsTableRow(false);
+   }
+
+   public String getAverageAsTableRow() {
+      return internalCumulativeAsTableRow(true);
+   }
+
+   private String internalCumulativeAsTableRow(boolean mean) {
+      double total = 0;
+      double count = mean ? invocationCount : 1;
+      StringBuilder builder = new StringBuilder(150);
+      appendRowHeaders(builder, device.getShortDescription(), String.valueOf(invocationCount));
+      for (int i = 1; i < currentTimes.length; ++i) {
+         ProfilingEvent stage = ProfilingEvent.values()[i];
+         double time = getCumulativeElapsedTime(stage);
+         if (mean) {
+            time /= count;
+         }
+         total += time;
+         String formatted = format.format(time);
+         appendCell(builder, formatted);
+      }
+      builder.append("  ").append(format.format(total));
+      return builder.toString();
+   }
+
+   private static void appendRowHeaders(StringBuilder builder, String device, String count) {
+      if (device.length() > TABLE_COLUMN_HEADER_WIDTH - 1) {
+         device = device.substring(0, TABLE_COLUMN_HEADER_WIDTH - 1);
+      }
+      builder.append(device);
+      int padding = TABLE_COLUMN_HEADER_WIDTH - device.length();
+      for (int i = 0; i < padding; ++i) {
+         builder.append(' ');
+      }
+
+      builder.append(count);
+      padding = TABLE_COLUMN_COUNT_WIDTH - count.length();
+      for (int i = 0; i < padding; ++i) {
+         builder.append(' ');
+      }
+   }
+
+   private static void appendCell(StringBuilder builder, String cell) {
+      int padding = TABLE_COLUMN_WIDTH - cell.length();
+      for (int paddingIndex = 0; paddingIndex < padding; ++paddingIndex) {
+         builder.append(' ');
+      }
+      builder.append(cell);
+   }
+
+   @Override
+   public String toString() {
+      return "KernelDeviceProfile{" + kernel.toString() + ", " + device.getShortDescription() + "}";
+   }
+}
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManager.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManager.java
index c1f29cbc51c95ed04011346b978f5a1bfd635293..3ced0ae0361ff83686972c6c695b8ba6a8d71345 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManager.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManager.java
@@ -1,300 +1,300 @@
-package com.amd.aparapi.internal.kernel;
-
-import com.amd.aparapi.*;
-import com.amd.aparapi.device.*;
-import com.amd.aparapi.internal.util.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-/**
- * Created by Barney on 24/08/2015.
- */
-public class KernelManager {
-
-   private static KernelManager INSTANCE = new KernelManager();
-   private LinkedHashMap<Class<? extends Kernel>, KernelPreferences> preferences = new LinkedHashMap<>();
-   private LinkedHashMap<Class<? extends Kernel>, KernelProfile> profiles = new LinkedHashMap<>();
-   private LinkedHashMap<Class<? extends Kernel>, Kernel> sharedInstances = new LinkedHashMap<>();
-
-   private KernelPreferences defaultPreferences;
-
-   protected KernelManager() {
-      defaultPreferences = createDefaultPreferences();
-   }
-
-   public static KernelManager instance() {
-      return INSTANCE;
-   }
-
-   public static void setKernelManager(KernelManager manager) {
-      INSTANCE = manager;
-   }
-
-   static {
-      if (Config.dumpProfilesOnExit) {
-         Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-               StringBuilder builder = new StringBuilder(2048);
-               instance().reportProfilingSummary(builder);
-               System.out.println(builder);
-            }
-         });
-      }
-   }
-
-   /** This method returns a shared instance of a given Kernel subclass. The kernelClass needs a no-args constructor, which
-    *  need not be public.
-    *
-    *  <p>Given that compilation of OpenCL is relatively expensive and that (currently!) there is no caching of compiled OpenCL
-    *  it is desirable to only ever create one instance of any given Kernel subclass, which this method facilitates.</p>
-    *
-    *  <p>In order to maintain thread saftey, it is necessary to synchronize on the returned kernel for the duration of the process of setting up,
-    *  executing and extracting the results from that kernel, when using a shared instance.</p>
-    *
-    *  @throws RuntimeException if the class cannot be instantiated
-    */
-   public static <T extends Kernel> T sharedKernelInstance(Class<T> kernelClass) {
-       return instance().getSharedKernelInstance(kernelClass);
-   }
-
-   /** Append a report to {@code builder} which contains information, per Kernel subclass, on which device is currently being used for the
-    * kernel class, and which (if any) devices failed to execute a given Kernel.
-    */
-   public void reportDeviceUsage(StringBuilder builder, boolean withProfilingInfo) {
-      builder.append("Device Usage by Kernel Subclass");
-      if (withProfilingInfo) {
-         builder.append(" (showing mean elapsed times in milliseconds)");
-      }
-      builder.append("\n\n");
-      for (Class<? extends Kernel> klass : preferences.keySet()) {
-         KernelPreferences preferences = this.preferences.get(klass);
-         KernelProfile profile = withProfilingInfo ? profiles.get(klass) : null;
-         builder.append(klass.getName()).append(":\n\tusing ").append(preferences.getPreferredDevice(null).getShortDescription());
-         List<Device> failedDevices = preferences.getFailedDevices();
-         if (failedDevices.size() > 0) {
-            builder.append(", failed devices = ");
-            for (int i = 0; i < failedDevices.size(); ++i) {
-               builder.append(failedDevices.get(i).getShortDescription());
-               if (i < failedDevices.size() - 1) {
-                  builder.append(" | ");
-               }
-            }
-         }
-         if (profile != null) {
-            builder.append("\n");
-            int row = 0;
-            for (KernelDeviceProfile deviceProfile : profile.getDeviceProfiles()) {
-               if (row == 0) {
-                  builder.append(deviceProfile.getTableHeader()).append("\n");
-               }
-               builder.append(deviceProfile.getAverageAsTableRow()).append("\n");
-               ++row;
-            }
-         }
-         builder.append("\n");
-      }
-   }
-
-   public void reportProfilingSummary(StringBuilder builder) {
-      builder.append("\nProfiles by Kernel Subclass (mean elapsed times in milliseconds)\n\n");
-      builder.append(KernelDeviceProfile.getTableHeader()).append("\n");
-      for (Class<? extends Kernel> kernelClass : profiles.keySet()) {
-         String simpleName = Reflection.getSimpleName(kernelClass);
-         String kernelName = "----------------- [[ " + simpleName + " ]] ";
-         builder.append(kernelName);
-         int dashes = 132 - kernelName.length();
-         for (int i = 0; i < dashes; ++i) {
-            builder.append('-');
-         }
-         builder.append("\n");
-         KernelProfile kernelProfile = profiles.get(kernelClass);
-         for (KernelDeviceProfile deviceProfile : kernelProfile.getDeviceProfiles()) {
-            builder.append(deviceProfile.getAverageAsTableRow()).append("\n");
-         }
-      }
-   }
-
-
-   public KernelPreferences getPreferences(Kernel kernel) {
-      synchronized (preferences) {
-         KernelPreferences kernelPreferences = preferences.get(kernel.getClass());
-         if (kernelPreferences == null) {
-            kernelPreferences = new KernelPreferences(this, kernel.getClass());
-            preferences.put(kernel.getClass(), kernelPreferences);
-         }
-         return kernelPreferences;
-      }
-   }
-
-   public void setPreferredDevices(Kernel _kernel, LinkedHashSet<Device> _devices) {
-      KernelPreferences kernelPreferences = getPreferences(_kernel);
-      kernelPreferences.setPreferredDevices(_devices);
-   }
-
-   public KernelPreferences getDefaultPreferences() {
-      return defaultPreferences;
-   }
-
-   public void setDefaultPreferredDevices(LinkedHashSet<Device> _devices) {
-      defaultPreferences.setPreferredDevices(_devices);
-   }
-
-   protected KernelPreferences createDefaultPreferences() {
-      KernelPreferences preferences = new KernelPreferences(this, null);
-      preferences.setPreferredDevices(createDefaultPreferredDevices());
-      return preferences;
-   }
-
-   private <T extends Kernel> T getSharedKernelInstance(Class<T> kernelClass) {
-      synchronized (sharedInstances) {
-         T shared = (T) sharedInstances.get(kernelClass);
-         if (shared == null) {
-            try {
-               Constructor<T> constructor = kernelClass.getConstructor();
-               constructor.setAccessible(true);
-               shared = constructor.newInstance();
-               sharedInstances.put(kernelClass, shared);
-            }
-            catch (Exception e) {
-               throw new RuntimeException(e);
-            }
-         }
-         return shared;
-      }
-   }
-
-   protected LinkedHashSet<Device> createDefaultPreferredDevices() {
-      LinkedHashSet<Device> devices = new LinkedHashSet<>();
-
-      List<OpenCLDevice> accelerators = OpenCLDevice.listDevices(Device.TYPE.ACC);
-      List<OpenCLDevice> gpus = OpenCLDevice.listDevices(Device.TYPE.GPU);
-      List<OpenCLDevice> cpus = OpenCLDevice.listDevices(Device.TYPE.CPU);
-
-      Collections.sort(accelerators, getDefaultAcceleratorComparator());
-      Collections.sort(gpus, getDefaultGPUComparator());
-
-      List<Device.TYPE> preferredDeviceTypes = getPreferredDeviceTypes();
-
-      for (Device.TYPE type : preferredDeviceTypes) {
-         switch (type) {
-            case UNKNOWN:
-               throw new AssertionError("UNKNOWN device type not supported");
-            case GPU:
-               devices.addAll(gpus);
-               break;
-            case CPU:
-               devices.add(cpus.get(0));
-               break;
-            case JTP:
-               devices.add(JavaDevice.THREAD_POOL);
-               break;
-            case SEQ:
-               devices.add(JavaDevice.SEQUENTIAL);
-               break;
-            case ACC:
-               devices.addAll(accelerators);
-               break;
-            case ALT:
-               devices.add(JavaDevice.ALTERNATIVE_ALGORITHM);
-               break;
-         }
-      }
-
-      return devices;
-   }
-
-   protected List<Device.TYPE> getPreferredDeviceTypes() {
-      return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU, Device.TYPE.ALT, Device.TYPE.JTP);
-   }
-
-   /** NB, returns -ve for the better device. */
-   protected Comparator<OpenCLDevice> getDefaultAcceleratorComparator() {
-      return new Comparator<OpenCLDevice>() {
-         @Override
-         public int compare(OpenCLDevice left, OpenCLDevice right) {
-            return (right.getMaxComputeUnits() - left.getMaxComputeUnits());
-         }
-      };
-   }
-
-   /** NB, returns -ve for the better device. */
-   protected Comparator<OpenCLDevice> getDefaultGPUComparator() {
-      return new Comparator<OpenCLDevice>() {
-         @Override
-         public int compare(OpenCLDevice left, OpenCLDevice right) {
-            return selectLhs(left, right) ? -1 : 1;
-         }
-      };
-   }
-
-   public Device bestDevice() {
-      return getDefaultPreferences().getPreferredDevice(null);
-   }
-
-    protected static boolean selectLhs(OpenCLDevice _deviceLhs, OpenCLDevice _deviceRhs) {
-       boolean nvidiaLhs = _deviceLhs.getOpenCLPlatform().getVendor().toLowerCase().contains("nvidia");
-       boolean nvidiaRhs = _deviceRhs.getOpenCLPlatform().getVendor().toLowerCase().contains("nvidia");
-       if (nvidiaLhs || nvidiaRhs) {
-          return selectLhsIfCUDA(_deviceLhs, _deviceRhs);
-       }
-       return _deviceLhs.getMaxComputeUnits() > _deviceRhs.getMaxComputeUnits();
-    }
-
-    /** NVidia/CUDA architecture reports maxComputeUnits in a completely different context, i.e. maxComputeUnits is not same as
-     * (is much less than) the number of OpenCL cores available.
-     *
-     * <p>Therefore when comparing an NVidia device we use different criteria.</p>
-     */
-    protected static boolean selectLhsIfCUDA(OpenCLDevice _deviceLhs, OpenCLDevice _deviceRhs) {
-       if (_deviceLhs.getType() != _deviceRhs.getType()) {
-          return selectLhsByType(_deviceLhs.getType(), _deviceRhs.getType());
-       }
-       return _deviceLhs.getMaxWorkGroupSize() == _deviceRhs.getMaxWorkGroupSize()
-               ? _deviceLhs.getGlobalMemSize() > _deviceRhs.getGlobalMemSize()
-               : _deviceLhs.getMaxWorkGroupSize() > _deviceRhs.getMaxWorkGroupSize();
-    }
-
-   private static boolean selectLhsByType(Device.TYPE lhs, Device.TYPE rhs) {
-      return lhs.rank < rhs.rank;
-   }
-
-   public KernelProfile getProfile(Class<? extends Kernel> kernelClass) {
-      synchronized (profiles) {
-         KernelProfile profile = profiles.get(kernelClass);
-         if (profile == null) {
-            profile = new KernelProfile(kernelClass);
-            profiles.put(kernelClass, profile);
-         }
-         return profile;
-      }
-   }
-
-   /** New home for deprecated methods of {@link Device}. */
-   public static class DeprecatedMethods {
-
-      @Deprecated
-      public static Device firstDevice(Device.TYPE _type) {
-         List<Device> devices = instance().getDefaultPreferences().getPreferredDevices(null);
-         for (Device device : devices) {
-            if(device.getType() == _type) {
-               return device;
-            }
-         }
-         return null;
-      }
-
-      @SuppressWarnings("deprecation")
-      @Deprecated
-      public static Device bestGPU() {
-         return firstDevice(Device.TYPE.GPU);
-      }
-
-      @SuppressWarnings("deprecation")
-      @Deprecated
-      public static Device bestACC() {
-         return firstDevice(Device.TYPE.ACC);
-      }
-   }
-}
+package com.amd.aparapi.internal.kernel;
+
+import com.amd.aparapi.*;
+import com.amd.aparapi.device.*;
+import com.amd.aparapi.internal.util.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Created by Barney on 24/08/2015.
+ */
+public class KernelManager {
+
+   private static KernelManager INSTANCE = new KernelManager();
+   private LinkedHashMap<Class<? extends Kernel>, KernelPreferences> preferences = new LinkedHashMap<>();
+   private LinkedHashMap<Class<? extends Kernel>, KernelProfile> profiles = new LinkedHashMap<>();
+   private LinkedHashMap<Class<? extends Kernel>, Kernel> sharedInstances = new LinkedHashMap<>();
+
+   private KernelPreferences defaultPreferences;
+
+   protected KernelManager() {
+      defaultPreferences = createDefaultPreferences();
+   }
+
+   public static KernelManager instance() {
+      return INSTANCE;
+   }
+
+   public static void setKernelManager(KernelManager manager) {
+      INSTANCE = manager;
+   }
+
+   static {
+      if (Config.dumpProfilesOnExit) {
+         Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override
+            public void run() {
+               StringBuilder builder = new StringBuilder(2048);
+               instance().reportProfilingSummary(builder);
+               System.out.println(builder);
+            }
+         });
+      }
+   }
+
+   /** This method returns a shared instance of a given Kernel subclass. The kernelClass needs a no-args constructor, which
+    *  need not be public.
+    *
+    *  <p>Given that compilation of OpenCL is relatively expensive and that (currently!) there is no caching of compiled OpenCL
+    *  it is desirable to only ever create one instance of any given Kernel subclass, which this method facilitates.</p>
+    *
+    *  <p>In order to maintain thread saftey, it is necessary to synchronize on the returned kernel for the duration of the process of setting up,
+    *  executing and extracting the results from that kernel, when using a shared instance.</p>
+    *
+    *  @throws RuntimeException if the class cannot be instantiated
+    */
+   public static <T extends Kernel> T sharedKernelInstance(Class<T> kernelClass) {
+       return instance().getSharedKernelInstance(kernelClass);
+   }
+
+   /** Append a report to {@code builder} which contains information, per Kernel subclass, on which device is currently being used for the
+    * kernel class, and which (if any) devices failed to execute a given Kernel.
+    */
+   public void reportDeviceUsage(StringBuilder builder, boolean withProfilingInfo) {
+      builder.append("Device Usage by Kernel Subclass");
+      if (withProfilingInfo) {
+         builder.append(" (showing mean elapsed times in milliseconds)");
+      }
+      builder.append("\n\n");
+      for (Class<? extends Kernel> klass : preferences.keySet()) {
+         KernelPreferences preferences = this.preferences.get(klass);
+         KernelProfile profile = withProfilingInfo ? profiles.get(klass) : null;
+         builder.append(klass.getName()).append(":\n\tusing ").append(preferences.getPreferredDevice(null).getShortDescription());
+         List<Device> failedDevices = preferences.getFailedDevices();
+         if (failedDevices.size() > 0) {
+            builder.append(", failed devices = ");
+            for (int i = 0; i < failedDevices.size(); ++i) {
+               builder.append(failedDevices.get(i).getShortDescription());
+               if (i < failedDevices.size() - 1) {
+                  builder.append(" | ");
+               }
+            }
+         }
+         if (profile != null) {
+            builder.append("\n");
+            int row = 0;
+            for (KernelDeviceProfile deviceProfile : profile.getDeviceProfiles()) {
+               if (row == 0) {
+                  builder.append(deviceProfile.getTableHeader()).append("\n");
+               }
+               builder.append(deviceProfile.getAverageAsTableRow()).append("\n");
+               ++row;
+            }
+         }
+         builder.append("\n");
+      }
+   }
+
+   public void reportProfilingSummary(StringBuilder builder) {
+      builder.append("\nProfiles by Kernel Subclass (mean elapsed times in milliseconds)\n\n");
+      builder.append(KernelDeviceProfile.getTableHeader()).append("\n");
+      for (Class<? extends Kernel> kernelClass : profiles.keySet()) {
+         String simpleName = Reflection.getSimpleName(kernelClass);
+         String kernelName = "----------------- [[ " + simpleName + " ]] ";
+         builder.append(kernelName);
+         int dashes = 132 - kernelName.length();
+         for (int i = 0; i < dashes; ++i) {
+            builder.append('-');
+         }
+         builder.append("\n");
+         KernelProfile kernelProfile = profiles.get(kernelClass);
+         for (KernelDeviceProfile deviceProfile : kernelProfile.getDeviceProfiles()) {
+            builder.append(deviceProfile.getAverageAsTableRow()).append("\n");
+         }
+      }
+   }
+
+
+   public KernelPreferences getPreferences(Kernel kernel) {
+      synchronized (preferences) {
+         KernelPreferences kernelPreferences = preferences.get(kernel.getClass());
+         if (kernelPreferences == null) {
+            kernelPreferences = new KernelPreferences(this, kernel.getClass());
+            preferences.put(kernel.getClass(), kernelPreferences);
+         }
+         return kernelPreferences;
+      }
+   }
+
+   public void setPreferredDevices(Kernel _kernel, LinkedHashSet<Device> _devices) {
+      KernelPreferences kernelPreferences = getPreferences(_kernel);
+      kernelPreferences.setPreferredDevices(_devices);
+   }
+
+   public KernelPreferences getDefaultPreferences() {
+      return defaultPreferences;
+   }
+
+   public void setDefaultPreferredDevices(LinkedHashSet<Device> _devices) {
+      defaultPreferences.setPreferredDevices(_devices);
+   }
+
+   protected KernelPreferences createDefaultPreferences() {
+      KernelPreferences preferences = new KernelPreferences(this, null);
+      preferences.setPreferredDevices(createDefaultPreferredDevices());
+      return preferences;
+   }
+
+   private <T extends Kernel> T getSharedKernelInstance(Class<T> kernelClass) {
+      synchronized (sharedInstances) {
+         T shared = (T) sharedInstances.get(kernelClass);
+         if (shared == null) {
+            try {
+               Constructor<T> constructor = kernelClass.getConstructor();
+               constructor.setAccessible(true);
+               shared = constructor.newInstance();
+               sharedInstances.put(kernelClass, shared);
+            }
+            catch (Exception e) {
+               throw new RuntimeException(e);
+            }
+         }
+         return shared;
+      }
+   }
+
+   protected LinkedHashSet<Device> createDefaultPreferredDevices() {
+      LinkedHashSet<Device> devices = new LinkedHashSet<>();
+
+      List<OpenCLDevice> accelerators = OpenCLDevice.listDevices(Device.TYPE.ACC);
+      List<OpenCLDevice> gpus = OpenCLDevice.listDevices(Device.TYPE.GPU);
+      List<OpenCLDevice> cpus = OpenCLDevice.listDevices(Device.TYPE.CPU);
+
+      Collections.sort(accelerators, getDefaultAcceleratorComparator());
+      Collections.sort(gpus, getDefaultGPUComparator());
+
+      List<Device.TYPE> preferredDeviceTypes = getPreferredDeviceTypes();
+
+      for (Device.TYPE type : preferredDeviceTypes) {
+         switch (type) {
+            case UNKNOWN:
+               throw new AssertionError("UNKNOWN device type not supported");
+            case GPU:
+               devices.addAll(gpus);
+               break;
+            case CPU:
+               devices.add(cpus.get(0));
+               break;
+            case JTP:
+               devices.add(JavaDevice.THREAD_POOL);
+               break;
+            case SEQ:
+               devices.add(JavaDevice.SEQUENTIAL);
+               break;
+            case ACC:
+               devices.addAll(accelerators);
+               break;
+            case ALT:
+               devices.add(JavaDevice.ALTERNATIVE_ALGORITHM);
+               break;
+         }
+      }
+
+      return devices;
+   }
+
+   protected List<Device.TYPE> getPreferredDeviceTypes() {
+      return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU, Device.TYPE.ALT, Device.TYPE.JTP);
+   }
+
+   /** NB, returns -ve for the better device. */
+   protected Comparator<OpenCLDevice> getDefaultAcceleratorComparator() {
+      return new Comparator<OpenCLDevice>() {
+         @Override
+         public int compare(OpenCLDevice left, OpenCLDevice right) {
+            return (right.getMaxComputeUnits() - left.getMaxComputeUnits());
+         }
+      };
+   }
+
+   /** NB, returns -ve for the better device. */
+   protected Comparator<OpenCLDevice> getDefaultGPUComparator() {
+      return new Comparator<OpenCLDevice>() {
+         @Override
+         public int compare(OpenCLDevice left, OpenCLDevice right) {
+            return selectLhs(left, right) ? -1 : 1;
+         }
+      };
+   }
+
+   public Device bestDevice() {
+      return getDefaultPreferences().getPreferredDevice(null);
+   }
+
+    protected static boolean selectLhs(OpenCLDevice _deviceLhs, OpenCLDevice _deviceRhs) {
+       boolean nvidiaLhs = _deviceLhs.getOpenCLPlatform().getVendor().toLowerCase().contains("nvidia");
+       boolean nvidiaRhs = _deviceRhs.getOpenCLPlatform().getVendor().toLowerCase().contains("nvidia");
+       if (nvidiaLhs || nvidiaRhs) {
+          return selectLhsIfCUDA(_deviceLhs, _deviceRhs);
+       }
+       return _deviceLhs.getMaxComputeUnits() > _deviceRhs.getMaxComputeUnits();
+    }
+
+    /** NVidia/CUDA architecture reports maxComputeUnits in a completely different context, i.e. maxComputeUnits is not same as
+     * (is much less than) the number of OpenCL cores available.
+     *
+     * <p>Therefore when comparing an NVidia device we use different criteria.</p>
+     */
+    protected static boolean selectLhsIfCUDA(OpenCLDevice _deviceLhs, OpenCLDevice _deviceRhs) {
+       if (_deviceLhs.getType() != _deviceRhs.getType()) {
+          return selectLhsByType(_deviceLhs.getType(), _deviceRhs.getType());
+       }
+       return _deviceLhs.getMaxWorkGroupSize() == _deviceRhs.getMaxWorkGroupSize()
+               ? _deviceLhs.getGlobalMemSize() > _deviceRhs.getGlobalMemSize()
+               : _deviceLhs.getMaxWorkGroupSize() > _deviceRhs.getMaxWorkGroupSize();
+    }
+
+   private static boolean selectLhsByType(Device.TYPE lhs, Device.TYPE rhs) {
+      return lhs.rank < rhs.rank;
+   }
+
+   public KernelProfile getProfile(Class<? extends Kernel> kernelClass) {
+      synchronized (profiles) {
+         KernelProfile profile = profiles.get(kernelClass);
+         if (profile == null) {
+            profile = new KernelProfile(kernelClass);
+            profiles.put(kernelClass, profile);
+         }
+         return profile;
+      }
+   }
+
+   /** New home for deprecated methods of {@link Device}. */
+   public static class DeprecatedMethods {
+
+      @Deprecated
+      public static Device firstDevice(Device.TYPE _type) {
+         List<Device> devices = instance().getDefaultPreferences().getPreferredDevices(null);
+         for (Device device : devices) {
+            if(device.getType() == _type) {
+               return device;
+            }
+         }
+         return null;
+      }
+
+      @SuppressWarnings("deprecation")
+      @Deprecated
+      public static Device bestGPU() {
+         return firstDevice(Device.TYPE.GPU);
+      }
+
+      @SuppressWarnings("deprecation")
+      @Deprecated
+      public static Device bestACC() {
+         return firstDevice(Device.TYPE.ACC);
+      }
+   }
+}
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManagers.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManagers.java
index 8a31cd70be8d93895f8254b66a2f266f4bc164c6..11b28b7085cc4798c4e25a9fd94bbf699b0408f3 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManagers.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelManagers.java
@@ -1,31 +1,31 @@
-package com.amd.aparapi.internal.kernel;
-
-import com.amd.aparapi.device.*;
-
-import java.util.*;
-
-/**
- * KernelManager instances useful for debugging.
- */
-public class KernelManagers {
-
-   public static final KernelManager JTP_ONLY = new KernelManager() {
-
-      private List<Device.TYPE> types = Collections.singletonList(Device.TYPE.JTP);
-
-      @Override
-      protected List<Device.TYPE> getPreferredDeviceTypes() {
-         return types;
-      }
-   };
-
-   public static final KernelManager SEQUENTIAL_ONLY = new KernelManager() {
-
-      private final List<Device.TYPE> types = Collections.singletonList(Device.TYPE.SEQ);
-
-      @Override
-      protected List<Device.TYPE> getPreferredDeviceTypes() {
-         return types;
-      }
-   };
-}
+package com.amd.aparapi.internal.kernel;
+
+import com.amd.aparapi.device.*;
+
+import java.util.*;
+
+/**
+ * KernelManager instances useful for debugging.
+ */
+public class KernelManagers {
+
+   public static final KernelManager JTP_ONLY = new KernelManager() {
+
+      private List<Device.TYPE> types = Collections.singletonList(Device.TYPE.JTP);
+
+      @Override
+      protected List<Device.TYPE> getPreferredDeviceTypes() {
+         return types;
+      }
+   };
+
+   public static final KernelManager SEQUENTIAL_ONLY = new KernelManager() {
+
+      private final List<Device.TYPE> types = Collections.singletonList(Device.TYPE.SEQ);
+
+      @Override
+      protected List<Device.TYPE> getPreferredDeviceTypes() {
+         return types;
+      }
+   };
+}
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelProfile.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelProfile.java
index 17e479a85fcfb7a9874943ade1d0c1cc042b674a..647ab5133fc3d50fa24247b1508d080eeaafdf7b 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelProfile.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelProfile.java
@@ -1,103 +1,103 @@
-package com.amd.aparapi.internal.kernel;
-
-import com.amd.aparapi.*;
-import com.amd.aparapi.device.*;
-
-import java.util.*;
-import java.util.logging.*;
-
-/**
- * Collects profiling information per kernel class per device. Not thread safe, it is necessary for client code to correctly synchronize on
- * objects of this class.
- */
-public class KernelProfile {
-
-   private static Logger logger = Logger.getLogger(Config.getLoggerName());
-   private final Class<? extends Kernel> kernelClass;
-   private LinkedHashMap<Device, KernelDeviceProfile> deviceProfiles = new LinkedHashMap<>();
-   private Device currentDevice;
-   private Device lastDevice;
-   private KernelDeviceProfile currentDeviceProfile;
-
-   public KernelProfile(Class<? extends Kernel> _kernelClass) {
-      kernelClass = _kernelClass;
-   }
-
-   public double getLastExecutionTime() {
-      KernelDeviceProfile lastDeviceProfile = getLastDeviceProfile();
-      return lastDeviceProfile == null ? Double.NaN : lastDeviceProfile.getLastElapsedTime(ProfilingEvent.START, ProfilingEvent.EXECUTED);
-   }
-
-   public double getLastConversionTime() {
-      KernelDeviceProfile lastDeviceProfile = getLastDeviceProfile();
-      return lastDeviceProfile == null ? Double.NaN : lastDeviceProfile.getLastElapsedTime(ProfilingEvent.START, ProfilingEvent.EXECUTED);   }
-
-   public double getAccumulatedTotalTime() {
-      KernelDeviceProfile lastDeviceProfile = getLastDeviceProfile();
-      if (lastDeviceProfile == null) {
-         return Double.NaN;
-      }
-      else {
-         return lastDeviceProfile.getCumulativeElapsedTimeAll();
-      }
-   }
-
-   private KernelDeviceProfile getLastDeviceProfile() {
-      return null;
-   }
-
-   void onStart(Device device) {
-      currentDevice = device;
-      synchronized (deviceProfiles) {
-         currentDeviceProfile = deviceProfiles.get(device);
-         if (currentDeviceProfile == null) {
-            currentDeviceProfile = new KernelDeviceProfile(kernelClass, device);
-            deviceProfiles.put(device, currentDeviceProfile);
-         }
-      }
-      currentDeviceProfile.onEvent(ProfilingEvent.START);
-   }
-
-   void onEvent(ProfilingEvent event) {
-      switch (event) {
-         case CLASS_MODEL_BUILT: // fallthrough
-         case OPENCL_GENERATED: // fallthrough
-         case OPENCL_COMPILED: // fallthrough
-         case PREPARE_EXECUTE: // fallthrough
-         case EXECUTED: // fallthrough
-         {
-            if (currentDeviceProfile == null) {
-               logger.log(Level.SEVERE, "Error in KernelProfile, no currentDevice (synchronization error?");
-            }
-            currentDeviceProfile.onEvent(event);
-            break;
-         }
-         case START:
-            throw new IllegalArgumentException("must use onStart(Device) to start profiling");
-         default:
-            throw new IllegalArgumentException("Unhandled event " + event);
-      }
-   }
-
-   void onFinishedExecution() {
-      reset();
-   }
-
-   private void reset() {
-      lastDevice = currentDevice;
-      currentDevice = null;
-      currentDeviceProfile = null;
-   }
-
-   public Collection<Device> getDevices() {
-      return deviceProfiles.keySet();
-   }
-
-   public Collection<KernelDeviceProfile> getDeviceProfiles() {
-      return deviceProfiles.values();
-   }
-
-   public KernelDeviceProfile getDeviceProfile(Device device) {
-      return deviceProfiles.get(device);
-   }
-}
+package com.amd.aparapi.internal.kernel;
+
+import com.amd.aparapi.*;
+import com.amd.aparapi.device.*;
+
+import java.util.*;
+import java.util.logging.*;
+
+/**
+ * Collects profiling information per kernel class per device. Not thread safe, it is necessary for client code to correctly synchronize on
+ * objects of this class.
+ */
+public class KernelProfile {
+
+   private static Logger logger = Logger.getLogger(Config.getLoggerName());
+   private final Class<? extends Kernel> kernelClass;
+   private LinkedHashMap<Device, KernelDeviceProfile> deviceProfiles = new LinkedHashMap<>();
+   private Device currentDevice;
+   private Device lastDevice;
+   private KernelDeviceProfile currentDeviceProfile;
+
+   public KernelProfile(Class<? extends Kernel> _kernelClass) {
+      kernelClass = _kernelClass;
+   }
+
+   public double getLastExecutionTime() {
+      KernelDeviceProfile lastDeviceProfile = getLastDeviceProfile();
+      return lastDeviceProfile == null ? Double.NaN : lastDeviceProfile.getLastElapsedTime(ProfilingEvent.START, ProfilingEvent.EXECUTED);
+   }
+
+   public double getLastConversionTime() {
+      KernelDeviceProfile lastDeviceProfile = getLastDeviceProfile();
+      return lastDeviceProfile == null ? Double.NaN : lastDeviceProfile.getLastElapsedTime(ProfilingEvent.START, ProfilingEvent.EXECUTED);   }
+
+   public double getAccumulatedTotalTime() {
+      KernelDeviceProfile lastDeviceProfile = getLastDeviceProfile();
+      if (lastDeviceProfile == null) {
+         return Double.NaN;
+      }
+      else {
+         return lastDeviceProfile.getCumulativeElapsedTimeAll();
+      }
+   }
+
+   private KernelDeviceProfile getLastDeviceProfile() {
+      return null;
+   }
+
+   void onStart(Device device) {
+      currentDevice = device;
+      synchronized (deviceProfiles) {
+         currentDeviceProfile = deviceProfiles.get(device);
+         if (currentDeviceProfile == null) {
+            currentDeviceProfile = new KernelDeviceProfile(kernelClass, device);
+            deviceProfiles.put(device, currentDeviceProfile);
+         }
+      }
+      currentDeviceProfile.onEvent(ProfilingEvent.START);
+   }
+
+   void onEvent(ProfilingEvent event) {
+      switch (event) {
+         case CLASS_MODEL_BUILT: // fallthrough
+         case OPENCL_GENERATED: // fallthrough
+         case OPENCL_COMPILED: // fallthrough
+         case PREPARE_EXECUTE: // fallthrough
+         case EXECUTED: // fallthrough
+         {
+            if (currentDeviceProfile == null) {
+               logger.log(Level.SEVERE, "Error in KernelProfile, no currentDevice (synchronization error?");
+            }
+            currentDeviceProfile.onEvent(event);
+            break;
+         }
+         case START:
+            throw new IllegalArgumentException("must use onStart(Device) to start profiling");
+         default:
+            throw new IllegalArgumentException("Unhandled event " + event);
+      }
+   }
+
+   void onFinishedExecution() {
+      reset();
+   }
+
+   private void reset() {
+      lastDevice = currentDevice;
+      currentDevice = null;
+      currentDeviceProfile = null;
+   }
+
+   public Collection<Device> getDevices() {
+      return deviceProfiles.keySet();
+   }
+
+   public Collection<KernelDeviceProfile> getDeviceProfiles() {
+      return deviceProfiles.values();
+   }
+
+   public KernelDeviceProfile getDeviceProfile(Device device) {
+      return deviceProfiles.get(device);
+   }
+}
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/ProfilingEvent.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/ProfilingEvent.java
index 77959b65cc75208325ffbafd5e954c6499aa07cd..fcb06bfd38a478b80d899c52566a7d5660c105a0 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/ProfilingEvent.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/ProfilingEvent.java
@@ -1,8 +1,8 @@
-package com.amd.aparapi.internal.kernel;
-
-/**
- * Created by Barney on 02/09/2015.
- */
-public enum ProfilingEvent {
-   START, CLASS_MODEL_BUILT, OPENCL_GENERATED, OPENCL_COMPILED, PREPARE_EXECUTE, EXECUTED
-}
+package com.amd.aparapi.internal.kernel;
+
+/**
+ * Created by Barney on 02/09/2015.
+ */
+public enum ProfilingEvent {
+   START, CLASS_MODEL_BUILT, OPENCL_GENERATED, OPENCL_COMPILED, PREPARE_EXECUTE, EXECUTED
+}
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/util/Reflection.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/util/Reflection.java
index 3f2ad65d866931cb04f9739020717f47ba15fc4f..ba7a553a0b45d1828d25815cb823c8c34a378604 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/util/Reflection.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/util/Reflection.java
@@ -1,18 +1,18 @@
-package com.amd.aparapi.internal.util;
-
-/**
- * Created by Barney on 03/09/2015.
- */
-public class Reflection {
-
-   /** Avoids getting dumb empty names for anonymous inners. */
-   public static String getSimpleName(Class<?> klass) {
-      String simpleName = klass.getSimpleName();
-      if (simpleName.isEmpty()) {
-         String fullName = klass.getName();
-         int index = fullName.lastIndexOf('.');
-         simpleName = (index < 0) ? fullName : fullName.substring(index + 1);
-      }
-      return simpleName;
-   }
-}
+package com.amd.aparapi.internal.util;
+
+/**
+ * Created by Barney on 03/09/2015.
+ */
+public class Reflection {
+
+   /** Avoids getting dumb empty names for anonymous inners. */
+   public static String getSimpleName(Class<?> klass) {
+      String simpleName = klass.getSimpleName();
+      if (simpleName.isEmpty()) {
+         String fullName = klass.getName();
+         int index = fullName.lastIndexOf('.');
+         simpleName = (index < 0) ? fullName : fullName.substring(index + 1);
+      }
+      return simpleName;
+   }
+}
diff --git a/samples/configuration/src/com/amd/aparapi/sample/configuration/ConfigurationDemo.java b/samples/configuration/src/com/amd/aparapi/sample/configuration/ConfigurationDemo.java
index 2e52a6e1113f61d475f46a942800d15a1088d052..bdfb3cf21d21ad26b50772f56c91d231cc7e352e 100644
--- a/samples/configuration/src/com/amd/aparapi/sample/configuration/ConfigurationDemo.java
+++ b/samples/configuration/src/com/amd/aparapi/sample/configuration/ConfigurationDemo.java
@@ -1,82 +1,82 @@
-package com.amd.aparapi.sample.configuration;
-
-import com.amd.aparapi.*;
-import com.amd.aparapi.internal.kernel.*;
-
-import java.util.*;
-
-/**
- * Tests device selection via {@link com.amd.aparapi.internal.kernel.KernelManager}.
- */
-public class ConfigurationDemo {
-   public static void main(String[] ignored) {
-      System.setProperty("com.amd.aparapi.dumpProfilesOnExit", "true");
-
-      StringBuilder report;
-
-      List<Integer> tests = Arrays.asList(0, 1, 2, 3);
-      int reps = 300;
-      for (int rep = 0; rep < reps; ++rep) {
-         runTests(rep == 0, tests);
-
-         if (rep % 100 == 99 || rep == 0) {
-            report = new StringBuilder("rep = " + rep + "\n");
-            KernelManager.instance().reportDeviceUsage(report, true);
-            System.out.println(report);
-         }
-      }
-   }
-
-   private static void runTests(boolean verbose, List<Integer> testIndicesToRun) {
-      final int globalSize = 1;
-      Kernel kernel;
-      if (testIndicesToRun.contains(0)) {
-         if (verbose) {
-            System.out.println();
-            System.out.println("Testing default KernelPreferences with kernel which cannot be run in OpenCL, with fallback algorithm");
-            System.out.println();
-         }
-         kernel = new KernelWithAlternateFallbackAlgorithm();
-         kernel.execute(globalSize);
-         kernel.dispose();
-      }
-
-      if (testIndicesToRun.contains(1)) {
-         if (verbose) {
-            System.out.println();
-            System.out.println("Testing default KernelPreferences with kernel which cannot be run in OpenCL, without fallback algorithm");
-            System.out.println();
-         }
-         kernel = new KernelWithoutAlternateFallbackAlgorithm();
-         kernel.execute(globalSize);
-         kernel.dispose();
-      }
-
-      if (testIndicesToRun.contains(2)) {
-         if (verbose) {
-            System.out.println();
-            System.out.println("Retesting previous case, should jump straight to regular java implementation without warnings");
-            System.out.println();
-         }
-         kernel = new KernelWithoutAlternateFallbackAlgorithm();
-         kernel.execute(globalSize);
-         kernel.dispose();
-      }
-
-      if (testIndicesToRun.contains(3)) {
-         if (verbose) {
-            System.out.println();
-            System.out.println("Testing default KernelPreferences with kernel which should be run in OpenCL");
-            System.out.println();
-         }
-         KernelOkayInOpenCL clKernel = new KernelOkayInOpenCL();
-         kernel = clKernel;
-         kernel.execute(clKernel.inChars.length);
-         String result = new String(clKernel.outChars);
-         if (verbose) {
-            System.out.println("kernel output: " + result);
-         }
-         kernel.dispose();
-      }
-   }
-}
+package com.amd.aparapi.sample.configuration;
+
+import com.amd.aparapi.*;
+import com.amd.aparapi.internal.kernel.*;
+
+import java.util.*;
+
+/**
+ * Tests device selection via {@link com.amd.aparapi.internal.kernel.KernelManager}.
+ */
+public class ConfigurationDemo {
+   public static void main(String[] ignored) {
+      System.setProperty("com.amd.aparapi.dumpProfilesOnExit", "true");
+
+      StringBuilder report;
+
+      List<Integer> tests = Arrays.asList(0, 1, 2, 3);
+      int reps = 300;
+      for (int rep = 0; rep < reps; ++rep) {
+         runTests(rep == 0, tests);
+
+         if (rep % 100 == 99 || rep == 0) {
+            report = new StringBuilder("rep = " + rep + "\n");
+            KernelManager.instance().reportDeviceUsage(report, true);
+            System.out.println(report);
+         }
+      }
+   }
+
+   private static void runTests(boolean verbose, List<Integer> testIndicesToRun) {
+      final int globalSize = 1;
+      Kernel kernel;
+      if (testIndicesToRun.contains(0)) {
+         if (verbose) {
+            System.out.println();
+            System.out.println("Testing default KernelPreferences with kernel which cannot be run in OpenCL, with fallback algorithm");
+            System.out.println();
+         }
+         kernel = new KernelWithAlternateFallbackAlgorithm();
+         kernel.execute(globalSize);
+         kernel.dispose();
+      }
+
+      if (testIndicesToRun.contains(1)) {
+         if (verbose) {
+            System.out.println();
+            System.out.println("Testing default KernelPreferences with kernel which cannot be run in OpenCL, without fallback algorithm");
+            System.out.println();
+         }
+         kernel = new KernelWithoutAlternateFallbackAlgorithm();
+         kernel.execute(globalSize);
+         kernel.dispose();
+      }
+
+      if (testIndicesToRun.contains(2)) {
+         if (verbose) {
+            System.out.println();
+            System.out.println("Retesting previous case, should jump straight to regular java implementation without warnings");
+            System.out.println();
+         }
+         kernel = new KernelWithoutAlternateFallbackAlgorithm();
+         kernel.execute(globalSize);
+         kernel.dispose();
+      }
+
+      if (testIndicesToRun.contains(3)) {
+         if (verbose) {
+            System.out.println();
+            System.out.println("Testing default KernelPreferences with kernel which should be run in OpenCL");
+            System.out.println();
+         }
+         KernelOkayInOpenCL clKernel = new KernelOkayInOpenCL();
+         kernel = clKernel;
+         kernel.execute(clKernel.inChars.length);
+         String result = new String(clKernel.outChars);
+         if (verbose) {
+            System.out.println("kernel output: " + result);
+         }
+         kernel.dispose();
+      }
+   }
+}
diff --git a/samples/configuration/src/com/amd/aparapi/sample/configuration/CustomConfigurationDemo.java b/samples/configuration/src/com/amd/aparapi/sample/configuration/CustomConfigurationDemo.java
index 476737d42fe97c6d3bd6eee1fc5f78fc105ebaf5..5ee4b8eb53155ecbe3d69737f46b347ecf45f693 100644
--- a/samples/configuration/src/com/amd/aparapi/sample/configuration/CustomConfigurationDemo.java
+++ b/samples/configuration/src/com/amd/aparapi/sample/configuration/CustomConfigurationDemo.java
@@ -1,42 +1,42 @@
-package com.amd.aparapi.sample.configuration;
-
-import com.amd.aparapi.device.*;
-import com.amd.aparapi.internal.kernel.*;
-
-import java.util.*;
-
-/**
- * Created by Barney on 31/08/2015.
- */
-public class CustomConfigurationDemo {
-
-   public static void main(String[] ignored) {
-      System.setProperty("com.amd.aparapi.dumpProfilesOnExit", "true");
-      KernelManager manager = new KernelManager() {
-         @Override
-         protected List<Device.TYPE> getPreferredDeviceTypes() {
-            return Arrays.asList(Device.TYPE.CPU, Device.TYPE.ALT, Device.TYPE.JTP);
-         }
-      };
-      KernelManager.setKernelManager(manager);
-
-      System.out.println("\nTesting custom KernelPreferences with kernel, preferences choose CPU");
-      KernelOkayInOpenCL kernel = new KernelOkayInOpenCL();
-      kernel.execute(kernel.inChars.length);
-      System.out.println(kernel.outChars);
-
-      System.out.println("\nTesting custom KernelPreferences with kernel, preferences specify CPU but kernel vetos CPU");
-      kernel = new KernelOkayInOpenCL() {
-         @Override
-         public boolean isAllowDevice(Device _device) {
-            return _device.getType() != Device.TYPE.CPU;
-         }
-      };
-      kernel.execute(kernel.inChars.length);
-      System.out.println(kernel.outChars);
-
-      StringBuilder report = new StringBuilder("\n");
-      KernelManager.instance().reportDeviceUsage(report, true);
-      System.out.println(report);
-   }
-}
+package com.amd.aparapi.sample.configuration;
+
+import com.amd.aparapi.device.*;
+import com.amd.aparapi.internal.kernel.*;
+
+import java.util.*;
+
+/**
+ * Created by Barney on 31/08/2015.
+ */
+public class CustomConfigurationDemo {
+
+   public static void main(String[] ignored) {
+      System.setProperty("com.amd.aparapi.dumpProfilesOnExit", "true");
+      KernelManager manager = new KernelManager() {
+         @Override
+         protected List<Device.TYPE> getPreferredDeviceTypes() {
+            return Arrays.asList(Device.TYPE.CPU, Device.TYPE.ALT, Device.TYPE.JTP);
+         }
+      };
+      KernelManager.setKernelManager(manager);
+
+      System.out.println("\nTesting custom KernelPreferences with kernel, preferences choose CPU");
+      KernelOkayInOpenCL kernel = new KernelOkayInOpenCL();
+      kernel.execute(kernel.inChars.length);
+      System.out.println(kernel.outChars);
+
+      System.out.println("\nTesting custom KernelPreferences with kernel, preferences specify CPU but kernel vetos CPU");
+      kernel = new KernelOkayInOpenCL() {
+         @Override
+         public boolean isAllowDevice(Device _device) {
+            return _device.getType() != Device.TYPE.CPU;
+         }
+      };
+      kernel.execute(kernel.inChars.length);
+      System.out.println(kernel.outChars);
+
+      StringBuilder report = new StringBuilder("\n");
+      KernelManager.instance().reportDeviceUsage(report, true);
+      System.out.println(report);
+   }
+}
diff --git a/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelOkayInOpenCL.java b/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelOkayInOpenCL.java
index 6ed54e5b7ef47eab954c42a3e9df5a795de42566..9423d7159affedccce83b34a68409d0bc307940a 100644
--- a/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelOkayInOpenCL.java
+++ b/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelOkayInOpenCL.java
@@ -1,21 +1,21 @@
-package com.amd.aparapi.sample.configuration;
-
-/**
- * Created by Barney on 24/08/2015.
- */
-public class KernelOkayInOpenCL extends com.amd.aparapi.Kernel {
-   char[] inChars = "KernelOkayInOpenCL".toCharArray();
-   char[] outChars = new char[inChars.length];
-
-   @Override
-   public void run() {
-      int index = getGlobalId();
-      oops();
-      outChars[index] = inChars[index];
-   }
-
-   @NoCL
-   private void oops() {
-      System.out.println("Oops, running in kernel in Java");
-   }
-}
+package com.amd.aparapi.sample.configuration;
+
+/**
+ * Created by Barney on 24/08/2015.
+ */
+public class KernelOkayInOpenCL extends com.amd.aparapi.Kernel {
+   char[] inChars = "KernelOkayInOpenCL".toCharArray();
+   char[] outChars = new char[inChars.length];
+
+   @Override
+   public void run() {
+      int index = getGlobalId();
+      oops();
+      outChars[index] = inChars[index];
+   }
+
+   @NoCL
+   private void oops() {
+      System.out.println("Oops, running in kernel in Java");
+   }
+}
diff --git a/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithAlternateFallbackAlgorithm.java b/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithAlternateFallbackAlgorithm.java
index 670e6a669193d05d017648f04515a439d9f0b8d1..6aee117e412dc48041f6b1c234f09494360ea369 100644
--- a/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithAlternateFallbackAlgorithm.java
+++ b/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithAlternateFallbackAlgorithm.java
@@ -1,24 +1,24 @@
-package com.amd.aparapi.sample.configuration;
-
-import com.amd.aparapi.*;
-
-/**
- * Kernel which will always fail to run on an OpenCLDevice but has an alternative fallback algorithm.
- */
-public class KernelWithAlternateFallbackAlgorithm extends Kernel {
-   @Override
-   public void run() {
-      // deliberately, will fail to generate OpenCL as println is unsupported
-      System.out.println("Running in Java (regular algorithm)");
-   }
-
-   @Override
-   public boolean hasFallbackAlgorithm() {
-      return true;
-   }
-
-   @Override
-   public void executeFallbackAlgorithm(Range _range, int _passes) {
-      System.out.println("Running in Java (alternate non-parallel algorithm)");
-   }
-}
+package com.amd.aparapi.sample.configuration;
+
+import com.amd.aparapi.*;
+
+/**
+ * Kernel which will always fail to run on an OpenCLDevice but has an alternative fallback algorithm.
+ */
+public class KernelWithAlternateFallbackAlgorithm extends Kernel {
+   @Override
+   public void run() {
+      // deliberately, will fail to generate OpenCL as println is unsupported
+      System.out.println("Running in Java (regular algorithm)");
+   }
+
+   @Override
+   public boolean hasFallbackAlgorithm() {
+      return true;
+   }
+
+   @Override
+   public void executeFallbackAlgorithm(Range _range, int _passes) {
+      System.out.println("Running in Java (alternate non-parallel algorithm)");
+   }
+}
diff --git a/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithoutAlternateFallbackAlgorithm.java b/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithoutAlternateFallbackAlgorithm.java
index 1096a092e38c2c696c153d969eb31b54c4d8c844..bdc1a12099458950c5a3b860dbd50aab0442d96e 100644
--- a/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithoutAlternateFallbackAlgorithm.java
+++ b/samples/configuration/src/com/amd/aparapi/sample/configuration/KernelWithoutAlternateFallbackAlgorithm.java
@@ -1,14 +1,14 @@
-package com.amd.aparapi.sample.configuration;
-
-import com.amd.aparapi.*;
-
-/**
- * Kernel which will always fail to run on an OpenCLDevice but has an alternative fallback algorithm.
- */
-public class KernelWithoutAlternateFallbackAlgorithm extends Kernel {
-   @Override
-   public void run() {
-      // deliberately, will fail to generate OpenCL as println is unsupported
-      System.out.println("Running in Java (regular algorithm)");
-   }
-}
+package com.amd.aparapi.sample.configuration;
+
+import com.amd.aparapi.*;
+
+/**
+ * Kernel which will always fail to run on an OpenCLDevice but has an alternative fallback algorithm.
+ */
+public class KernelWithoutAlternateFallbackAlgorithm extends Kernel {
+   @Override
+   public void run() {
+      // deliberately, will fail to generate OpenCL as println is unsupported
+      System.out.println("Running in Java (regular algorithm)");
+   }
+}
diff --git a/samples/configuration/src/com/amd/aparapi/sample/configuration/LegacyConfigurationDemo.java b/samples/configuration/src/com/amd/aparapi/sample/configuration/LegacyConfigurationDemo.java
index db4149a139f3b50d49de50b94c48ceafe98ec4e5..73ea9d70a79aa0ebf11e63cb11188c805303b0e8 100644
--- a/samples/configuration/src/com/amd/aparapi/sample/configuration/LegacyConfigurationDemo.java
+++ b/samples/configuration/src/com/amd/aparapi/sample/configuration/LegacyConfigurationDemo.java
@@ -1,26 +1,26 @@
-package com.amd.aparapi.sample.configuration;
-
-import com.amd.aparapi.*;
-import com.amd.aparapi.internal.kernel.*;
-
-/**
- * Tests device selection when circumventing the {@link com.amd.aparapi.internal.kernel.KernelManager} by using the legacy mechanism
- * (setExecutionMode, etc.).
- */
-public class LegacyConfigurationDemo {
-
-   @SuppressWarnings("deprecation")
-   public static void main(String[] ignored) {
-      System.setProperty("com.amd.aparapi.executionMode", "GPU,CPU,SEQ");
-      System.setProperty("com.amd.aparapi.dumpProfilesOnExit", "true");
-
-      KernelWithAlternateFallbackAlgorithm kernel = new KernelWithAlternateFallbackAlgorithm();
-      kernel.setExecutionMode(Kernel.EXECUTION_MODE.GPU);
-      int globalRange = 1;
-      kernel.execute(globalRange);
-
-      StringBuilder report = new StringBuilder("\n");
-      KernelManager.instance().reportDeviceUsage(report, true);
-      System.out.println(report);
-   }
-}
+package com.amd.aparapi.sample.configuration;
+
+import com.amd.aparapi.*;
+import com.amd.aparapi.internal.kernel.*;
+
+/**
+ * Tests device selection when circumventing the {@link com.amd.aparapi.internal.kernel.KernelManager} by using the legacy mechanism
+ * (setExecutionMode, etc.).
+ */
+public class LegacyConfigurationDemo {
+
+   @SuppressWarnings("deprecation")
+   public static void main(String[] ignored) {
+      System.setProperty("com.amd.aparapi.executionMode", "GPU,CPU,SEQ");
+      System.setProperty("com.amd.aparapi.dumpProfilesOnExit", "true");
+
+      KernelWithAlternateFallbackAlgorithm kernel = new KernelWithAlternateFallbackAlgorithm();
+      kernel.setExecutionMode(Kernel.EXECUTION_MODE.GPU);
+      int globalRange = 1;
+      kernel.execute(globalRange);
+
+      StringBuilder report = new StringBuilder("\n");
+      KernelManager.instance().reportDeviceUsage(report, true);
+      System.out.println(report);
+   }
+}