diff --git a/doc/ChoosingSpecificDevicesForExecution.md b/doc/ChoosingSpecificDevicesForExecution.md
new file mode 100644
index 0000000000000000000000000000000000000000..62b4ce089e982347ece86397f538793849c5918e
--- /dev/null
+++ b/doc/ChoosingSpecificDevicesForExecution.md
@@ -0,0 +1,58 @@
+#ChoosingSpecificDevicesForExecution
+*Using the new Device API's to choose Kernel execution on a specific device. Updated Sep 18, 2012 by frost.g...@gmail.com*
+
+Previously Aparapi chose the first GPU device when Kernel.execute() was called. This make it easy to execute simple Kernels, but was problematic when users wished finer control over which device should be chosen. Especially when the first device may be unsuitable. We recently added new classes and API's to allow the developer to specify exactly which device we intend to target.
+
+A new Device class has been added. This allows the user to select a specific device; either by calling a helper method Device.firstGPU() or Device.best(). Or by allowing the user to iterate through all devices and choose one based on some other criteria (capabilities? vendor name?).
+
+So selecting the 'best' (most performant) device could be achieved using.
+
+    Device device = Device.best();
+
+Alternatively if I wanted the first AMD GPU device I might use:-
+
+    Device chosen=null;
+    for (Device device: devices.getAll()){
+       if (device.getVendor().contains("AMD") && device.isGPU()){
+          chosen = device;
+          break;
+       }
+    }
+
+A Device can be queried `(isGPU(), isOpenCL(), isGroup(), isJava(), getOpenCLPlatform(), getMaxMemory(), getLocalSizes())` to yield it's characteristics.
+
+To execute on a specific device we must use the device to create our range.
+
+    Range range = device.createRange2D(width, height);
+
+This allows the Range to be created with knowledge of the underlying device. So for example device.createRange3D(1024, 1024, 1024, 16, 16, 16) will fail if the device does not allow a local size of (16x16x16).
+
+A range created using a device method captures the device which created it. The range instance has a device field which is set by the device which creates it.
+
+It's as if we had this code
+
+    Range range = Range.create(width, height);
+    range.setDevice(device);
+
+So the Range locks the device that it can be used with.
+
+Now when we have a Kernel.
+
+    Kernel kernel = new Kernel(){
+        @Override public void run(){
+          ...
+        }
+    }
+
+And we then use a device created range.
+
+    Device device = Device.firstGPU();
+    Kernel kernel = new Kernel(){
+        @Override public void run(){
+          // uses input[];
+        }
+    };
+    range = device.createRange2D(1024, 1024);
+    kernel.execute(range);
+
+We have forced execution on the first GPU.
diff --git a/doc/FrequentlyAskedQuestions.md b/doc/FrequentlyAskedQuestions.md
new file mode 100644
index 0000000000000000000000000000000000000000..4092dff8f4fc173fdf75bd7fd08c8ab9708ae904
--- /dev/null
+++ b/doc/FrequentlyAskedQuestions.md
@@ -0,0 +1,134 @@
+#FrequentlyAskedQuestions
+*Frequently Asked Questions Updated Oct 17, 2012 by frost.g...@gmail.com*
+
+##Frequently Asked Questions
+
+##Why is this project called Aparapi and how is it pronounced?
+
+Aparapi is just a contraction of A PAR{allel} API and is pronounced (ap-per-rap-ee).
+
+##Does Aparapi only work with AMD graphics cards?
+
+No. Aparapi has been tested with AMD's OpenCL enabled drivers and devices as well as a limited set of NVidia devices and drivers on Windows, Linux and Mac OSX platforms. The minimal requirement at runtime is OpenCL 1.1. If you have a compatible OpenCL 1.1 runtime and supported devices Aparapi should work.
+
+Although the build is currently configured for AMD APP SDK, OpenCL is an open standard and we look forward to contributions which will allow Aparapi to be built against other OpenCL SDK's.
+
+Note that dll's built using AMD APP SDK will work on other platforms at runtime. So the binary builds are expected to work on all OpenCL 1.1 platforms.
+
+Witold Bolt has kindly supplied the patches to allow Mac OS support. The Mac OS build will run against OpenCL 1.1 and 1.0 runtimes, but we won't fix any issues reported against the OpenCL 1.0, your code may run, or may not.
+
+Aparapi may be used in JTP (Java Thread Pool) mode on any platform supported by Oracle®’s JDK.
+
+## Does Aparapi only support AMD CPUs?
+
+No, there is nothing restricting Aparapi to AMD CPUs. The JNI code that we use may run on any x86/x64 machine provided there is a compatible Java Virtual Machine® JVM implementation for your platform.
+
+##Will there be an Aparapi-like translator for .NET?
+
+This is still an early technology and Aparapi is currently focused on Java® enablement. There are similar projects targeting .NET (See www.tidepowerd.com)
+
+##How can I profile the OpenCL kernels that Aparapi generates? Can I get details on the latency of my kernel request?How do I optimize my kernel?
+
+AMD offers the ‘AMD APP Profiler’ which can be used to profile the kernels. With Aparapi, we recommend using the command line mode of the profiler, which is described in the release notes. Using the ‘AMD APP Profiler’ you can see how much time is taken by each kernel execution and buffer transfer. Also, in each kernel, you can get more detailed information on things like memory reads and writes, and other useful data.
+
+##Can I have multiple threads all using the GPU compute capabilities?
+
+Yes. There might be a performance impact if the device becomes a bottleneck. However, OpenCL and your GPU driver are designed to coordinate the various threads of execution.
+
+##Can I make method calls from the run method?
+
+You can generally only make calls to other methods declared in the same class as the initial run() method. Aparapi will follow this call chain to try to determine whether it can create OpenCL. If, for example, Aparapi encounters System.out.println("Hello World") ( call to a method not in the users Kernel class) it will detect this and refuse to consider the call chain as an OpenCL candidate.
+
+One exception to this rule allows a kernel to access or mutate the state of objects held in simple arrays via their setters/getters. For example a kernel can include :-
+
+    out[i].setValue(in[i].getValue()*5);
+
+##Does Aparapi support vectorized types?
+
+Due to Java's lack of vector types (float4 for example) Aparapi can't directly use them. Also, due to Java's lack of operator overloading, simulating these with Java abstracts could lead to very complex and unwieldy code.
+
+##Is there a way I can see the generated OpenCL?
+
+Yes, by using adding -Dcom.amd.aparapi.enableShowGeneratedOpenCL=true to your command line when you start your JVM.
+
+##Does Aparapi support sharing buffers with JOGL? Can I exploit the features of JOGAMP/glugen?
+
+Rather than only supporting display-oriented compute, we are pursuing general data parallel compute. Therefore, we have chosen not to bind Aparapi too closely with JOGL.
+
+##What is the performance delta from handcrafted OpenCL?
+
+This depends heavily on the application. Although we can currently show 20x performance improvement on some compute intensive Java applications compared with the same algorithm using a Java Thread Pool a developer who is prepared to handcraft and hand-tune OpenCL and write custom host code in C/C++ is likely to see better performance than Aparapi may achieve.
+
+We understand that some user may use Aparapi as a gateway technology to test their Java code before porting to hand-crafted/tuned OpenCL.
+
+##Are you working with Project Lambda for offloading/parallelizing suitable work?
+
+We are following the progress of Project Lambda (currently scheduled for inclusion in Java 8) and would like to be able to leverage Lambda expression format in Aparapi, but none exists now.
+
+##Can I select a specific GPU if I have more than one card?
+
+Under review. At present, Aparapi just looks for the first AMD GPU (or APU) device. If the community has feedback on its preference, let us know.
+
+##Can I get the demos/samples presented at JavaOne or ADFS?
+
+The Squares and Mandlebrot sample code is included in the binary download of Aparapi. The NBody source is not included in the binary (because of a dependency on JOGL). We have, however, included the NBody code as an example project in the Open Source tree (code.google.com/p/aparapi) and provide details and we provide details on how to install the appropriate JOGL components.
+
+##Can Mersenne twister be ported as a random number function inside the kernel class?
+
+You can elect to implement your own Mersenne twister and use it in our own derived Kernel.
+
+##Does Aparapi use JNI?
+
+Yes, we do ship a small JNI shim to handle the host OpenCL calls.
+
+##How can I confirm that my code is actually executing on the GPU?
+
+From within the Java code itself you can query the execution mode after Kernel.execute(n) has returned.
+
+    Kernel kernel = new Kernel(){
+       @Override public void run(){
+       }
+    } ;
+    kernel.execute(1024);
+    System.out.priintln(“Execution mode = “+kernel.getExecutionMode());
+
+The above code fragment will print either ‘GPU’ if the kernel executed on the GPU or JTP if Aparapi executed the Kernel in a Java Thread Pool.
+
+Alternatively, setting the property –Dcom.amd.aparapi.enableShowExecutionModes=true when you start your JVM will cause Aparapi to automatically report the execution mode of all kernels to stdout.
+
+##Why does Aparapi need me to compile my code with -g?
+
+Aparapi extracts most of the information required to create OpenCL from the bytecode of your Kernel.run() (and run-reachable) methods. We use the debug information to re-create the original variable name and to determine the local variable scope information.
+
+Of course only the derived Kernel class (or accessed Objects using new Arrays of Objects feature) need to be compiled using -g.
+
+##Why does the Aparapi documentation suggest I use Oracle's JDK/JRE? Why can't I use any JVM/JDK?
+
+The documentation suggests using Oracle's JDK/JRE for coverage reasons and not as a requirement. AMD focused its testing on Oracle's JVM/JDK.
+
+There are two parts to this.
+
+1. Our bytecode to OpenCL engine is somewhat tuned to the bytecode structures created by javac supplied by Oracle®. Specifically, there are some optimizations that other javac implementation might perform that Aparapi won't recognize. Eclipse (for example) does not presently use Oracle's javac, and so we do have some experience handling Eclipse specific bytecode patterns.
+2. At runtime, we piggyback on the (aptly named) sun.misc.Unsafe class, which is included in rt.jar from Oracle®. This class is useful because it helps us avoid some JNI calls by providing low level routines for accessing object field addresses (in real memory) and useful routines for Atomic operations. All accesses to 'sun.misc.Unsafe' are handled by an Aparapi class called UnsafeWrapper with the intent that this could be refactored to avoid this dependency.
+
+##I am using a dynamic language (Clojure, Scala, Groovy, Beanshell, etc) will I be able to use Aparapi?
+
+No.
+
+To access the bytecode for a method Aparapi needs to parse the original class file. For Java code, Aparapi can use something like `YourClass.getClassLoader().loadAsResource(YourClass.getName()+".class"))` to reload the class file bytes and parse the constant pool, attributes, fields, methods and method bytecode.
+
+It is unlikely that this process would work with a dynamically created class based on the presumption that dynamic languages employ some form of custom classloader to make dynamically generated bytecode available to the JVM. Therefore, it is unlikely that these classloaders would yield the classfile bytes. However, we encourage contributors to investigate opportunities here. Even if the class bytes were loadable, Aparapi would also expect debug information to be available (see previous FAQ entry). Again, this is not impossible for a dynamic language to do, indeed it would probably even be desirable as it would allow the code to be debugged using JDB compatible debugger.
+
+Finally, Aparapi recognizes bytecode patterns created by the javac supplied by Oracle® and it is possible that the code generated by a particular dynamic language may not be compatible with Aparapi current code analyzer.
+
+Therefore, at present this is unlikely to work. However, these would be excellent contributions to Aparapi. It would be great to see Aparapi being adopted by other JVM based dynamic language.
+
+##Why does Aparapi seems to be copying data unnecessarily back and forth between host and GPU. Can I stop Aparapi from doing this?
+
+Aparapi ensures that required data is moved to the GPU prior to kernel execution and returned to the appropriate array before Java execution resumes. Generally, this is what the Java user will expect. However, for some code patterns where multiple Kernel.execute() calls are made in succession (or more likely in a tight loop) Aparapi's approach may not be optimal.
+
+In the NewFeatures page we discuss a couple of Aparapi enhancements which will developers to elect intervene to reduce unnecessary copies.
+
+##Do I have to refactor my code to use arrays of primitives? Why can’t Aparapi just work with Java Objects?
+
+Aparapi creates OpenCL from the bytecode. Generally, OpenCL constrains us to using parallel primitive arrays (OpenCL does indeed allow structs, but Java and OpenCL do not have comparable memory layouts for these structures). Therefore, you will probably need to refactor your code to use primitive arrays. In this initial contribution, we have included some limited support for Arrays of simple Objects and hope contributors extend them. Check the NewFeatures page which shows how you can use this feature.
\ No newline at end of file
diff --git a/doc/LIbraryAgentDuality.md b/doc/LIbraryAgentDuality.md
new file mode 100644
index 0000000000000000000000000000000000000000..88e164e679d635bdd00aebc83d57ff88cb82637c
--- /dev/null
+++ b/doc/LIbraryAgentDuality.md
@@ -0,0 +1,28 @@
+#LIbraryAgentDuality
+*Aparapi libraries can now be loaded as JVMTI agents. Updated Jan 15, 2013 by frost.g...@gmail.com*
+
+##What are all these check-ins referring to JVMTI agents?
+
+If you have been tracking Aparapi SVN checkins you will have noticed a bunch of changes to JNI code. I just finished arranging for aparapi libraries (.dll or .so) to be able to be loaded as JVMTI agent. Now (assuming library is in ${APARAPI_DIR}) we can either launch using the traditional...
+
+    java –Djava.library.path=${APARAPI_DIR} –classpath ${APARAPI_DIR}/aparapi.jar;my.jar mypackage.MyClass
+
+or ...
+
+    java –agentpath=${APARAPI_DIR}/aparapi_x86_64.dll –classpath ${APARAPI_DIR}/aparapi.jar;my.jar mypackage.MyClass
+
+So the dll/so is now both ‘just a library’ and a JVMTI agent.
+
+##When would I need an agent?
+
+Prevously Aparapi loaded classes that it needed to convert to OpenCL using java.lang.Class.getResourceAsStream(). This only works if we have a jar, or if the classes are on the filesystem somewhere. This approach will not work for 'synthetically generated classes'.
+
+There are applications/frameworks which create synthetic classes (at runtime) which would not normally be useable by Aparapi.
+
+Specifically (and significantly) Java 8 uses synthetic classes to capture args (closure captures) so they can be passed to the final lambda implementation. We needed a way to allow Aparapi to access bytecode of any class, not just those in jars or on the disk.
+
+A JVMTI agent can register an interest in loaded classes (loaded by the classloader)do this. So when we use the aparapi library in 'agent mode' it caches all bytes for all loaded classes (yes we could filter by name) and puts this information in a common data structure (should be a map but is a linked list at present).
+
+By adding a new OpenCLJNI.getBytes(String) JNI method, Aparapi can now retrieve the bytes for any loaded classes, out of this cache.
+
+So this combined with our ability to parse classes which don’t have line number information should really enable Aparapi to be used with Scala/JRuby/Groovy or other dynamic scripting languages which create classes on the fly.
diff --git a/doc/README.md b/doc/README.md
index abf3be0651149a76b44dfb6e2e83721464f4adcb..980cb216cebce4a778b870a5b8658ee5f52e8666 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -14,10 +14,10 @@ APARAPI Documentation
 | [AddingLambdasToAparapi](AddingLambdasToAparapi.md) | Adding Java 8 Lambda Support to Aparapi |
 | [ProfilingKernelExecution](ProfilingKernelExecution.md) | Using Aparapi's built in profiling APIs |
 | [HowToAddUML](HowToAddUML.md) | How to add plantuml docs to wiki pages |
-| LIbraryAgentDuality | Aparapi libraries can now be loaded as JVMTI agents. |
-| FrequentlyAskedQuestions | Frequently Asked Questions|
+| [LIbraryAgentDuality](LIbraryAgentDuality.md) | Aparapi libraries can now be loaded as JVMTI agents. |
+| [FrequentlyAskedQuestions](FrequentlyAskedQuestions.md) | Frequently Asked Questions|
 | HomePageSuggestions ||
-| ChoosingSpecificDevicesForExecution | Using the new Device API's to choose Kernel execution on a specific device.	|
+| [ChoosingSpecificDevicesForExecution](ChoosingSpecificDevicesForExecution.md) | Using the new Device API's to choose Kernel execution on a specific device.	|
 | Gadgets | Gadgetorium|
 | ConvertingBytecodeToOpenCL | How Aparapi converts bytecode to OpenCL |
 | DevelopersGuideLinux | Developer guide for Linux. |
@@ -37,7 +37,7 @@ APARAPI Documentation
 | LocalMemoryAndBarrierProposal | A proposal for handling local memory and barriers |
 | AddressSpacesUsingBuffers | Proposal For OpenCL address space support using java Buffers instead of arrays.	|
 | BuildingNBody | How to build the NBody example.|
-| UnitTestGuide | Unit test Guide Find out how to run Junit tests and how to add new tests. |
+| [UnitTestGuide](UnitTestGuide.md) | Unit test Guide Find out how to run Junit tests and how to add new tests. |
 | NewFeatures | New Features added to this open source release of Aparapi. |
 | UsersGuide | Aparapi User's Guide. |
 | DevelopersGuide | Aparapi developers guide. |
diff --git a/doc/UnitTestGuide.md b/doc/UnitTestGuide.md
new file mode 100644
index 0000000000000000000000000000000000000000..6d829d68046408113158f5a642eab0531c0019f6
--- /dev/null
+++ b/doc/UnitTestGuide.md
@@ -0,0 +1,174 @@
+#UnitTestGuide
+*Unit test Guide Find out how to run Junit tests and how to add new tests. Updated Sep 14, 2011 by frost.g...@gmail.com*
+
+#Unit Test Guide
+
+The Unit Test Guide explains the test infrastructure associated with Aparapi, including instructions for executing existing tests adding new test cases.
+OpenCLâ„¢ code generation tests
+
+The initial open source tree includes the codegen subdirectory (test/codegen), which used to validate the Aparapi bytecode to OpenCLâ„¢ conversion.
+
+    aparapi/trunk/
+       com.amd.aparapi/
+          src/java/com.amd.aparapi/
+          build.xml
+       test/
+          codegen/
+             src/java/
+                com.amd.aparapi/
+                com.amd.aparapi.test/
+             build.xml
+       build.xml
+
+The code generation tests to not require OpenCLâ„¢ , AMD APP SDK or a GPU devices to be configured; these tests only validate the creation of valid OpenCLâ„¢ code by comparing against predefined expected output.
+
+##Running the OpenCLâ„¢ code generation JUnit tests
+
+Before executing the code generation tests, build the com.amd.aparapi sub-project and ensure that you have JUnit 4 installed.
+
+Edit the junit.jar property in test/codegen/build.xml to point to your install directory.
+
+    <property name="junit.jar" value="C:\JUnit4.9\junit-4.9.jar"/>
+
+Initiate the code generation tests using ant.
+
+    C:\> cd tests/codegen
+    C:\> ant
+    <failures will be reported here>
+    C:>
+
+View the HTML version of the JUnit report at junit/html/index.html. On Microsoft Windows(r) platforms use
+
+    C:\> start junit\html\index.html
+
+On Linux(r) platforms just invoke your browser (Firefox in this case).
+
+    C:\> firefox junit\html\index.html
+
+##Adding a new OpenCLâ„¢ code generation test
+
+The test cases for OpenCLâ„¢ code generation are not strictly JUnit tests. Instead the codegen Java tree contains a tool (CreateJUnitTests) to create JUnit test cases from specially formatted test source files.
+
+The package `com.amd.aparapi.test (codegen/src/java/com/amd/aparapi/test)` contains all of the existing code generation tests.
+
+Here is an example that tests the code generation resulting from a call to Kernel.getPassId(), this is taken from com.amd.aparapi.test.CallGetPassId
+
+    package com.amd.aparapi.test;
+
+    import com.amd.aparapi.Kernel;
+
+    public class CallGetPassId extends Kernel{
+       public void run() {
+          int thePassId = getPassId();
+       }
+
+    }
+    /**{OpenCL{
+
+    typedef struct This_s{
+       int passid;
+    }This;
+    int get_pass_id(This *this){
+       return this->passid;
+    }
+    __kernel void run(
+       int passid
+    ){
+       This thisStruct;
+       This* this=&thisStruct;
+       this->passid = passid;
+       {
+          int thePassId = get_pass_id(this);
+          return;
+       }
+    }
+
+    }OpenCL}**/
+
+The test source takes the form of a simple class that extends the kernel and a block of OpenCL code between the /**{OpenCL{ and }OpenCL}**/ markers. The code between these markers is the OpenCL code that we expect Aparapi to produce as a result of converting the run() method to OpenCL.
+
+The code-generating ant build.xml file performs the following steps to generate its report:
+
+* compiles the src/java tree. This compiles all the test cases as well as a few ‘utility’ classes.
+* executes the com.amd.aparapi.test.CreateJUnitTests program. This iterates through all of the test source files and converts them to JUnit form. The generated source is written to the src/genjava tree.
+* compiles the src/genjava tree to create the required JUnit classes
+* initiates the JUnit test phase (result data in junit/data)
+* creates the JUnit report (in junit/html/junit from junit/data)
+
+To create a new test case, just add your test case to the codegen/src/java/com/amd/aparapi/test package (including the expected OpenCL).
+
+Sometimes different javac implementations (such as Oracle and Eclipse) will generate different bytecode for the same source. When Aparapi converts this bytecode it may yield different (but equally acceptable) OpenCL forms. One example of this is the BooleanToggle test:
+
+    public class BooleanToggle{
+       public void run() {
+          boolean pass = false;
+
+          pass = !pass;
+
+       }
+    }
+
+The BooleanToggle test code creates two (slightly different) versions of OpenCLâ„¢ (sadly one line different) depending on the javac compiler.
+
+This example shows the ‘toggle’ OpenCL™ created from the bytecode generated by Oracle.
+
+    pass = pass==1?0:1;
+
+This example shows the bytecode from Eclipse javac:
+
+    pass = pass==0?1:0;
+
+Logically either of the above are correct. However, to accommodate the alternate acceptable forms we need to add two complete `/**{OpenCL{ and }OpenCL}**/` sections to the file. If either matches, the test will pass.
+
+Here is the complete BooleanToggle code.
+
+    package com.amd.aparapi.test;
+
+    public class BooleanToggle{
+       public void run() {
+          boolean pass = false;
+
+          pass = !pass;
+
+       }
+    }
+    /**{OpenCL{
+    typedef struct This_s{
+       int passid;
+    }This;
+    int get_pass_id(This *this){
+       return this->passid;
+    }
+    __kernel void run(
+       int passid
+    ){
+       This thisStruct;
+       This* this=&thisStruct;
+       this->passid = passid;
+       {
+          char pass = 0;
+          pass = (pass==0)?1:0;
+          return;
+       }
+    }
+    }OpenCL}**/
+    /**{OpenCL{
+    typedef struct This_s{
+       int passid;
+    }This;
+    int get_pass_id(This *this){
+       return this->passid;
+    }
+    __kernel void run(
+       int passid
+    ){
+       This thisStruct;
+       This* this=&thisStruct;
+       this->passid = passid;
+       {
+          char pass = 0;
+          pass = (pass!=0)?0:1;
+          return;
+       }
+    }
+    }OpenCL}**/
\ No newline at end of file