diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ff92765ccaaefa57e986ce4810a2fdac569c888..b312ab1a854533b52ce69b82a6f230e0fe45a4a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
 * Java execution mode now provides detailed backtraces of failed Kernel threads including passId, groupIds, globalIds and localIds
 * Internal translation of bytecode is now facilitated by the BCEL library
 * Scala support has been added (see unit tests).
+* Fix arrays of AtomicInteger stored on local variables no longer fail with type cast exception while generating OpenCL (support for I_ALOAD_0,1,2,3 bytecode instructions)
 
 ## 1.9.0
 
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 07babbf4de7efeab2df0cec5c26522ab7b372c29..7f4eef9480bced902a861278aebc7f6ff5cc53ae 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -58,3 +58,4 @@ Below are some of the specific details of various contributions.
 * Luis Mendes submited PR to Fix Java execution mode to fail-fast when Kernel execution fails
 * Luis Mendes submited PR to Java execution mode now provides detailed backtraces of failed Kernel threads including passId, groupIds, globalIds and localIds
 * Saurabh Rawat contributed apache BCEL bytecode parsing and Scala support.
+* Luis Mendes submited PR #139 to Fix arrays of AtomicInteger stored on local variables no longer fail with type cast exception - Partial fix for #138
\ No newline at end of file
diff --git a/src/main/java/com/aparapi/internal/writer/BlockWriter.java b/src/main/java/com/aparapi/internal/writer/BlockWriter.java
index 22789c60d42ddd4e56c079f75f0b87d8e51cb389..013239d05513c2e6025191a5af2eac73cd9be252 100644
--- a/src/main/java/com/aparapi/internal/writer/BlockWriter.java
+++ b/src/main/java/com/aparapi/internal/writer/BlockWriter.java
@@ -790,12 +790,20 @@ public abstract class BlockWriter{
    }
 
    private boolean isMultiDimensionalArray(final AccessArrayElement arrayLoadInstruction) {
-       AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
-      return isMultiDimensionalArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry());
+      AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
+       if (accessInstanceField != null) {
+           return isMultiDimensionalArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry());
+       } else {
+           //Arrays can be accessed through local variables instead of instance fields, thus, AccessField instruction
+           //can be null.
+           AccessLocalVariable accessLocalVariable = getUltimateInstanceLocalVarAccess(arrayLoadInstruction);
+           //Directly check for multi-dimensional array...
+           return accessLocalVariable.getLocalVariableInfo().getVariableDescriptor().startsWith("[[");
+       }      
    }
 
    private boolean isObjectArray(final AccessArrayElement arrayLoadInstruction) {
-       AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
+      AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
       return isObjectArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry());
    }
 
@@ -804,10 +812,25 @@ public abstract class BlockWriter{
       while (load instanceof I_AALOAD) {
          load = load.getFirstChild();
       }
+      
+      if (load instanceof I_ALOAD ||
+          load instanceof I_ALOAD_0 || load instanceof I_ALOAD_1 || load instanceof I_ALOAD_2 || load instanceof I_ALOAD_3)  {
+          //It is not a Field Access, it is either a constant index local variable (0..3), or is a variable indexed local variable (>3)
+          return null;
+      }
 
       return (AccessField) load;
    }
 
+   private AccessLocalVariable getUltimateInstanceLocalVarAccess(AccessArrayElement arrayLoadInstruction) {
+       Instruction load = arrayLoadInstruction.getArrayRef();
+       while (load instanceof I_AALOAD) {
+          load = load.getFirstChild();
+       }
+
+       return (AccessLocalVariable)load;
+   }   
+   
    public void writeMethod(MethodCall _methodCall, MethodEntry _methodEntry) throws CodeGenException {
       boolean noCL = _methodEntry.getOwnerClassModel().getNoCLMethods()
             .contains(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
diff --git a/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java b/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f70f16cbe7fdd4057d3d272430892743331d46f
--- /dev/null
+++ b/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2016 - 2018 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.aparapi.runtime;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.aparapi.Kernel;
+import com.aparapi.Range;
+import com.aparapi.device.Device;
+import com.aparapi.device.JavaDevice;
+import com.aparapi.device.OpenCLDevice;
+import com.aparapi.internal.kernel.KernelManager;
+
+public class LocalAtomicVariableArrayTest {
+    private static final int SIZE = 10;
+    
+    private static OpenCLDevice openCLDevice = null;
+
+    private class CLKernelManager extends KernelManager {
+        @Override
+        protected List<Device.TYPE> getPreferredDeviceTypes() {
+            return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU);
+        }
+    }
+    
+    private class JTPKernelManager extends KernelManager {
+        private JTPKernelManager() {
+            LinkedHashSet<Device> preferredDevices = new LinkedHashSet<Device>(1);
+            preferredDevices.add(JavaDevice.THREAD_POOL);
+            setDefaultPreferredDevices(preferredDevices);
+        }
+        @Override
+        protected List<Device.TYPE> getPreferredDeviceTypes() {
+            return Arrays.asList(Device.TYPE.JTP);
+        }
+    }
+
+    @Before
+    public void setUpBeforeClass() throws Exception {
+        KernelManager.setKernelManager(new CLKernelManager());
+        Device device = KernelManager.instance().bestDevice();
+        assumeTrue (device != null && device instanceof OpenCLDevice);
+        openCLDevice = (OpenCLDevice) device;
+    }
+
+    @After
+    public void classTeardown() {
+        Util.resetKernelManager();
+    }
+
+    @Test
+    public void simpleConstIndexOpenCLTest() {
+        SimpleConstIndexLocalVarKernel myKernel = new SimpleConstIndexLocalVarKernel();
+        Range range = openCLDevice.createRange(SIZE, SIZE);
+        try {
+            myKernel.execute(range);
+            assertEquals("Atomic increment doesn't match, index 1", SIZE, myKernel.atomics[1].get());
+            assertEquals("Atomic increment doesn't match, index 2", SIZE, myKernel.atomics[2].get());
+            assertEquals("Atomic increment doesn't match, index 3", SIZE, myKernel.atomics[3].get());            
+        } finally {
+            myKernel.dispose();
+        }
+    }        
+
+    @Test
+    public void simpleVarIndexOpenCLTest() {
+        SimpleVarIndexLocalVarKernel myKernel = new SimpleVarIndexLocalVarKernel();
+        Range range = openCLDevice.createRange(SIZE, SIZE);
+        try {
+            myKernel.execute(range);
+            assertEquals("Atomic increment doesn't match", SIZE, myKernel.atomics[4].get());
+        } finally {
+            myKernel.dispose();
+        }
+    }        
+
+    public class SimpleConstIndexLocalVarKernel extends Kernel {
+        private AtomicInteger[] atomics = new AtomicInteger[SIZE];
+
+        public SimpleConstIndexLocalVarKernel() {
+            for (int i = 0; i < atomics.length; i++) {
+                atomics[i] = new AtomicInteger(0);
+            }
+        }
+
+        @Override 
+        public void run() {
+            atomicUpdate1(atomics, 1);
+            atomicUpdate2(2, atomics);
+            atomicUpdate3(3, 0, atomics);
+        }
+
+        public int atomicUpdate1(AtomicInteger[] arr, int index) {
+            //Exercises I_ALOAD_1
+            return atomicInc(arr[index]);    
+        }
+
+        public int atomicUpdate2(int index, AtomicInteger[] arr) {
+            //Exercises I_ALOAD_2
+            return atomicInc(arr[index]);    
+        }
+        
+        public int atomicUpdate3(int index, int indexB, AtomicInteger[] arr) {
+            //Exercises I_ALOAD_3
+            return atomicInc(arr[index+indexB]);    
+        }     
+    }
+    
+    public class SimpleVarIndexLocalVarKernel extends Kernel {
+        private AtomicInteger[] atomics = new AtomicInteger[SIZE];
+
+        public SimpleVarIndexLocalVarKernel() {
+            for (int i = 0; i < atomics.length; i++) {
+                atomics[i] = new AtomicInteger(0);
+            }
+        }
+
+        @Override 
+        public void run() {
+            atomicUpdate4(4, 0, 0, atomics);
+        }
+
+        public int atomicUpdate4(int index, int indexB, int indexC, AtomicInteger[] arr) {
+            //Exercises I_ALOAD - when index is greater than 3
+            return atomicInc(arr[index+indexB+indexC]);
+        }   
+    }
+}