Merge "Add New support to binary.Class" into studio-1.3-dev
diff --git a/api/apic/template/types.go b/api/apic/template/types.go
index de5d59b..0b2b775 100644
--- a/api/apic/template/types.go
+++ b/api/apic/template/types.go
@@ -83,6 +83,7 @@
 		semantic.Reference{},
 		semantic.Return{},
 		semantic.Select{},
+		semantic.SliceAssign{},
 		semantic.SliceIndex{},
 		semantic.SliceRange{},
 		semantic.Slice{},
diff --git a/api/resolver/statement.go b/api/resolver/statement.go
index 56e50ae..bb6692d 100644
--- a/api/resolver/statement.go
+++ b/api/resolver/statement.go
@@ -112,6 +112,8 @@
 	switch lhs := lhs.(type) {
 	case *semantic.MapIndex:
 		out = &semantic.MapAssign{AST: in, To: lhs, Value: rhs, Operator: in.Operator}
+	case *semantic.SliceIndex:
+		out = &semantic.SliceAssign{AST: in, To: lhs, Value: rhs, Operator: in.Operator}
 	default:
 		out = &semantic.Assign{AST: in, LHS: lhs, Operator: in.Operator, RHS: rhs}
 	}
diff --git a/api/semantic/statement.go b/api/semantic/statement.go
index da6d5ef..a127aec 100644
--- a/api/semantic/statement.go
+++ b/api/semantic/statement.go
@@ -73,6 +73,14 @@
 	Value    Expression  // the value to set in the map
 }
 
+// SliceAssign represents assigning to a slice index expression.
+type SliceAssign struct {
+	AST      *ast.Assign // the underlying syntax node this was built from
+	To       *SliceIndex // the slice index to assign to
+	Operator string      // the assignment operator being applied
+	Value    Expression  // the value to set in the slice
+}
+
 // DeclareLocal represents a local variable declaration statement.
 // Variables cannot be modified after declaration.
 type DeclareLocal struct {
diff --git a/cc/gapii/gles_spy.h b/cc/gapii/gles_spy.h
index 6bf81b2..e3669ed 100644
--- a/cc/gapii/gles_spy.h
+++ b/cc/gapii/gles_spy.h
@@ -20,24 +20,19 @@
 #define GAPII_GLES_SPY_H
 
 #include "gles_imports.h"
-#include "gles_state.h"
 #include "gles_types.h"
 
-#include <gapic/encoder.h>
+#include "spy_base.h"
+
 #include <gapic/log.h>
 
 #include <memory>
 #include <string>
-#include <unordered_set>
-
-#include <stdint.h>
 
 namespace gapii {
 
-class GlesSpy {
+class GlesSpy : public SpyBase {
 public:
-    inline GlesSpy();
-
     inline void init(std::shared_ptr<gapic::Encoder> encoder);
 
     inline void replayCreateRenderer(uint32_t id);
@@ -298,58 +293,44 @@
 
 protected:
     GlesImports mImports;
-    GlesState mState;
 
-private:
-    enum order {
-        PRE_OBSERVE,
-        POST_OBSERVE,
-    };
+    // Globals
+    ContextID NextContextID;
+    ThreadID CurrentThread;
+    ThreadIDToContextRef Contexts;
+    EGLContextToContextRef EGLContexts;
+    GLXContextToContextRef GLXContexts;
+    HGLRCToContextRef WGLContexts;
+    CGLContextObjToContextRef CGLContexts;
 
-    inline void observe(const void* base, uint64_t offset, uint64_t size);
-
-    std::unordered_set<gapic::Id> mObserved;
-    std::shared_ptr<gapic::Encoder> mEncoder;
+#include "gles_state_externs.inl"
 };
 
-inline GlesSpy::GlesSpy()
-    : mState(std::bind(&GlesSpy::observe, this, std::placeholders::_1, std::placeholders::_2,
-                       std::placeholders::_3)) {}
-
 // Inline methods
 inline void GlesSpy::init(std::shared_ptr<gapic::Encoder> encoder) {
-    mEncoder = encoder;
+    SpyBase::init(encoder);
     mImports.Resolve();
 }
 
-inline void GlesSpy::observe(const void* base, uint64_t offset, uint64_t size) {
-    const void* ptr = reinterpret_cast<const uint8_t*>(base) + offset;
-    gapic::Id id = gapic::Id::Hash(ptr, size);
-    if (mObserved.count(id) == 0) {
-        mEncoder->Uint16(0xfffd);  // Type ID -- TODO: mEncoder->Id(RESOURCE_ID);
-        mEncoder->Id(id);
-        mEncoder->Data(ptr, static_cast<int32_t>(size));
-        mObserved.emplace(id);
-    }
-    mEncoder->Uint16(0xfffe);  // Type ID -- TODO: mEncoder->Id(OBSERVATION_ID);
-    mEncoder->Uint64(reinterpret_cast<uint64_t>(ptr));
-    mEncoder->Uint64(size);
-    mEncoder->Id(id);
-}
-
 inline void GlesSpy::replayCreateRenderer(uint32_t id) {
     GAPID_INFO("replayCreateRenderer()\n");
-    mState.replayCreateRenderer(id);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(0);  // Type ID -- TODO: mEncoder->Id(REPLAY_CREATE_RENDERER_ID);
+    encodeObservations();
     mEncoder->Uint32(id);
 }
 
 inline void GlesSpy::replayBindRenderer(uint32_t id) {
     GAPID_INFO("replayBindRenderer()\n");
-    mState.replayBindRenderer(id);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(1);  // Type ID -- TODO: mEncoder->Id(REPLAY_BIND_RENDERER_ID);
+    encodeObservations();
     mEncoder->Uint32(id);
 }
 
@@ -357,9 +338,42 @@
                                     uint32_t depth_fmt, uint32_t stencil_fmt,
                                     bool resetViewportScissor) {
     GAPID_INFO("backbufferInfo()\n");
-    mState.backbufferInfo(width, height, color_fmt, depth_fmt, stencil_fmt, resetViewportScissor);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_0_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_0_result;
+        std::shared_ptr<Framebuffer> l_backbuffer =
+                l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)];
+        RenderbufferId l_color_id = (RenderbufferId)(
+                l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0].mObject);
+        std::shared_ptr<Renderbuffer> l_color_buffer = l_ctx->mInstances.mRenderbuffers[l_color_id];
+        RenderbufferId l_depth_id = (RenderbufferId)(
+                l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT].mObject);
+        std::shared_ptr<Renderbuffer> l_depth_buffer = l_ctx->mInstances.mRenderbuffers[l_depth_id];
+        RenderbufferId l_stencil_id = (RenderbufferId)(
+                l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT].mObject);
+        std::shared_ptr<Renderbuffer> l_stencil_buffer =
+                l_ctx->mInstances.mRenderbuffers[l_stencil_id];
+        l_color_buffer->mWidth = width;
+        l_color_buffer->mHeight = height;
+        l_color_buffer->mFormat = color_fmt;
+        l_depth_buffer->mWidth = width;
+        l_depth_buffer->mHeight = height;
+        l_depth_buffer->mFormat = depth_fmt;
+        l_stencil_buffer->mWidth = width;
+        l_stencil_buffer->mHeight = height;
+        l_stencil_buffer->mFormat = stencil_fmt;
+        if (resetViewportScissor) {
+            l_ctx->mRasterizing.mScissor.mWidth = width;
+            l_ctx->mRasterizing.mScissor.mHeight = height;
+            l_ctx->mRasterizing.mViewport.mWidth = width;
+            l_ctx->mRasterizing.mViewport.mHeight = height;
+        }
+    } while (false);
 
     mEncoder->Uint16(2);  // Type ID -- TODO: mEncoder->Id(BACKBUFFER_INFO_ID);
+    encodeObservations();
     mEncoder->Int32(width);
     mEncoder->Int32(height);
     mEncoder->Uint32(static_cast<uint32_t>(color_fmt));
@@ -370,18 +384,25 @@
 
 inline void GlesSpy::startTimer(uint8_t index) {
     GAPID_INFO("startTimer()\n");
-    mState.startTimer(index);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(3);  // Type ID -- TODO: mEncoder->Id(START_TIMER_ID);
+    encodeObservations();
     mEncoder->Uint8(index);
 }
 
 inline uint64_t GlesSpy::stopTimer(uint8_t index) {
     GAPID_INFO("stopTimer()\n");
     uint64_t result = 0;
-    mState.stopTimer(index, result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(4);  // Type ID -- TODO: mEncoder->Id(STOP_TIMER_ID);
+    encodeObservations();
     mEncoder->Uint8(index);
     mEncoder->Uint64(result);
 
@@ -390,20 +411,32 @@
 
 inline void GlesSpy::flushPostBuffer() {
     GAPID_INFO("flushPostBuffer()\n");
-    mState.flushPostBuffer();
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(5);  // Type ID -- TODO: mEncoder->Id(FLUSH_POST_BUFFER_ID);
+    encodeObservations();
 }
 
 inline int GlesSpy::eglInitialize(void* dpy, int* major, int* minor) {
     GAPID_INFO("eglInitialize()\n");
     int result = mImports.eglInitialize(dpy, major, minor);
-    mState.eglInitialize(dpy, major, minor, result);
+
+    do {
+        write(slice(major, 0, 1), 0, read(slice(major, 0, 1), 0));
+        write(slice(minor, 0, 1), 0, read(slice(minor, 0, 1), 0));
+        break;
+    } while (false);
 
     mEncoder->Uint16(6);  // Type ID -- TODO: mEncoder->Id(EGL_INITIALIZE_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(dpy));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(major));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(minor));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(result);
 
     return result;
@@ -413,14 +446,71 @@
                                        int* attrib_list) {
     GAPID_INFO("eglCreateContext()\n");
     void* result = mImports.eglCreateContext(display, config, share_context, attrib_list);
-    mState.eglCreateContext(display, config, share_context, attrib_list, result);
+
+    do {
+        EGLContext l_context = (EGLContext)(result);
+        ContextID l_identifier = this->NextContextID;
+        this->NextContextID = this->NextContextID + (ContextID)(1);
+        std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
+        l_ctx->mIdentifier = l_identifier;
+        l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
+        l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
+        l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        RenderbufferId l_color_id = (RenderbufferId)(4294967295);
+        RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
+        RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
+        l_ctx->mInstances.mRenderbuffers[l_color_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_depth_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        std::shared_ptr<Framebuffer> l_backbuffer =
+                std::shared_ptr<Framebuffer>((new Framebuffer()));
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_color_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_depth_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_stencil_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
+        for (int32_t l_i = 0; l_i < 64; ++l_i) {
+            l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
+                    std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
+        }
+        std::shared_ptr<Context> l_CreateContext_1_result = l_ctx;
+        this->EGLContexts[l_context] = l_CreateContext_1_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(7);  // Type ID -- TODO: mEncoder->Id(EGL_CREATE_CONTEXT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(display));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(config));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(share_context));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(attrib_list));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(result));
+    mEncoder->Uint32(0);  // PoolID
 
     return result;
 }
@@ -428,13 +518,23 @@
 inline int GlesSpy::eglMakeCurrent(void* display, void* draw, void* read, void* context) {
     GAPID_INFO("eglMakeCurrent()\n");
     int result = mImports.eglMakeCurrent(display, draw, read, context);
-    mState.eglMakeCurrent(display, draw, read, context, result);
+
+    do {
+        std::shared_ptr<Context> l_SetContext_2_context = this->EGLContexts[context];
+        this->Contexts[this->CurrentThread] = l_SetContext_2_context;
+        break;
+    } while (false);
 
     mEncoder->Uint16(8);  // Type ID -- TODO: mEncoder->Id(EGL_MAKE_CURRENT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(display));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(draw));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(read));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(context));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(result);
 
     return result;
@@ -443,11 +543,17 @@
 inline int GlesSpy::eglSwapBuffers(void* display, void* surface) {
     GAPID_INFO("eglSwapBuffers()\n");
     int result = mImports.eglSwapBuffers(display, surface);
-    mState.eglSwapBuffers(display, surface, result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(9);  // Type ID -- TODO: mEncoder->Id(EGL_SWAP_BUFFERS_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(display));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(surface));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(result);
 
     return result;
@@ -456,13 +562,21 @@
 inline int GlesSpy::eglQuerySurface(void* display, void* surface, int attribute, int* value) {
     GAPID_INFO("eglQuerySurface()\n");
     int result = mImports.eglQuerySurface(display, surface, attribute, value);
-    mState.eglQuerySurface(display, surface, attribute, value, result);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+        break;
+    } while (false);
 
     mEncoder->Uint16(10);  // Type ID -- TODO: mEncoder->Id(EGL_QUERY_SURFACE_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(display));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(surface));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(attribute);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(result);
 
     return result;
@@ -471,14 +585,70 @@
 inline void* GlesSpy::glXCreateContext(void* dpy, void* vis, void* shareList, bool direct) {
     GAPID_INFO("glXCreateContext()\n");
     void* result = mImports.glXCreateContext(dpy, vis, shareList, direct);
-    mState.glXCreateContext(dpy, vis, shareList, direct, result);
+
+    do {
+        GLXContext l_context = (GLXContext)(result);
+        ContextID l_identifier = this->NextContextID;
+        this->NextContextID = this->NextContextID + (ContextID)(1);
+        std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
+        l_ctx->mIdentifier = l_identifier;
+        l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
+        l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
+        l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        RenderbufferId l_color_id = (RenderbufferId)(4294967295);
+        RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
+        RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
+        l_ctx->mInstances.mRenderbuffers[l_color_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_depth_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        std::shared_ptr<Framebuffer> l_backbuffer =
+                std::shared_ptr<Framebuffer>((new Framebuffer()));
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_color_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_depth_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_stencil_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
+        for (int32_t l_i = 0; l_i < 64; ++l_i) {
+            l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
+                    std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
+        }
+        std::shared_ptr<Context> l_CreateContext_3_result = l_ctx;
+        this->GLXContexts[l_context] = l_CreateContext_3_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(11);  // Type ID -- TODO: mEncoder->Id(GL_X_CREATE_CONTEXT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(dpy));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(vis));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(shareList));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Bool(direct);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(result));
+    mEncoder->Uint32(0);  // PoolID
 
     return result;
 }
@@ -487,15 +657,71 @@
                                           void* shared, bool direct) {
     GAPID_INFO("glXCreateNewContext()\n");
     void* result = mImports.glXCreateNewContext(display, fbconfig, type, shared, direct);
-    mState.glXCreateNewContext(display, fbconfig, type, shared, direct, result);
+
+    do {
+        GLXContext l_context = (GLXContext)(result);
+        ContextID l_identifier = this->NextContextID;
+        this->NextContextID = this->NextContextID + (ContextID)(1);
+        std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
+        l_ctx->mIdentifier = l_identifier;
+        l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
+        l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
+        l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        RenderbufferId l_color_id = (RenderbufferId)(4294967295);
+        RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
+        RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
+        l_ctx->mInstances.mRenderbuffers[l_color_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_depth_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        std::shared_ptr<Framebuffer> l_backbuffer =
+                std::shared_ptr<Framebuffer>((new Framebuffer()));
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_color_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_depth_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_stencil_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
+        for (int32_t l_i = 0; l_i < 64; ++l_i) {
+            l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
+                    std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
+        }
+        std::shared_ptr<Context> l_CreateContext_4_result = l_ctx;
+        this->GLXContexts[l_context] = l_CreateContext_4_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(12);  // Type ID -- TODO: mEncoder->Id(GL_X_CREATE_NEW_CONTEXT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(display));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(fbconfig));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint32(type);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(shared));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Bool(direct);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(result));
+    mEncoder->Uint32(0);  // PoolID
 
     return result;
 }
@@ -503,33 +729,101 @@
 inline void GlesSpy::glXMakeContextCurrent(void* display, void* draw, void* read, void* ctx) {
     GAPID_INFO("glXMakeContextCurrent()\n");
     mImports.glXMakeContextCurrent(display, draw, read, ctx);
-    mState.glXMakeContextCurrent(display, draw, read, ctx);
+
+    do {
+        std::shared_ptr<Context> l_SetContext_5_context = this->GLXContexts[ctx];
+        this->Contexts[this->CurrentThread] = l_SetContext_5_context;
+    } while (false);
 
     mEncoder->Uint16(13);  // Type ID -- TODO: mEncoder->Id(GL_X_MAKE_CONTEXT_CURRENT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(display));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(draw));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(read));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(ctx));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glXSwapBuffers(void* display, void* drawable) {
     GAPID_INFO("glXSwapBuffers()\n");
     mImports.glXSwapBuffers(display, drawable);
-    mState.glXSwapBuffers(display, drawable);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(14);  // Type ID -- TODO: mEncoder->Id(GL_X_SWAP_BUFFERS_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(display));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(drawable));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void* GlesSpy::wglCreateContext(void* hdc) {
     GAPID_INFO("wglCreateContext()\n");
     void* result = mImports.wglCreateContext(hdc);
-    mState.wglCreateContext(hdc, result);
+
+    do {
+        HGLRC l_context = (HGLRC)(result);
+        ContextID l_identifier = this->NextContextID;
+        this->NextContextID = this->NextContextID + (ContextID)(1);
+        std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
+        l_ctx->mIdentifier = l_identifier;
+        l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
+        l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
+        l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        RenderbufferId l_color_id = (RenderbufferId)(4294967295);
+        RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
+        RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
+        l_ctx->mInstances.mRenderbuffers[l_color_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_depth_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        std::shared_ptr<Framebuffer> l_backbuffer =
+                std::shared_ptr<Framebuffer>((new Framebuffer()));
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_color_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_depth_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_stencil_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
+        for (int32_t l_i = 0; l_i < 64; ++l_i) {
+            l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
+                    std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
+        }
+        std::shared_ptr<Context> l_CreateContext_6_result = l_ctx;
+        this->WGLContexts[l_context] = l_CreateContext_6_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(15);  // Type ID -- TODO: mEncoder->Id(WGL_CREATE_CONTEXT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(hdc));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(result));
+    mEncoder->Uint32(0);  // PoolID
 
     return result;
 }
@@ -537,13 +831,69 @@
 inline void* GlesSpy::wglCreateContextAttribsARB(void* hdc, void* hShareContext, int* attribList) {
     GAPID_INFO("wglCreateContextAttribsARB()\n");
     void* result = mImports.wglCreateContextAttribsARB(hdc, hShareContext, attribList);
-    mState.wglCreateContextAttribsARB(hdc, hShareContext, attribList, result);
+
+    do {
+        HGLRC l_context = (HGLRC)(result);
+        ContextID l_identifier = this->NextContextID;
+        this->NextContextID = this->NextContextID + (ContextID)(1);
+        std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
+        l_ctx->mIdentifier = l_identifier;
+        l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
+        l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
+        l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        RenderbufferId l_color_id = (RenderbufferId)(4294967295);
+        RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
+        RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
+        l_ctx->mInstances.mRenderbuffers[l_color_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_depth_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        std::shared_ptr<Framebuffer> l_backbuffer =
+                std::shared_ptr<Framebuffer>((new Framebuffer()));
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_color_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_depth_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_stencil_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
+        for (int32_t l_i = 0; l_i < 64; ++l_i) {
+            l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
+                    std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
+        }
+        std::shared_ptr<Context> l_CreateContext_7_result = l_ctx;
+        this->WGLContexts[l_context] = l_CreateContext_7_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(16);  // Type ID -- TODO: mEncoder->Id(WGL_CREATE_CONTEXT_ATTRIBS_A_R_B_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(hdc));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(hShareContext));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(attribList));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(result));
+    mEncoder->Uint32(0);  // PoolID
 
     return result;
 }
@@ -551,11 +901,19 @@
 inline int GlesSpy::wglMakeCurrent(void* hdc, void* hglrc) {
     GAPID_INFO("wglMakeCurrent()\n");
     int result = mImports.wglMakeCurrent(hdc, hglrc);
-    mState.wglMakeCurrent(hdc, hglrc, result);
+
+    do {
+        std::shared_ptr<Context> l_SetContext_8_context = this->WGLContexts[hglrc];
+        this->Contexts[this->CurrentThread] = l_SetContext_8_context;
+        break;
+    } while (false);
 
     mEncoder->Uint16(17);  // Type ID -- TODO: mEncoder->Id(WGL_MAKE_CURRENT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(hdc));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(hglrc));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(result);
 
     return result;
@@ -564,21 +922,81 @@
 inline void GlesSpy::wglSwapBuffers(void* hdc) {
     GAPID_INFO("wglSwapBuffers()\n");
     mImports.wglSwapBuffers(hdc);
-    mState.wglSwapBuffers(hdc);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(18);  // Type ID -- TODO: mEncoder->Id(WGL_SWAP_BUFFERS_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(hdc));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline int GlesSpy::CGLCreateContext(void* pix, void* share, void** ctx) {
     GAPID_INFO("CGLCreateContext()\n");
     int result = mImports.CGLCreateContext(pix, share, ctx);
-    mState.CGLCreateContext(pix, share, ctx, result);
+
+    do {
+        CGLContextObj l_context = (CGLContextObj)(read(slice(ctx, 0, 1), 0));
+        ContextID l_identifier = this->NextContextID;
+        this->NextContextID = this->NextContextID + (ContextID)(1);
+        std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
+        l_ctx->mIdentifier = l_identifier;
+        l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
+        l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
+        l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        RenderbufferId l_color_id = (RenderbufferId)(4294967295);
+        RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
+        RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
+        l_ctx->mInstances.mRenderbuffers[l_color_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_depth_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
+                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        std::shared_ptr<Framebuffer> l_backbuffer =
+                std::shared_ptr<Framebuffer>((new Framebuffer()));
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_color_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_depth_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
+                FramebufferAttachmentInfo()
+                        .SetObject((uint32_t)(l_stencil_id))
+                        .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
+                        .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+        l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
+        l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
+        for (int32_t l_i = 0; l_i < 64; ++l_i) {
+            l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
+                    std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
+        }
+        std::shared_ptr<Context> l_CreateContext_9_result = l_ctx;
+        this->CGLContexts[l_context] = l_CreateContext_9_result;
+        write(slice(ctx, 0, 1), 0, l_context);
+        break;
+    } while (false);
 
     mEncoder->Uint16(19);  // Type ID -- TODO: mEncoder->Id(C_G_L_CREATE_CONTEXT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(pix));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(share));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(ctx));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(result);
 
     return result;
@@ -587,10 +1005,17 @@
 inline int GlesSpy::CGLSetCurrentContext(void* ctx) {
     GAPID_INFO("CGLSetCurrentContext()\n");
     int result = mImports.CGLSetCurrentContext(ctx);
-    mState.CGLSetCurrentContext(ctx, result);
+
+    do {
+        std::shared_ptr<Context> l_SetContext_10_context = this->CGLContexts[ctx];
+        this->Contexts[this->CurrentThread] = l_SetContext_10_context;
+        break;
+    } while (false);
 
     mEncoder->Uint16(20);  // Type ID -- TODO: mEncoder->Id(C_G_L_SET_CURRENT_CONTEXT_ID);
+    encodeObservations();
     mEncoder->Uint64(reinterpret_cast<uint64_t>(ctx));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int64(result);
 
     return result;
@@ -599,18 +1024,32 @@
 inline void GlesSpy::glEnableClientState(uint32_t type) {
     GAPID_INFO("glEnableClientState()\n");
     mImports.glEnableClientState(type);
-    mState.glEnableClientState(type);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_11_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_11_result;
+        l_ctx->mCapabilities[(uint32_t)(type)] = true;
+    } while (false);
 
     mEncoder->Uint16(21);  // Type ID -- TODO: mEncoder->Id(GL_ENABLE_CLIENT_STATE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(type));
 }
 
 inline void GlesSpy::glDisableClientState(uint32_t type) {
     GAPID_INFO("glDisableClientState()\n");
     mImports.glDisableClientState(type);
-    mState.glDisableClientState(type);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_12_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_12_result;
+        l_ctx->mCapabilities[(uint32_t)(type)] = false;
+    } while (false);
 
     mEncoder->Uint16(22);  // Type ID -- TODO: mEncoder->Id(GL_DISABLE_CLIENT_STATE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(type));
 }
 
@@ -619,26 +1058,40 @@
                                            void* binary) {
     GAPID_INFO("glGetProgramBinaryOES()\n");
     mImports.glGetProgramBinaryOES(program, buffer_size, bytes_written, binary_format, binary);
-    mState.glGetProgramBinaryOES(program, buffer_size, bytes_written, binary_format, binary);
+
+    do {
+        int32_t l_l = (int32_t)(read(slice(bytes_written, 0, 1), 0));
+        write(slice(bytes_written, 0, 1), 0, l_l);
+        write(slice(binary_format, 0, 1), 0, read(slice(binary_format, 0, 1), 0));
+        write(slice(binary, (uint64_t)(0), (uint64_t)(l_l)));
+    } while (false);
 
     mEncoder->Uint16(23);  // Type ID -- TODO: mEncoder->Id(GL_GET_PROGRAM_BINARY_O_E_S_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Int32(buffer_size);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(bytes_written));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(binary_format));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(binary));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glProgramBinaryOES(uint32_t program, uint32_t binary_format, void* binary,
                                         int32_t binary_size) {
     GAPID_INFO("glProgramBinaryOES()\n");
     mImports.glProgramBinaryOES(program, binary_format, binary, binary_size);
-    mState.glProgramBinaryOES(program, binary_format, binary, binary_size);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(24);  // Type ID -- TODO: mEncoder->Id(GL_PROGRAM_BINARY_O_E_S_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Uint32(binary_format);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(binary));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int32(binary_size);
 }
 
@@ -646,9 +1099,12 @@
                                        uint32_t preserveMask) {
     GAPID_INFO("glStartTilingQCOM()\n");
     mImports.glStartTilingQCOM(x, y, width, height, preserveMask);
-    mState.glStartTilingQCOM(x, y, width, height, preserveMask);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(25);  // Type ID -- TODO: mEncoder->Id(GL_START_TILING_Q_C_O_M_ID);
+    encodeObservations();
     mEncoder->Int32(x);
     mEncoder->Int32(y);
     mEncoder->Int32(width);
@@ -659,9 +1115,12 @@
 inline void GlesSpy::glEndTilingQCOM(uint32_t preserve_mask) {
     GAPID_INFO("glEndTilingQCOM()\n");
     mImports.glEndTilingQCOM(preserve_mask);
-    mState.glEndTilingQCOM(preserve_mask);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(26);  // Type ID -- TODO: mEncoder->Id(GL_END_TILING_Q_C_O_M_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(preserve_mask));
 }
 
@@ -669,20 +1128,27 @@
                                              uint32_t* attachments) {
     GAPID_INFO("glDiscardFramebufferEXT()\n");
     mImports.glDiscardFramebufferEXT(target, numAttachments, attachments);
-    mState.glDiscardFramebufferEXT(target, numAttachments, attachments);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(27);  // Type ID -- TODO: mEncoder->Id(GL_DISCARD_FRAMEBUFFER_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(numAttachments);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(attachments));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glInsertEventMarkerEXT(int32_t length, char* marker) {
     GAPID_INFO("glInsertEventMarkerEXT()\n");
     mImports.glInsertEventMarkerEXT(length, marker);
-    mState.glInsertEventMarkerEXT(length, marker);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(28);  // Type ID -- TODO: mEncoder->Id(GL_INSERT_EVENT_MARKER_E_X_T_ID);
+    encodeObservations();
     mEncoder->Int32(length);
     mEncoder->String(marker);
 }
@@ -690,9 +1156,12 @@
 inline void GlesSpy::glPushGroupMarkerEXT(int32_t length, char* marker) {
     GAPID_INFO("glPushGroupMarkerEXT()\n");
     mImports.glPushGroupMarkerEXT(length, marker);
-    mState.glPushGroupMarkerEXT(length, marker);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(29);  // Type ID -- TODO: mEncoder->Id(GL_PUSH_GROUP_MARKER_E_X_T_ID);
+    encodeObservations();
     mEncoder->Int32(length);
     mEncoder->String(marker);
 }
@@ -700,18 +1169,24 @@
 inline void GlesSpy::glPopGroupMarkerEXT() {
     GAPID_INFO("glPopGroupMarkerEXT()\n");
     mImports.glPopGroupMarkerEXT();
-    mState.glPopGroupMarkerEXT();
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(30);  // Type ID -- TODO: mEncoder->Id(GL_POP_GROUP_MARKER_E_X_T_ID);
+    encodeObservations();
 }
 
 inline void GlesSpy::glTexStorage1DEXT(uint32_t target, int32_t levels, uint32_t format,
                                        int32_t width) {
     GAPID_INFO("glTexStorage1DEXT()\n");
     mImports.glTexStorage1DEXT(target, levels, format, width);
-    mState.glTexStorage1DEXT(target, levels, format, width);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(31);  // Type ID -- TODO: mEncoder->Id(GL_TEX_STORAGE1D_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(levels);
     mEncoder->Uint32(static_cast<uint32_t>(format));
@@ -722,9 +1197,12 @@
                                        int32_t width, int32_t height) {
     GAPID_INFO("glTexStorage2DEXT()\n");
     mImports.glTexStorage2DEXT(target, levels, format, width, height);
-    mState.glTexStorage2DEXT(target, levels, format, width, height);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(32);  // Type ID -- TODO: mEncoder->Id(GL_TEX_STORAGE2D_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(levels);
     mEncoder->Uint32(static_cast<uint32_t>(format));
@@ -736,9 +1214,12 @@
                                        int32_t width, int32_t height, int32_t depth) {
     GAPID_INFO("glTexStorage3DEXT()\n");
     mImports.glTexStorage3DEXT(target, levels, format, width, height, depth);
-    mState.glTexStorage3DEXT(target, levels, format, width, height, depth);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(33);  // Type ID -- TODO: mEncoder->Id(GL_TEX_STORAGE3D_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(levels);
     mEncoder->Uint32(static_cast<uint32_t>(format));
@@ -751,9 +1232,12 @@
                                            uint32_t format, int32_t width) {
     GAPID_INFO("glTextureStorage1DEXT()\n");
     mImports.glTextureStorage1DEXT(texture, target, levels, format, width);
-    mState.glTextureStorage1DEXT(texture, target, levels, format, width);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(34);  // Type ID -- TODO: mEncoder->Id(GL_TEXTURE_STORAGE1D_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(texture);
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(levels);
@@ -765,9 +1249,12 @@
                                            uint32_t format, int32_t width, int32_t height) {
     GAPID_INFO("glTextureStorage2DEXT()\n");
     mImports.glTextureStorage2DEXT(texture, target, levels, format, width, height);
-    mState.glTextureStorage2DEXT(texture, target, levels, format, width, height);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(35);  // Type ID -- TODO: mEncoder->Id(GL_TEXTURE_STORAGE2D_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(texture);
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(levels);
@@ -781,9 +1268,12 @@
                                            int32_t depth) {
     GAPID_INFO("glTextureStorage3DEXT()\n");
     mImports.glTextureStorage3DEXT(texture, target, levels, format, width, height, depth);
-    mState.glTextureStorage3DEXT(texture, target, levels, format, width, height, depth);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(36);  // Type ID -- TODO: mEncoder->Id(GL_TEXTURE_STORAGE3D_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(texture);
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(levels);
@@ -796,38 +1286,83 @@
 inline void GlesSpy::glGenVertexArraysOES(int32_t count, uint32_t* arrays) {
     GAPID_INFO("glGenVertexArraysOES()\n");
     mImports.glGenVertexArraysOES(count, arrays);
-    mState.glGenVertexArraysOES(count, arrays);
+
+    do {
+        Slice<VertexArrayId> l_a = slice(arrays, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_13_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_13_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            VertexArrayId l_id = (VertexArrayId)(
+                    read(slice(arrays, (uint64_t)(0), (uint64_t)(count)), (uint64_t)(l_i)));
+            l_ctx->mInstances.mVertexArrays[l_id] =
+                    std::shared_ptr<VertexArray>((new VertexArray()));
+            write(l_a, (uint64_t)(l_i), l_id);
+        }
+    } while (false);
 
     mEncoder->Uint16(37);  // Type ID -- TODO: mEncoder->Id(GL_GEN_VERTEX_ARRAYS_O_E_S_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(arrays));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glBindVertexArrayOES(uint32_t array) {
     GAPID_INFO("glBindVertexArrayOES()\n");
     mImports.glBindVertexArrayOES(array);
-    mState.glBindVertexArrayOES(array);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_14_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_14_result;
+        if (!(l_ctx->mInstances.mVertexArrays.count(array) > 0)) {
+            l_ctx->mInstances.mVertexArrays[array] =
+                    std::shared_ptr<VertexArray>((new VertexArray()));
+        }
+        l_ctx->mBoundVertexArray = array;
+    } while (false);
 
     mEncoder->Uint16(38);  // Type ID -- TODO: mEncoder->Id(GL_BIND_VERTEX_ARRAY_O_E_S_ID);
+    encodeObservations();
     mEncoder->Uint32(array);
 }
 
 inline void GlesSpy::glDeleteVertexArraysOES(int32_t count, uint32_t* arrays) {
     GAPID_INFO("glDeleteVertexArraysOES()\n");
     mImports.glDeleteVertexArraysOES(count, arrays);
-    mState.glDeleteVertexArraysOES(count, arrays);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_15_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_15_result;
+        Slice<VertexArrayId> l_a = slice(arrays, (uint64_t)(0), (uint64_t)(count));
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            l_ctx->mInstances.mVertexArrays[read(l_a, (uint64_t)(l_i))] =
+                    std::shared_ptr<VertexArray>();
+        }
+    } while (false);
 
     mEncoder->Uint16(39);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_VERTEX_ARRAYS_O_E_S_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(arrays));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline bool GlesSpy::glIsVertexArrayOES(uint32_t array) {
     GAPID_INFO("glIsVertexArrayOES()\n");
     bool result = mImports.glIsVertexArrayOES(array);
-    mState.glIsVertexArrayOES(array, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_16_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_16_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(40);  // Type ID -- TODO: mEncoder->Id(GL_IS_VERTEX_ARRAY_O_E_S_ID);
+    encodeObservations();
     mEncoder->Uint32(array);
     mEncoder->Bool(result);
 
@@ -837,31 +1372,43 @@
 inline void GlesSpy::glEGLImageTargetTexture2DOES(uint32_t target, void* image) {
     GAPID_INFO("glEGLImageTargetTexture2DOES()\n");
     mImports.glEGLImageTargetTexture2DOES(target, image);
-    mState.glEGLImageTargetTexture2DOES(target, image);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(
             41);  // Type ID -- TODO: mEncoder->Id(GL_E_G_L_IMAGE_TARGET_TEXTURE2D_O_E_S_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(image));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glEGLImageTargetRenderbufferStorageOES(uint32_t target, void* image) {
     GAPID_INFO("glEGLImageTargetRenderbufferStorageOES()\n");
     mImports.glEGLImageTargetRenderbufferStorageOES(target, image);
-    mState.glEGLImageTargetRenderbufferStorageOES(target, image);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(42);  // Type ID -- TODO:
                            // mEncoder->Id(GL_E_G_L_IMAGE_TARGET_RENDERBUFFER_STORAGE_O_E_S_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(image));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline uint32_t GlesSpy::glGetGraphicsResetStatusEXT() {
     GAPID_INFO("glGetGraphicsResetStatusEXT()\n");
     uint32_t result = mImports.glGetGraphicsResetStatusEXT();
-    mState.glGetGraphicsResetStatusEXT(result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(43);  // Type ID -- TODO: mEncoder->Id(GL_GET_GRAPHICS_RESET_STATUS_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(result));
 
     return result;
@@ -870,9 +1417,17 @@
 inline void GlesSpy::glBindAttribLocation(uint32_t program, uint32_t location, char* name) {
     GAPID_INFO("glBindAttribLocation()\n");
     mImports.glBindAttribLocation(program, location, name);
-    mState.glBindAttribLocation(program, location, name);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_17_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_17_result;
+        std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
+        l_p->mAttributeBindings[name] = location;
+    } while (false);
 
     mEncoder->Uint16(44);  // Type ID -- TODO: mEncoder->Id(GL_BIND_ATTRIB_LOCATION_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Uint32(location);
     mEncoder->String(name);
@@ -881,9 +1436,19 @@
 inline void GlesSpy::glBlendFunc(uint32_t src_factor, uint32_t dst_factor) {
     GAPID_INFO("glBlendFunc()\n");
     mImports.glBlendFunc(src_factor, dst_factor);
-    mState.glBlendFunc(src_factor, dst_factor);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_18_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_18_result;
+        l_ctx->mBlending.mSrcRgbBlendFactor = src_factor;
+        l_ctx->mBlending.mSrcAlphaBlendFactor = src_factor;
+        l_ctx->mBlending.mDstRgbBlendFactor = dst_factor;
+        l_ctx->mBlending.mDstAlphaBlendFactor = dst_factor;
+    } while (false);
 
     mEncoder->Uint16(45);  // Type ID -- TODO: mEncoder->Id(GL_BLEND_FUNC_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(src_factor));
     mEncoder->Uint32(static_cast<uint32_t>(dst_factor));
 }
@@ -893,9 +1458,19 @@
     GAPID_INFO("glBlendFuncSeparate()\n");
     mImports.glBlendFuncSeparate(src_factor_rgb, dst_factor_rgb, src_factor_alpha,
                                  dst_factor_alpha);
-    mState.glBlendFuncSeparate(src_factor_rgb, dst_factor_rgb, src_factor_alpha, dst_factor_alpha);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_19_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_19_result;
+        l_ctx->mBlending.mSrcRgbBlendFactor = src_factor_rgb;
+        l_ctx->mBlending.mDstRgbBlendFactor = dst_factor_rgb;
+        l_ctx->mBlending.mSrcAlphaBlendFactor = src_factor_alpha;
+        l_ctx->mBlending.mDstAlphaBlendFactor = dst_factor_alpha;
+    } while (false);
 
     mEncoder->Uint16(46);  // Type ID -- TODO: mEncoder->Id(GL_BLEND_FUNC_SEPARATE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(src_factor_rgb));
     mEncoder->Uint32(static_cast<uint32_t>(dst_factor_rgb));
     mEncoder->Uint32(static_cast<uint32_t>(src_factor_alpha));
@@ -905,18 +1480,34 @@
 inline void GlesSpy::glBlendEquation(uint32_t equation) {
     GAPID_INFO("glBlendEquation()\n");
     mImports.glBlendEquation(equation);
-    mState.glBlendEquation(equation);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_20_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_20_result;
+        l_ctx->mBlending.mBlendEquationRgb = equation;
+        l_ctx->mBlending.mBlendEquationAlpha = equation;
+    } while (false);
 
     mEncoder->Uint16(47);  // Type ID -- TODO: mEncoder->Id(GL_BLEND_EQUATION_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(equation));
 }
 
 inline void GlesSpy::glBlendEquationSeparate(uint32_t rgb, uint32_t alpha) {
     GAPID_INFO("glBlendEquationSeparate()\n");
     mImports.glBlendEquationSeparate(rgb, alpha);
-    mState.glBlendEquationSeparate(rgb, alpha);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_21_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_21_result;
+        l_ctx->mBlending.mBlendEquationRgb = rgb;
+        l_ctx->mBlending.mBlendEquationAlpha = alpha;
+    } while (false);
 
     mEncoder->Uint16(48);  // Type ID -- TODO: mEncoder->Id(GL_BLEND_EQUATION_SEPARATE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(rgb));
     mEncoder->Uint32(static_cast<uint32_t>(alpha));
 }
@@ -924,9 +1515,17 @@
 inline void GlesSpy::glBlendColor(float red, float green, float blue, float alpha) {
     GAPID_INFO("glBlendColor()\n");
     mImports.glBlendColor(red, green, blue, alpha);
-    mState.glBlendColor(red, green, blue, alpha);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_22_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_22_result;
+        l_ctx->mBlending.mBlendColor =
+                Color().SetRed(red).SetGreen(green).SetBlue(blue).SetAlpha(alpha);
+    } while (false);
 
     mEncoder->Uint16(49);  // Type ID -- TODO: mEncoder->Id(GL_BLEND_COLOR_ID);
+    encodeObservations();
     mEncoder->Float32(red);
     mEncoder->Float32(green);
     mEncoder->Float32(blue);
@@ -936,18 +1535,32 @@
 inline void GlesSpy::glEnableVertexAttribArray(uint32_t location) {
     GAPID_INFO("glEnableVertexAttribArray()\n");
     mImports.glEnableVertexAttribArray(location);
-    mState.glEnableVertexAttribArray(location);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_23_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_23_result;
+        l_ctx->mVertexAttributeArrays[location]->mEnabled = true;
+    } while (false);
 
     mEncoder->Uint16(50);  // Type ID -- TODO: mEncoder->Id(GL_ENABLE_VERTEX_ATTRIB_ARRAY_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
 }
 
 inline void GlesSpy::glDisableVertexAttribArray(uint32_t location) {
     GAPID_INFO("glDisableVertexAttribArray()\n");
     mImports.glDisableVertexAttribArray(location);
-    mState.glDisableVertexAttribArray(location);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_24_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_24_result;
+        l_ctx->mVertexAttributeArrays[location]->mEnabled = false;
+    } while (false);
 
     mEncoder->Uint16(51);  // Type ID -- TODO: mEncoder->Id(GL_DISABLE_VERTEX_ATTRIB_ARRAY_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
 }
 
@@ -955,15 +1568,29 @@
                                            bool normalized, int32_t stride, void* data) {
     GAPID_INFO("glVertexAttribPointer()\n");
     mImports.glVertexAttribPointer(location, size, type, normalized, stride, data);
-    mState.glVertexAttribPointer(location, size, type, normalized, stride, data);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_25_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_25_result;
+        std::shared_ptr<VertexAttributeArray> l_a = l_ctx->mVertexAttributeArrays[location];
+        l_a->mSize = (uint32_t)(size);
+        l_a->mType = type;
+        l_a->mNormalized = normalized;
+        l_a->mStride = stride;
+        l_a->mPointer = data;
+        l_a->mBuffer = l_ctx->mBoundBuffers[BufferTarget::GL_ARRAY_BUFFER];
+    } while (false);
 
     mEncoder->Uint16(52);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB_POINTER_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Int32(size);
     mEncoder->Uint32(static_cast<uint32_t>(type));
     mEncoder->Bool(normalized);
     mEncoder->Int32(stride);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetActiveAttrib(uint32_t program, uint32_t location, int32_t buffer_size,
@@ -972,17 +1599,23 @@
     GAPID_INFO("glGetActiveAttrib()\n");
     mImports.glGetActiveAttrib(program, location, buffer_size, buffer_bytes_written, vector_count,
                                type, name);
-    mState.glGetActiveAttrib(program, location, buffer_size, buffer_bytes_written, vector_count,
-                             type, name);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(53);  // Type ID -- TODO: mEncoder->Id(GL_GET_ACTIVE_ATTRIB_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Uint32(location);
     mEncoder->Int32(buffer_size);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(buffer_bytes_written));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(vector_count));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(type));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(name));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetActiveUniform(uint32_t program, int32_t location, int32_t buffer_size,
@@ -991,25 +1624,35 @@
     GAPID_INFO("glGetActiveUniform()\n");
     mImports.glGetActiveUniform(program, location, buffer_size, buffer_bytes_written, size, type,
                                 name);
-    mState.glGetActiveUniform(program, location, buffer_size, buffer_bytes_written, size, type,
-                              name);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(54);  // Type ID -- TODO: mEncoder->Id(GL_GET_ACTIVE_UNIFORM_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Int32(location);
     mEncoder->Int32(buffer_size);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(buffer_bytes_written));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(size));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(type));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(name));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline uint32_t GlesSpy::glGetError() {
     GAPID_INFO("glGetError()\n");
     uint32_t result = mImports.glGetError();
-    mState.glGetError(result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(55);  // Type ID -- TODO: mEncoder->Id(GL_GET_ERROR_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(result));
 
     return result;
@@ -1018,31 +1661,75 @@
 inline void GlesSpy::glGetProgramiv(uint32_t program, uint32_t parameter, int32_t* value) {
     GAPID_INFO("glGetProgramiv()\n");
     mImports.glGetProgramiv(program, parameter, value);
-    mState.glGetProgramiv(program, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(56);  // Type ID -- TODO: mEncoder->Id(GL_GET_PROGRAMIV_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetShaderiv(uint32_t shader, uint32_t parameter, int32_t* value) {
     GAPID_INFO("glGetShaderiv()\n");
     mImports.glGetShaderiv(shader, parameter, value);
-    mState.glGetShaderiv(shader, parameter, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_26_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_26_result;
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
+        write(slice(value, 0, 1), 0, /* clang-format off */
+        /* switch(parameter) */
+            /* case ShaderParameter::GL_SHADER_TYPE: */(((parameter) == (ShaderParameter::GL_SHADER_TYPE))) ? ((int32_t)(l_s->mType)) :
+            /* case ShaderParameter::GL_DELETE_STATUS: */(((parameter) == (ShaderParameter::GL_DELETE_STATUS))) ? (/* clang-format off */
+            /* switch(l_s->mDeletable) */
+                /* case true: */(((l_s->mDeletable) == (true))) ? (1) :
+                /* case false: */(((l_s->mDeletable) == (false))) ? (0) :
+                /* default: */ 0 /* clang-format on */)
+                              :
+                              /* case ShaderParameter::GL_COMPILE_STATUS: */ (
+                                      ((parameter) == (ShaderParameter::GL_COMPILE_STATUS)))
+                                      ? (/* clang-format off */
+            /* switch(l_s->mCompiled) */
+                /* case true: */(((l_s->mCompiled) == (true))) ? (1) :
+                /* case false: */(((l_s->mCompiled) == (false))) ? (0) :
+                /* default: */ 0 /* clang-format on */)
+                                      :
+                                      /* case ShaderParameter::GL_INFO_LOG_LENGTH: */ ((
+                                              (parameter) == (ShaderParameter::GL_INFO_LOG_LENGTH)))
+                                              ? ((int32_t)(strlen(l_s->mInfoLog)))
+                                              :
+                                              /* case ShaderParameter::GL_SHADER_SOURCE_LENGTH: */ (
+                                                      ((parameter) ==
+                                                       (ShaderParameter::GL_SHADER_SOURCE_LENGTH)))
+                                                      ? ((int32_t)(strlen(l_s->mSource)))
+                                                      :
+                                                      /* default: */ 0 /* clang-format on */);
+    } while (false);
 
     mEncoder->Uint16(57);  // Type ID -- TODO: mEncoder->Id(GL_GET_SHADERIV_ID);
+    encodeObservations();
     mEncoder->Uint32(shader);
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline int32_t GlesSpy::glGetUniformLocation(uint32_t program, char* name) {
     GAPID_INFO("glGetUniformLocation()\n");
     int32_t result = mImports.glGetUniformLocation(program, name);
-    mState.glGetUniformLocation(program, name, result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(58);  // Type ID -- TODO: mEncoder->Id(GL_GET_UNIFORM_LOCATION_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->String(name);
     mEncoder->Int32(result);
@@ -1053,9 +1740,13 @@
 inline uint32_t GlesSpy::glGetAttribLocation(uint32_t program, char* name) {
     GAPID_INFO("glGetAttribLocation()\n");
     uint32_t result = mImports.glGetAttribLocation(program, name);
-    mState.glGetAttribLocation(program, name, result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(59);  // Type ID -- TODO: mEncoder->Id(GL_GET_ATTRIB_LOCATION_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->String(name);
     mEncoder->Uint32(result);
@@ -1066,9 +1757,16 @@
 inline void GlesSpy::glPixelStorei(uint32_t parameter, int32_t value) {
     GAPID_INFO("glPixelStorei()\n");
     mImports.glPixelStorei(parameter, value);
-    mState.glPixelStorei(parameter, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_27_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_27_result;
+        l_ctx->mPixelStorage[parameter] = value;
+    } while (false);
 
     mEncoder->Uint16(60);  // Type ID -- TODO: mEncoder->Id(GL_PIXEL_STOREI_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Int32(value);
 }
@@ -1076,9 +1774,55 @@
 inline void GlesSpy::glTexParameteri(uint32_t target, uint32_t parameter, int32_t value) {
     GAPID_INFO("glTexParameteri()\n");
     mImports.glTexParameteri(target, parameter, value);
-    mState.glTexParameteri(target, parameter, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_28_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_28_result;
+        TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
+        std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+        switch (parameter) {
+            case TextureParameter::GL_TEXTURE_MAG_FILTER: {
+                l_t->mMagFilter = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_MIN_FILTER: {
+                l_t->mMinFilter = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_WRAP_S: {
+                l_t->mWrapS = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_WRAP_T: {
+                l_t->mWrapT = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: {
+                l_t->mMaxAnisotropy = (float)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_R: {
+                l_t->mSwizzleR = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_G: {
+                l_t->mSwizzleG = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_B: {
+                l_t->mSwizzleB = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_A: {
+                l_t->mSwizzleA = (uint32_t)(value);
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(61);  // Type ID -- TODO: mEncoder->Id(GL_TEX_PARAMETERI_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Int32(value);
@@ -1087,9 +1831,55 @@
 inline void GlesSpy::glTexParameterf(uint32_t target, uint32_t parameter, float value) {
     GAPID_INFO("glTexParameterf()\n");
     mImports.glTexParameterf(target, parameter, value);
-    mState.glTexParameterf(target, parameter, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_29_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_29_result;
+        TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
+        std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+        switch (parameter) {
+            case TextureParameter::GL_TEXTURE_MAG_FILTER: {
+                l_t->mMagFilter = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_MIN_FILTER: {
+                l_t->mMinFilter = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_WRAP_S: {
+                l_t->mWrapS = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_WRAP_T: {
+                l_t->mWrapT = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: {
+                l_t->mMaxAnisotropy = value;
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_R: {
+                l_t->mSwizzleR = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_G: {
+                l_t->mSwizzleG = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_B: {
+                l_t->mSwizzleB = (uint32_t)(value);
+                break;
+            }
+            case TextureParameter::GL_TEXTURE_SWIZZLE_A: {
+                l_t->mSwizzleA = (uint32_t)(value);
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(62);  // Type ID -- TODO: mEncoder->Id(GL_TEX_PARAMETERF_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Float32(value);
@@ -1098,31 +1888,84 @@
 inline void GlesSpy::glGetTexParameteriv(uint32_t target, uint32_t parameter, int32_t* values) {
     GAPID_INFO("glGetTexParameteriv()\n");
     mImports.glGetTexParameteriv(target, parameter, values);
-    mState.glGetTexParameteriv(target, parameter, values);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_30_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_30_result;
+        TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
+        std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+        write(slice(values, 0, 1), 0, /* clang-format off */
+        /* switch(parameter) */
+            /* case TextureParameter::GL_TEXTURE_MAG_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MAG_FILTER))) ? ((int32_t)(l_t->mMagFilter)) :
+            /* case TextureParameter::GL_TEXTURE_MIN_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MIN_FILTER))) ? ((int32_t)(l_t->mMinFilter)) :
+            /* case TextureParameter::GL_TEXTURE_WRAP_S: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_S))) ? ((int32_t)(l_t->mWrapS)) :
+            /* case TextureParameter::GL_TEXTURE_WRAP_T: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_T))) ? ((int32_t)(l_t->mWrapT)) :
+            /* case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: */(((parameter) == (TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT))) ? ((int32_t)(l_t->mMaxAnisotropy)) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_R: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_R))) ? ((int32_t)(l_t->mSwizzleR)) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_G: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_G))) ? ((int32_t)(l_t->mSwizzleG)) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_B: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_B))) ? ((int32_t)(l_t->mSwizzleB)) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_A: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_A))) ? ((int32_t)(l_t->mSwizzleA)) :
+            /* default: */ 0 /* clang-format on */);
+    } while (false);
 
     mEncoder->Uint16(63);  // Type ID -- TODO: mEncoder->Id(GL_GET_TEX_PARAMETERIV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetTexParameterfv(uint32_t target, uint32_t parameter, float* values) {
     GAPID_INFO("glGetTexParameterfv()\n");
     mImports.glGetTexParameterfv(target, parameter, values);
-    mState.glGetTexParameterfv(target, parameter, values);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_31_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_31_result;
+        TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
+        std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+        write(slice(values, 0, 1), 0, /* clang-format off */
+        /* switch(parameter) */
+            /* case TextureParameter::GL_TEXTURE_MAG_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MAG_FILTER))) ? ((float)(l_t->mMagFilter)) :
+            /* case TextureParameter::GL_TEXTURE_MIN_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MIN_FILTER))) ? ((float)(l_t->mMinFilter)) :
+            /* case TextureParameter::GL_TEXTURE_WRAP_S: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_S))) ? ((float)(l_t->mWrapS)) :
+            /* case TextureParameter::GL_TEXTURE_WRAP_T: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_T))) ? ((float)(l_t->mWrapT)) :
+            /* case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: */(((parameter) == (TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT))) ? (l_t->mMaxAnisotropy) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_R: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_R))) ? ((float)(l_t->mSwizzleR)) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_G: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_G))) ? ((float)(l_t->mSwizzleG)) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_B: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_B))) ? ((float)(l_t->mSwizzleB)) :
+            /* case TextureParameter::GL_TEXTURE_SWIZZLE_A: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_A))) ? ((float)(l_t->mSwizzleA)) :
+            /* default: */ 0 /* clang-format on */);
+    } while (false);
 
     mEncoder->Uint16(64);  // Type ID -- TODO: mEncoder->Id(GL_GET_TEX_PARAMETERFV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform1i(int32_t location, int32_t value) {
     GAPID_INFO("glUniform1i()\n");
     mImports.glUniform1i(location, value);
-    mState.glUniform1i(location, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_32_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_32_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT;
+        l_uniform.mValue.mS32 = value;
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(65);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM1I_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(value);
 }
@@ -1130,9 +1973,20 @@
 inline void GlesSpy::glUniform2i(int32_t location, int32_t value0, int32_t value1) {
     GAPID_INFO("glUniform2i()\n");
     mImports.glUniform2i(location, value0, value1);
-    mState.glUniform2i(location, value0, value1);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_33_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_33_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT_VEC2;
+        l_uniform.mValue.mVec2i = Vec2i().SetX(value0).SetY(value1);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(66);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM2I_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(value0);
     mEncoder->Int32(value1);
@@ -1141,9 +1995,20 @@
 inline void GlesSpy::glUniform3i(int32_t location, int32_t value0, int32_t value1, int32_t value2) {
     GAPID_INFO("glUniform3i()\n");
     mImports.glUniform3i(location, value0, value1, value2);
-    mState.glUniform3i(location, value0, value1, value2);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_34_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_34_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT_VEC3;
+        l_uniform.mValue.mVec3i = Vec3i().SetX(value0).SetY(value1).SetZ(value2);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(67);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM3I_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(value0);
     mEncoder->Int32(value1);
@@ -1154,9 +2019,20 @@
                                  int32_t value3) {
     GAPID_INFO("glUniform4i()\n");
     mImports.glUniform4i(location, value0, value1, value2, value3);
-    mState.glUniform4i(location, value0, value1, value2, value3);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_35_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_35_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT_VEC4;
+        l_uniform.mValue.mVec4i = Vec4i().SetX(value0).SetY(value1).SetZ(value2).SetW(value3);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(68);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM4I_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(value0);
     mEncoder->Int32(value1);
@@ -1167,53 +2043,116 @@
 inline void GlesSpy::glUniform1iv(int32_t location, int32_t count, int32_t* value) {
     GAPID_INFO("glUniform1iv()\n");
     mImports.glUniform1iv(location, count, value);
-    mState.glUniform1iv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_36_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_36_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT;
+        l_uniform.mValue.mS32 = read(slice(value, 0, 1), 0);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(69);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM1IV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform2iv(int32_t location, int32_t count, int32_t* value) {
     GAPID_INFO("glUniform2iv()\n");
     mImports.glUniform2iv(location, count, value);
-    mState.glUniform2iv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_37_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_37_result;
+        Slice<int32_t> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 2));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT_VEC2;
+        l_uniform.mValue.mVec2i = Vec2i().SetX(read(l_v, 0)).SetY(read(l_v, 1));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(70);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM2IV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform3iv(int32_t location, int32_t count, int32_t* value) {
     GAPID_INFO("glUniform3iv()\n");
     mImports.glUniform3iv(location, count, value);
-    mState.glUniform3iv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_38_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_38_result;
+        Slice<int32_t> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 3));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT_VEC3;
+        l_uniform.mValue.mVec3i = Vec3i().SetX(read(l_v, 0)).SetY(read(l_v, 1)).SetZ(read(l_v, 2));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(71);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM3IV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform4iv(int32_t location, int32_t count, int32_t* value) {
     GAPID_INFO("glUniform4iv()\n");
     mImports.glUniform4iv(location, count, value);
-    mState.glUniform4iv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_39_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_39_result;
+        Slice<int32_t> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 4));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_INT_VEC4;
+        l_uniform.mValue.mVec4i =
+                Vec4i().SetX(read(l_v, 0)).SetY(read(l_v, 1)).SetZ(read(l_v, 2)).SetW(read(l_v, 3));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(72);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM4IV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform1f(int32_t location, float value) {
     GAPID_INFO("glUniform1f()\n");
     mImports.glUniform1f(location, value);
-    mState.glUniform1f(location, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_40_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_40_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT;
+        l_uniform.mValue.mF32 = value;
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(73);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM1F_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Float32(value);
 }
@@ -1221,9 +2160,20 @@
 inline void GlesSpy::glUniform2f(int32_t location, float value0, float value1) {
     GAPID_INFO("glUniform2f()\n");
     mImports.glUniform2f(location, value0, value1);
-    mState.glUniform2f(location, value0, value1);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_41_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_41_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC2;
+        l_uniform.mValue.mVec2f = Vec2f().SetX(value0).SetY(value1);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(74);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM2F_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Float32(value0);
     mEncoder->Float32(value1);
@@ -1232,9 +2182,20 @@
 inline void GlesSpy::glUniform3f(int32_t location, float value0, float value1, float value2) {
     GAPID_INFO("glUniform3f()\n");
     mImports.glUniform3f(location, value0, value1, value2);
-    mState.glUniform3f(location, value0, value1, value2);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_42_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_42_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC3;
+        l_uniform.mValue.mVec3f = Vec3f().SetX(value0).SetY(value1).SetZ(value2);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(75);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM3F_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Float32(value0);
     mEncoder->Float32(value1);
@@ -1245,9 +2206,20 @@
                                  float value3) {
     GAPID_INFO("glUniform4f()\n");
     mImports.glUniform4f(location, value0, value1, value2, value3);
-    mState.glUniform4f(location, value0, value1, value2, value3);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_43_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_43_result;
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC4;
+        l_uniform.mValue.mVec4f = Vec4f().SetX(value0).SetY(value1).SetZ(value2).SetW(value3);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(76);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM4F_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Float32(value0);
     mEncoder->Float32(value1);
@@ -1258,114 +2230,243 @@
 inline void GlesSpy::glUniform1fv(int32_t location, int32_t count, float* value) {
     GAPID_INFO("glUniform1fv()\n");
     mImports.glUniform1fv(location, count, value);
-    mState.glUniform1fv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_44_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_44_result;
+        Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT;
+        l_uniform.mValue.mF32 = read(l_v, 0);
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(77);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM1FV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform2fv(int32_t location, int32_t count, float* value) {
     GAPID_INFO("glUniform2fv()\n");
     mImports.glUniform2fv(location, count, value);
-    mState.glUniform2fv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_45_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_45_result;
+        Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 2));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC2;
+        l_uniform.mValue.mVec2f = Vec2f().SetX(read(l_v, 0)).SetY(read(l_v, 1));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(78);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM2FV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform3fv(int32_t location, int32_t count, float* value) {
     GAPID_INFO("glUniform3fv()\n");
     mImports.glUniform3fv(location, count, value);
-    mState.glUniform3fv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_46_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_46_result;
+        Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 3));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC3;
+        l_uniform.mValue.mVec3f = Vec3f().SetX(read(l_v, 0)).SetY(read(l_v, 1)).SetZ(read(l_v, 2));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(79);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM3FV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniform4fv(int32_t location, int32_t count, float* value) {
     GAPID_INFO("glUniform4fv()\n");
     mImports.glUniform4fv(location, count, value);
-    mState.glUniform4fv(location, count, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_47_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_47_result;
+        Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 4));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC4;
+        l_uniform.mValue.mVec4f =
+                Vec4f().SetX(read(l_v, 0)).SetY(read(l_v, 1)).SetZ(read(l_v, 2)).SetW(read(l_v, 3));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(80);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM4FV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniformMatrix2fv(int32_t location, int32_t count, bool transpose,
                                         float* values) {
     GAPID_INFO("glUniformMatrix2fv()\n");
     mImports.glUniformMatrix2fv(location, count, transpose, values);
-    mState.glUniformMatrix2fv(location, count, transpose, values);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_48_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_48_result;
+        Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(count * 4));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_MAT2;
+        l_uniform.mValue.mMat2f = Mat2f()
+                                          .SetCol0(Vec2f().SetX(read(l_v, 0)).SetY(read(l_v, 1)))
+                                          .SetCol1(Vec2f().SetX(read(l_v, 3)).SetY(read(l_v, 4)));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(81);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM_MATRIX2FV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Bool(transpose);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniformMatrix3fv(int32_t location, int32_t count, bool transpose,
                                         float* values) {
     GAPID_INFO("glUniformMatrix3fv()\n");
     mImports.glUniformMatrix3fv(location, count, transpose, values);
-    mState.glUniformMatrix3fv(location, count, transpose, values);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_49_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_49_result;
+        Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(count * 9));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mType = ShaderUniformType::GL_FLOAT_MAT3;
+        l_uniform.mValue.mMat3f =
+                Mat3f()
+                        .SetCol0(Vec3f().SetX(read(l_v, 0)).SetY(read(l_v, 1)).SetZ(read(l_v, 2)))
+                        .SetCol1(Vec3f().SetX(read(l_v, 3)).SetY(read(l_v, 4)).SetZ(read(l_v, 5)))
+                        .SetCol2(Vec3f().SetX(read(l_v, 6)).SetY(read(l_v, 7)).SetZ(read(l_v, 8)));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(82);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM_MATRIX3FV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Bool(transpose);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUniformMatrix4fv(int32_t location, int32_t count, bool transpose,
                                         float* values) {
     GAPID_INFO("glUniformMatrix4fv()\n");
     mImports.glUniformMatrix4fv(location, count, transpose, values);
-    mState.glUniformMatrix4fv(location, count, transpose, values);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_50_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_50_result;
+        Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(count * 16));
+        std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
+        Uniform l_uniform = l_program->mUniforms[location];
+        l_uniform.mValue.mMat4f =
+                Mat4f()
+                        .SetCol0(Vec4f()
+                                         .SetX(read(l_v, 0))
+                                         .SetY(read(l_v, 1))
+                                         .SetZ(read(l_v, 2))
+                                         .SetW(read(l_v, 3)))
+                        .SetCol1(Vec4f()
+                                         .SetX(read(l_v, 4))
+                                         .SetY(read(l_v, 5))
+                                         .SetZ(read(l_v, 6))
+                                         .SetW(read(l_v, 7)))
+                        .SetCol2(Vec4f()
+                                         .SetX(read(l_v, 8))
+                                         .SetY(read(l_v, 9))
+                                         .SetZ(read(l_v, 10))
+                                         .SetW(read(l_v, 11)))
+                        .SetCol3(Vec4f()
+                                         .SetX(read(l_v, 12))
+                                         .SetY(read(l_v, 13))
+                                         .SetZ(read(l_v, 14))
+                                         .SetW(read(l_v, 15)));
+        l_program->mUniforms[location] = l_uniform;
+    } while (false);
 
     mEncoder->Uint16(83);  // Type ID -- TODO: mEncoder->Id(GL_UNIFORM_MATRIX4FV_ID);
+    encodeObservations();
     mEncoder->Int32(location);
     mEncoder->Int32(count);
     mEncoder->Bool(transpose);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetUniformfv(uint32_t program, int32_t location, float* values) {
     GAPID_INFO("glGetUniformfv()\n");
     mImports.glGetUniformfv(program, location, values);
-    mState.glGetUniformfv(program, location, values);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(84);  // Type ID -- TODO: mEncoder->Id(GL_GET_UNIFORMFV_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Int32(location);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetUniformiv(uint32_t program, int32_t location, int32_t* values) {
     GAPID_INFO("glGetUniformiv()\n");
     mImports.glGetUniformiv(program, location, values);
-    mState.glGetUniformiv(program, location, values);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(85);  // Type ID -- TODO: mEncoder->Id(GL_GET_UNIFORMIV_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Int32(location);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glVertexAttrib1f(uint32_t location, float value0) {
     GAPID_INFO("glVertexAttrib1f()\n");
     mImports.glVertexAttrib1f(location, value0);
-    mState.glVertexAttrib1f(location, value0);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(86);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB1F_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Float32(value0);
 }
@@ -1373,9 +2474,12 @@
 inline void GlesSpy::glVertexAttrib2f(uint32_t location, float value0, float value1) {
     GAPID_INFO("glVertexAttrib2f()\n");
     mImports.glVertexAttrib2f(location, value0, value1);
-    mState.glVertexAttrib2f(location, value0, value1);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(87);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB2F_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Float32(value0);
     mEncoder->Float32(value1);
@@ -1384,9 +2488,12 @@
 inline void GlesSpy::glVertexAttrib3f(uint32_t location, float value0, float value1, float value2) {
     GAPID_INFO("glVertexAttrib3f()\n");
     mImports.glVertexAttrib3f(location, value0, value1, value2);
-    mState.glVertexAttrib3f(location, value0, value1, value2);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(88);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB3F_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Float32(value0);
     mEncoder->Float32(value1);
@@ -1397,9 +2504,12 @@
                                       float value3) {
     GAPID_INFO("glVertexAttrib4f()\n");
     mImports.glVertexAttrib4f(location, value0, value1, value2, value3);
-    mState.glVertexAttrib4f(location, value0, value1, value2, value3);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(89);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB4F_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Float32(value0);
     mEncoder->Float32(value1);
@@ -1410,80 +2520,129 @@
 inline void GlesSpy::glVertexAttrib1fv(uint32_t location, float* value) {
     GAPID_INFO("glVertexAttrib1fv()\n");
     mImports.glVertexAttrib1fv(location, value);
-    mState.glVertexAttrib1fv(location, value);
+
+    do {
+        read(slice(value, 0, 1));
+    } while (false);
 
     mEncoder->Uint16(90);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB1FV_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glVertexAttrib2fv(uint32_t location, float* value) {
     GAPID_INFO("glVertexAttrib2fv()\n");
     mImports.glVertexAttrib2fv(location, value);
-    mState.glVertexAttrib2fv(location, value);
+
+    do {
+        read(slice(value, 0, 2));
+    } while (false);
 
     mEncoder->Uint16(91);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB2FV_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glVertexAttrib3fv(uint32_t location, float* value) {
     GAPID_INFO("glVertexAttrib3fv()\n");
     mImports.glVertexAttrib3fv(location, value);
-    mState.glVertexAttrib3fv(location, value);
+
+    do {
+        read(slice(value, 0, 3));
+    } while (false);
 
     mEncoder->Uint16(92);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB3FV_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glVertexAttrib4fv(uint32_t location, float* value) {
     GAPID_INFO("glVertexAttrib4fv()\n");
     mImports.glVertexAttrib4fv(location, value);
-    mState.glVertexAttrib4fv(location, value);
+
+    do {
+        read(slice(value, 0, 4));
+    } while (false);
 
     mEncoder->Uint16(93);  // Type ID -- TODO: mEncoder->Id(GL_VERTEX_ATTRIB4FV_ID);
+    encodeObservations();
     mEncoder->Uint32(location);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetShaderPrecisionFormat(uint32_t shader_type, uint32_t precision_type,
                                                 int32_t* range, int32_t* precision) {
     GAPID_INFO("glGetShaderPrecisionFormat()\n");
     mImports.glGetShaderPrecisionFormat(shader_type, precision_type, range, precision);
-    mState.glGetShaderPrecisionFormat(shader_type, precision_type, range, precision);
+
+    do {
+        write(slice(range, 0, 2));
+        write(slice(precision, 0, 1), 0, read(slice(precision, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(94);  // Type ID -- TODO: mEncoder->Id(GL_GET_SHADER_PRECISION_FORMAT_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(shader_type));
     mEncoder->Uint32(static_cast<uint32_t>(precision_type));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(range));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(precision));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glDepthMask(bool enabled) {
     GAPID_INFO("glDepthMask()\n");
     mImports.glDepthMask(enabled);
-    mState.glDepthMask(enabled);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_51_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_51_result;
+        l_ctx->mRasterizing.mDepthMask = enabled;
+    } while (false);
 
     mEncoder->Uint16(95);  // Type ID -- TODO: mEncoder->Id(GL_DEPTH_MASK_ID);
+    encodeObservations();
     mEncoder->Bool(enabled);
 }
 
 inline void GlesSpy::glDepthFunc(uint32_t function) {
     GAPID_INFO("glDepthFunc()\n");
     mImports.glDepthFunc(function);
-    mState.glDepthFunc(function);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_52_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_52_result;
+        l_ctx->mRasterizing.mDepthTestFunction = function;
+    } while (false);
 
     mEncoder->Uint16(96);  // Type ID -- TODO: mEncoder->Id(GL_DEPTH_FUNC_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(function));
 }
 
 inline void GlesSpy::glDepthRangef(float near, float far) {
     GAPID_INFO("glDepthRangef()\n");
     mImports.glDepthRangef(near, far);
-    mState.glDepthRangef(near, far);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_53_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_53_result;
+        l_ctx->mRasterizing.mDepthNear = near;
+        l_ctx->mRasterizing.mDepthFar = far;
+    } while (false);
 
     mEncoder->Uint16(97);  // Type ID -- TODO: mEncoder->Id(GL_DEPTH_RANGEF_ID);
+    encodeObservations();
     mEncoder->Float32(near);
     mEncoder->Float32(far);
 }
@@ -1491,9 +2650,19 @@
 inline void GlesSpy::glColorMask(bool red, bool green, bool blue, bool alpha) {
     GAPID_INFO("glColorMask()\n");
     mImports.glColorMask(red, green, blue, alpha);
-    mState.glColorMask(red, green, blue, alpha);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_54_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_54_result;
+        l_ctx->mRasterizing.mColorMaskRed = red;
+        l_ctx->mRasterizing.mColorMaskGreen = green;
+        l_ctx->mRasterizing.mColorMaskBlue = blue;
+        l_ctx->mRasterizing.mColorMaskAlpha = alpha;
+    } while (false);
 
     mEncoder->Uint16(98);  // Type ID -- TODO: mEncoder->Id(GL_COLOR_MASK_ID);
+    encodeObservations();
     mEncoder->Bool(red);
     mEncoder->Bool(green);
     mEncoder->Bool(blue);
@@ -1503,18 +2672,47 @@
 inline void GlesSpy::glStencilMask(uint32_t mask) {
     GAPID_INFO("glStencilMask()\n");
     mImports.glStencilMask(mask);
-    mState.glStencilMask(mask);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_55_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_55_result;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = mask;
+        l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = mask;
+    } while (false);
 
     mEncoder->Uint16(99);  // Type ID -- TODO: mEncoder->Id(GL_STENCIL_MASK_ID);
+    encodeObservations();
     mEncoder->Uint32(mask);
 }
 
 inline void GlesSpy::glStencilMaskSeparate(uint32_t face, uint32_t mask) {
     GAPID_INFO("glStencilMaskSeparate()\n");
     mImports.glStencilMaskSeparate(face, mask);
-    mState.glStencilMaskSeparate(face, mask);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_56_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_56_result;
+        switch (face) {
+            case FaceMode::GL_FRONT: {
+                l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = mask;
+                break;
+            }
+            case FaceMode::GL_BACK: {
+                l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = mask;
+                break;
+            }
+            case FaceMode::GL_FRONT_AND_BACK: {
+                l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = mask;
+                l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = mask;
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(100);  // Type ID -- TODO: mEncoder->Id(GL_STENCIL_MASK_SEPARATE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(face));
     mEncoder->Uint32(mask);
 }
@@ -1523,9 +2721,12 @@
                                            int32_t reference_value, int32_t mask) {
     GAPID_INFO("glStencilFuncSeparate()\n");
     mImports.glStencilFuncSeparate(face, function, reference_value, mask);
-    mState.glStencilFuncSeparate(face, function, reference_value, mask);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(101);  // Type ID -- TODO: mEncoder->Id(GL_STENCIL_FUNC_SEPARATE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(face));
     mEncoder->Uint32(static_cast<uint32_t>(function));
     mEncoder->Int32(reference_value);
@@ -1538,10 +2739,12 @@
     GAPID_INFO("glStencilOpSeparate()\n");
     mImports.glStencilOpSeparate(face, stencil_fail, stencil_pass_depth_fail,
                                  stencil_pass_depth_pass);
-    mState.glStencilOpSeparate(face, stencil_fail, stencil_pass_depth_fail,
-                               stencil_pass_depth_pass);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(102);  // Type ID -- TODO: mEncoder->Id(GL_STENCIL_OP_SEPARATE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(face));
     mEncoder->Uint32(static_cast<uint32_t>(stencil_fail));
     mEncoder->Uint32(static_cast<uint32_t>(stencil_pass_depth_fail));
@@ -1551,18 +2754,32 @@
 inline void GlesSpy::glFrontFace(uint32_t orientation) {
     GAPID_INFO("glFrontFace()\n");
     mImports.glFrontFace(orientation);
-    mState.glFrontFace(orientation);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_57_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_57_result;
+        l_ctx->mRasterizing.mFrontFace = orientation;
+    } while (false);
 
     mEncoder->Uint16(103);  // Type ID -- TODO: mEncoder->Id(GL_FRONT_FACE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(orientation));
 }
 
 inline void GlesSpy::glViewport(int32_t x, int32_t y, int32_t width, int32_t height) {
     GAPID_INFO("glViewport()\n");
     mImports.glViewport(x, y, width, height);
-    mState.glViewport(x, y, width, height);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_58_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_58_result;
+        l_ctx->mRasterizing.mViewport = Rect().SetX(x).SetY(y).SetWidth(width).SetHeight(height);
+    } while (false);
 
     mEncoder->Uint16(104);  // Type ID -- TODO: mEncoder->Id(GL_VIEWPORT_ID);
+    encodeObservations();
     mEncoder->Int32(x);
     mEncoder->Int32(y);
     mEncoder->Int32(width);
@@ -1572,9 +2789,16 @@
 inline void GlesSpy::glScissor(int32_t x, int32_t y, int32_t width, int32_t height) {
     GAPID_INFO("glScissor()\n");
     mImports.glScissor(x, y, width, height);
-    mState.glScissor(x, y, width, height);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_59_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_59_result;
+        l_ctx->mRasterizing.mScissor = Rect().SetX(x).SetY(y).SetWidth(width).SetHeight(height);
+    } while (false);
 
     mEncoder->Uint16(105);  // Type ID -- TODO: mEncoder->Id(GL_SCISSOR_ID);
+    encodeObservations();
     mEncoder->Int32(x);
     mEncoder->Int32(y);
     mEncoder->Int32(width);
@@ -1584,38 +2808,80 @@
 inline void GlesSpy::glActiveTexture(uint32_t unit) {
     GAPID_INFO("glActiveTexture()\n");
     mImports.glActiveTexture(unit);
-    mState.glActiveTexture(unit);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_60_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_60_result;
+        l_ctx->mActiveTextureUnit = unit;
+        if (!(l_ctx->mTextureUnits.count(unit) > 0)) {
+            l_ctx->mTextureUnits[unit] = l_ctx->mTextureUnits[unit];
+        }
+    } while (false);
 
     mEncoder->Uint16(106);  // Type ID -- TODO: mEncoder->Id(GL_ACTIVE_TEXTURE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(unit));
 }
 
 inline void GlesSpy::glGenTextures(int32_t count, uint32_t* textures) {
     GAPID_INFO("glGenTextures()\n");
     mImports.glGenTextures(count, textures);
-    mState.glGenTextures(count, textures);
+
+    do {
+        Slice<TextureId> l_t = slice(textures, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_61_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_61_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            TextureId l_id = (TextureId)(
+                    read(slice(textures, (uint64_t)(0), (uint64_t)(count)), (uint64_t)(l_i)));
+            l_ctx->mInstances.mTextures[l_id] = std::shared_ptr<Texture>((new Texture()));
+            write(l_t, (uint64_t)(l_i), l_id);
+        }
+    } while (false);
 
     mEncoder->Uint16(107);  // Type ID -- TODO: mEncoder->Id(GL_GEN_TEXTURES_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(textures));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glDeleteTextures(int32_t count, uint32_t* textures) {
     GAPID_INFO("glDeleteTextures()\n");
     mImports.glDeleteTextures(count, textures);
-    mState.glDeleteTextures(count, textures);
+
+    do {
+        Slice<TextureId> l_t = slice(textures, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_62_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_62_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            l_ctx->mInstances.mTextures[read(l_t, (uint64_t)(l_i))] = std::shared_ptr<Texture>();
+        }
+    } while (false);
 
     mEncoder->Uint16(108);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_TEXTURES_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(textures));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline bool GlesSpy::glIsTexture(uint32_t texture) {
     GAPID_INFO("glIsTexture()\n");
     bool result = mImports.glIsTexture(texture);
-    mState.glIsTexture(texture, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_63_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_63_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(109);  // Type ID -- TODO: mEncoder->Id(GL_IS_TEXTURE_ID);
+    encodeObservations();
     mEncoder->Uint32(texture);
     mEncoder->Bool(result);
 
@@ -1625,9 +2891,19 @@
 inline void GlesSpy::glBindTexture(uint32_t target, uint32_t texture) {
     GAPID_INFO("glBindTexture()\n");
     mImports.glBindTexture(target, texture);
-    mState.glBindTexture(target, texture);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_64_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_64_result;
+        if (!(l_ctx->mInstances.mTextures.count(texture) > 0)) {
+            l_ctx->mInstances.mTextures[texture] = std::shared_ptr<Texture>((new Texture()));
+        }
+        l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target] = texture;
+    } while (false);
 
     mEncoder->Uint16(110);  // Type ID -- TODO: mEncoder->Id(GL_BIND_TEXTURE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(texture);
 }
@@ -1638,9 +2914,72 @@
     GAPID_INFO("glTexImage2D()\n");
     mImports.glTexImage2D(target, level, internal_format, width, height, border, format, type,
                           data);
-    mState.glTexImage2D(target, level, internal_format, width, height, border, format, type, data);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_65_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_65_result;
+        switch (target) {
+            case TextureImageTarget::GL_TEXTURE_2D: {
+                TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                     [TextureTarget::GL_TEXTURE_2D];
+                std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+                Image l_l = Image()
+                                    .SetWidth(width)
+                                    .SetHeight(height)
+                                    .SetSize(imageSize((uint32_t)(width), (uint32_t)(height),
+                                                       format, type))
+                                    .SetFormat((uint32_t)(format));
+                if (data != nullptr) {
+                    if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] ==
+                        (BufferId)(0)) {
+                        l_l.mData = clone(
+                                slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
+                    }
+                } else {
+                    l_l.mData = make<uint8_t>((uint64_t)(l_l.mSize));
+                }
+                l_t->mTexture2D[level] = l_l;
+                l_t->mKind = TextureKind::TEXTURE2D;
+                l_t->mFormat = (uint32_t)(format);
+                break;
+            }
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: {
+                TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                     [TextureTarget::GL_TEXTURE_CUBE_MAP];
+                std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+                Image l_l = Image()
+                                    .SetWidth(width)
+                                    .SetHeight(height)
+                                    .SetSize(imageSize((uint32_t)(width), (uint32_t)(height),
+                                                       format, type))
+                                    .SetFormat((uint32_t)(format));
+                if (data != nullptr) {
+                    if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] ==
+                        (BufferId)(0)) {
+                        l_l.mData = clone(
+                                slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
+                    }
+                } else {
+                    l_l.mData = make<uint8_t>((uint64_t)(l_l.mSize));
+                }
+                CubemapLevel l_cube = l_t->mCubemap[level];
+                l_cube.mFaces[(uint32_t)(target)] = l_l;
+                l_t->mCubemap[level] = l_cube;
+                l_t->mKind = TextureKind::CUBEMAP;
+                l_t->mFormat = (uint32_t)(format);
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(111);  // Type ID -- TODO: mEncoder->Id(GL_TEX_IMAGE2D_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(level);
     mEncoder->Uint32(static_cast<uint32_t>(internal_format));
@@ -1650,6 +2989,7 @@
     mEncoder->Uint32(static_cast<uint32_t>(format));
     mEncoder->Uint32(static_cast<uint32_t>(type));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glTexSubImage2D(uint32_t target, int32_t level, int32_t xoffset,
@@ -1657,9 +2997,64 @@
                                      uint32_t format, uint32_t type, void* data) {
     GAPID_INFO("glTexSubImage2D()\n");
     mImports.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
-    mState.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_66_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_66_result;
+        switch (target) {
+            case TextureImageTarget::GL_TEXTURE_2D: {
+                TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                     [TextureTarget::GL_TEXTURE_2D];
+                std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+                Image l_l = Image()
+                                    .SetWidth(width)
+                                    .SetHeight(height)
+                                    .SetSize(imageSize((uint32_t)(width), (uint32_t)(height),
+                                                       format, type))
+                                    .SetFormat((uint32_t)(format));
+                if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
+                    data != nullptr) {
+                    l_l.mData =
+                            clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
+                }
+                l_t->mTexture2D[level] = l_l;
+                l_t->mKind = TextureKind::TEXTURE2D;
+                l_t->mFormat = (uint32_t)(format);
+                break;
+            }
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: {
+                TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                     [TextureTarget::GL_TEXTURE_CUBE_MAP];
+                std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+                Image l_l = Image()
+                                    .SetWidth(width)
+                                    .SetHeight(height)
+                                    .SetSize(imageSize((uint32_t)(width), (uint32_t)(height),
+                                                       format, type))
+                                    .SetFormat((uint32_t)(format));
+                if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
+                    data != nullptr) {
+                    l_l.mData =
+                            clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
+                }
+                CubemapLevel l_cube = l_t->mCubemap[level];
+                l_cube.mFaces[(uint32_t)(target)] = l_l;
+                l_t->mCubemap[level] = l_cube;
+                l_t->mKind = TextureKind::CUBEMAP;
+                l_t->mFormat = (uint32_t)(format);
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(112);  // Type ID -- TODO: mEncoder->Id(GL_TEX_SUB_IMAGE2D_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(level);
     mEncoder->Int32(xoffset);
@@ -1669,15 +3064,19 @@
     mEncoder->Uint32(static_cast<uint32_t>(format));
     mEncoder->Uint32(static_cast<uint32_t>(type));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glCopyTexImage2D(uint32_t target, int32_t level, uint32_t format, int32_t x,
                                       int32_t y, int32_t width, int32_t height, int32_t border) {
     GAPID_INFO("glCopyTexImage2D()\n");
     mImports.glCopyTexImage2D(target, level, format, x, y, width, height, border);
-    mState.glCopyTexImage2D(target, level, format, x, y, width, height, border);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(113);  // Type ID -- TODO: mEncoder->Id(GL_COPY_TEX_IMAGE2D_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(level);
     mEncoder->Uint32(static_cast<uint32_t>(format));
@@ -1693,9 +3092,12 @@
                                          int32_t height) {
     GAPID_INFO("glCopyTexSubImage2D()\n");
     mImports.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-    mState.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(114);  // Type ID -- TODO: mEncoder->Id(GL_COPY_TEX_SUB_IMAGE2D_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(level);
     mEncoder->Int32(xoffset);
@@ -1711,9 +3113,62 @@
                                             int32_t image_size, void* data) {
     GAPID_INFO("glCompressedTexImage2D()\n");
     mImports.glCompressedTexImage2D(target, level, format, width, height, border, image_size, data);
-    mState.glCompressedTexImage2D(target, level, format, width, height, border, image_size, data);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_67_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_67_result;
+        switch (target) {
+            case TextureImageTarget::GL_TEXTURE_2D: {
+                TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                     [TextureTarget::GL_TEXTURE_2D];
+                std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+                Image l_l = Image()
+                                    .SetWidth(width)
+                                    .SetHeight(height)
+                                    .SetSize((uint32_t)(image_size))
+                                    .SetFormat((uint32_t)(format));
+                if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
+                    data != nullptr) {
+                    l_l.mData =
+                            clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
+                }
+                l_t->mTexture2D[level] = l_l;
+                l_t->mKind = TextureKind::TEXTURE2D;
+                l_t->mFormat = (uint32_t)(format);
+                break;
+            }
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:  // fall-through...
+            case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: {
+                TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                     [TextureTarget::GL_TEXTURE_CUBE_MAP];
+                std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
+                Image l_l = Image()
+                                    .SetWidth(width)
+                                    .SetHeight(height)
+                                    .SetSize((uint32_t)(image_size))
+                                    .SetFormat((uint32_t)(format));
+                if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
+                    data != nullptr) {
+                    l_l.mData =
+                            clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
+                }
+                CubemapLevel l_cube = l_t->mCubemap[level];
+                l_cube.mFaces[(uint32_t)(target)] = l_l;
+                l_t->mCubemap[level] = l_cube;
+                l_t->mKind = TextureKind::CUBEMAP;
+                l_t->mFormat = (uint32_t)(format);
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(115);  // Type ID -- TODO: mEncoder->Id(GL_COMPRESSED_TEX_IMAGE2D_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(level);
     mEncoder->Uint32(static_cast<uint32_t>(format));
@@ -1722,6 +3177,7 @@
     mEncoder->Int32(border);
     mEncoder->Int32(image_size);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glCompressedTexSubImage2D(uint32_t target, int32_t level, int32_t xoffset,
@@ -1730,10 +3186,12 @@
     GAPID_INFO("glCompressedTexSubImage2D()\n");
     mImports.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format,
                                        image_size, data);
-    mState.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format,
-                                     image_size, data);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(116);  // Type ID -- TODO: mEncoder->Id(GL_COMPRESSED_TEX_SUB_IMAGE2D_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(level);
     mEncoder->Int32(xoffset);
@@ -1743,14 +3201,18 @@
     mEncoder->Uint32(static_cast<uint32_t>(format));
     mEncoder->Int32(image_size);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGenerateMipmap(uint32_t target) {
     GAPID_INFO("glGenerateMipmap()\n");
     mImports.glGenerateMipmap(target);
-    mState.glGenerateMipmap(target);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(117);  // Type ID -- TODO: mEncoder->Id(GL_GENERATE_MIPMAP_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
 }
 
@@ -1758,9 +3220,14 @@
                                   uint32_t format, uint32_t type, void* data) {
     GAPID_INFO("glReadPixels()\n");
     mImports.glReadPixels(x, y, width, height, format, type, data);
-    mState.glReadPixels(x, y, width, height, format, type, data);
+
+    do {
+        write(slice(data, (uint64_t)(0), (uint64_t)(imageSize((uint32_t)(width), (uint32_t)(height),
+                                                              (uint32_t)(format), type))));
+    } while (false);
 
     mEncoder->Uint16(118);  // Type ID -- TODO: mEncoder->Id(GL_READ_PIXELS_ID);
+    encodeObservations();
     mEncoder->Int32(x);
     mEncoder->Int32(y);
     mEncoder->Int32(width);
@@ -1768,24 +3235,56 @@
     mEncoder->Uint32(static_cast<uint32_t>(format));
     mEncoder->Uint32(static_cast<uint32_t>(type));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGenFramebuffers(int32_t count, uint32_t* framebuffers) {
     GAPID_INFO("glGenFramebuffers()\n");
     mImports.glGenFramebuffers(count, framebuffers);
-    mState.glGenFramebuffers(count, framebuffers);
+
+    do {
+        Slice<FramebufferId> l_f = slice(framebuffers, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_68_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_68_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            FramebufferId l_id = (FramebufferId)(
+                    read(slice(framebuffers, (uint64_t)(0), (uint64_t)(count)), (uint64_t)(l_i)));
+            l_ctx->mInstances.mFramebuffers[l_id] =
+                    std::shared_ptr<Framebuffer>((new Framebuffer()));
+            write(l_f, (uint64_t)(l_i), l_id);
+        }
+    } while (false);
 
     mEncoder->Uint16(119);  // Type ID -- TODO: mEncoder->Id(GL_GEN_FRAMEBUFFERS_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(framebuffers));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glBindFramebuffer(uint32_t target, uint32_t framebuffer) {
     GAPID_INFO("glBindFramebuffer()\n");
     mImports.glBindFramebuffer(target, framebuffer);
-    mState.glBindFramebuffer(target, framebuffer);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_69_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_69_result;
+        if (!(l_ctx->mInstances.mFramebuffers.count(framebuffer) > 0)) {
+            l_ctx->mInstances.mFramebuffers[framebuffer] =
+                    std::shared_ptr<Framebuffer>((new Framebuffer()));
+        }
+        if (target == FramebufferTarget::GL_FRAMEBUFFER) {
+            l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = framebuffer;
+            l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = framebuffer;
+        } else {
+            l_ctx->mBoundFramebuffers[target] = framebuffer;
+        }
+    } while (false);
 
     mEncoder->Uint16(120);  // Type ID -- TODO: mEncoder->Id(GL_BIND_FRAMEBUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(framebuffer);
 }
@@ -1793,9 +3292,13 @@
 inline uint32_t GlesSpy::glCheckFramebufferStatus(uint32_t target) {
     GAPID_INFO("glCheckFramebufferStatus()\n");
     uint32_t result = mImports.glCheckFramebufferStatus(target);
-    mState.glCheckFramebufferStatus(target, result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(121);  // Type ID -- TODO: mEncoder->Id(GL_CHECK_FRAMEBUFFER_STATUS_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(result));
 
@@ -1805,19 +3308,38 @@
 inline void GlesSpy::glDeleteFramebuffers(int32_t count, uint32_t* framebuffers) {
     GAPID_INFO("glDeleteFramebuffers()\n");
     mImports.glDeleteFramebuffers(count, framebuffers);
-    mState.glDeleteFramebuffers(count, framebuffers);
+
+    do {
+        Slice<FramebufferId> l_f = slice(framebuffers, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_70_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_70_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            l_ctx->mInstances.mFramebuffers[read(l_f, (uint64_t)(l_i))] =
+                    std::shared_ptr<Framebuffer>();
+        }
+    } while (false);
 
     mEncoder->Uint16(122);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_FRAMEBUFFERS_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(framebuffers));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline bool GlesSpy::glIsFramebuffer(uint32_t framebuffer) {
     GAPID_INFO("glIsFramebuffer()\n");
     bool result = mImports.glIsFramebuffer(framebuffer);
-    mState.glIsFramebuffer(framebuffer, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_71_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_71_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(123);  // Type ID -- TODO: mEncoder->Id(GL_IS_FRAMEBUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(framebuffer);
     mEncoder->Bool(result);
 
@@ -1827,19 +3349,45 @@
 inline void GlesSpy::glGenRenderbuffers(int32_t count, uint32_t* renderbuffers) {
     GAPID_INFO("glGenRenderbuffers()\n");
     mImports.glGenRenderbuffers(count, renderbuffers);
-    mState.glGenRenderbuffers(count, renderbuffers);
+
+    do {
+        Slice<RenderbufferId> l_r = slice(renderbuffers, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_72_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_72_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            RenderbufferId l_id = (RenderbufferId)(
+                    read(slice(renderbuffers, (uint64_t)(0), (uint64_t)(count)), (uint64_t)(l_i)));
+            l_ctx->mInstances.mRenderbuffers[l_id] =
+                    std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+            write(l_r, (uint64_t)(l_i), l_id);
+        }
+    } while (false);
 
     mEncoder->Uint16(124);  // Type ID -- TODO: mEncoder->Id(GL_GEN_RENDERBUFFERS_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(renderbuffers));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glBindRenderbuffer(uint32_t target, uint32_t renderbuffer) {
     GAPID_INFO("glBindRenderbuffer()\n");
     mImports.glBindRenderbuffer(target, renderbuffer);
-    mState.glBindRenderbuffer(target, renderbuffer);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_73_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_73_result;
+        if (!(l_ctx->mInstances.mRenderbuffers.count(renderbuffer) > 0)) {
+            l_ctx->mInstances.mRenderbuffers[renderbuffer] =
+                    std::shared_ptr<Renderbuffer>((new Renderbuffer()));
+        }
+        l_ctx->mBoundRenderbuffers[target] = renderbuffer;
+    } while (false);
 
     mEncoder->Uint16(125);  // Type ID -- TODO: mEncoder->Id(GL_BIND_RENDERBUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(renderbuffer);
 }
@@ -1848,9 +3396,20 @@
                                            int32_t height) {
     GAPID_INFO("glRenderbufferStorage()\n");
     mImports.glRenderbufferStorage(target, format, width, height);
-    mState.glRenderbufferStorage(target, format, width, height);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_74_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_74_result;
+        RenderbufferId l_id = l_ctx->mBoundRenderbuffers[target];
+        std::shared_ptr<Renderbuffer> l_rb = l_ctx->mInstances.mRenderbuffers[l_id];
+        l_rb->mFormat = format;
+        l_rb->mWidth = width;
+        l_rb->mHeight = height;
+    } while (false);
 
     mEncoder->Uint16(126);  // Type ID -- TODO: mEncoder->Id(GL_RENDERBUFFER_STORAGE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(format));
     mEncoder->Int32(width);
@@ -1860,19 +3419,38 @@
 inline void GlesSpy::glDeleteRenderbuffers(int32_t count, uint32_t* renderbuffers) {
     GAPID_INFO("glDeleteRenderbuffers()\n");
     mImports.glDeleteRenderbuffers(count, renderbuffers);
-    mState.glDeleteRenderbuffers(count, renderbuffers);
+
+    do {
+        Slice<RenderbufferId> l_r = slice(renderbuffers, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_75_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_75_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            l_ctx->mInstances.mRenderbuffers[read(l_r, (uint64_t)(l_i))] =
+                    std::shared_ptr<Renderbuffer>();
+        }
+    } while (false);
 
     mEncoder->Uint16(127);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_RENDERBUFFERS_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(renderbuffers));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline bool GlesSpy::glIsRenderbuffer(uint32_t renderbuffer) {
     GAPID_INFO("glIsRenderbuffer()\n");
     bool result = mImports.glIsRenderbuffer(renderbuffer);
-    mState.glIsRenderbuffer(renderbuffer, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_76_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_76_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(128);  // Type ID -- TODO: mEncoder->Id(GL_IS_RENDERBUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(renderbuffer);
     mEncoder->Bool(result);
 
@@ -1883,30 +3461,69 @@
                                                   int32_t* values) {
     GAPID_INFO("glGetRenderbufferParameteriv()\n");
     mImports.glGetRenderbufferParameteriv(target, parameter, values);
-    mState.glGetRenderbufferParameteriv(target, parameter, values);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_77_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_77_result;
+        RenderbufferId l_id = l_ctx->mBoundRenderbuffers[target];
+        std::shared_ptr<Renderbuffer> l_rb = l_ctx->mInstances.mRenderbuffers[l_id];
+        write(slice(values, 0, 1), 0, /* clang-format off */
+        /* switch(parameter) */
+            /* case RenderbufferParameter::GL_RENDERBUFFER_WIDTH: */(((parameter) == (RenderbufferParameter::GL_RENDERBUFFER_WIDTH))) ? (l_rb->mWidth) :
+            /* case RenderbufferParameter::GL_RENDERBUFFER_HEIGHT: */(((parameter) == (RenderbufferParameter::GL_RENDERBUFFER_HEIGHT))) ? (l_rb->mHeight) :
+            /* case RenderbufferParameter::GL_RENDERBUFFER_INTERNAL_FORMAT: */(((parameter) == (RenderbufferParameter::GL_RENDERBUFFER_INTERNAL_FORMAT))) ? ((int32_t)(l_rb->mFormat)) :
+            /* default: */ 0 /* clang-format on */);
+    } while (false);
 
     mEncoder->Uint16(129);  // Type ID -- TODO: mEncoder->Id(GL_GET_RENDERBUFFER_PARAMETERIV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGenBuffers(int32_t count, uint32_t* buffers) {
     GAPID_INFO("glGenBuffers()\n");
     mImports.glGenBuffers(count, buffers);
-    mState.glGenBuffers(count, buffers);
+
+    do {
+        Slice<BufferId> l_b = slice(buffers, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_78_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_78_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            BufferId l_id = (BufferId)(
+                    read(slice(buffers, (uint64_t)(0), (uint64_t)(count)), (uint64_t)(l_i)));
+            l_ctx->mInstances.mBuffers[l_id] = std::shared_ptr<Buffer>((new Buffer()));
+            write(l_b, (uint64_t)(l_i), l_id);
+        }
+    } while (false);
 
     mEncoder->Uint16(130);  // Type ID -- TODO: mEncoder->Id(GL_GEN_BUFFERS_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(buffers));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glBindBuffer(uint32_t target, uint32_t buffer) {
     GAPID_INFO("glBindBuffer()\n");
     mImports.glBindBuffer(target, buffer);
-    mState.glBindBuffer(target, buffer);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_79_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_79_result;
+        if (!(l_ctx->mInstances.mBuffers.count(buffer) > 0)) {
+            l_ctx->mInstances.mBuffers[buffer] = std::shared_ptr<Buffer>((new Buffer()));
+        }
+        l_ctx->mBoundBuffers[target] = buffer;
+    } while (false);
 
     mEncoder->Uint16(131);  // Type ID -- TODO: mEncoder->Id(GL_BIND_BUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(buffer);
 }
@@ -1914,43 +3531,82 @@
 inline void GlesSpy::glBufferData(uint32_t target, int32_t size, void* data, uint32_t usage) {
     GAPID_INFO("glBufferData()\n");
     mImports.glBufferData(target, size, data, usage);
-    mState.glBufferData(target, size, data, usage);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_80_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_80_result;
+        BufferId l_id = l_ctx->mBoundBuffers[target];
+        std::shared_ptr<Buffer> l_b = l_ctx->mInstances.mBuffers[l_id];
+        l_b->mData = /* clang-format off */
+        /* switch(data != nullptr) */
+            /* case true: */(((data != nullptr) == (true))) ? (clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(size)))) :
+            /* case false: */(((data != nullptr) == (false))) ? (make<uint8_t>((uint64_t)(size))) :
+            /* default: */ Slice<uint8_t>() /* clang-format on */;
+        l_b->mSize = size;
+        l_b->mUsage = usage;
+    } while (false);
 
     mEncoder->Uint16(132);  // Type ID -- TODO: mEncoder->Id(GL_BUFFER_DATA_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(size);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint32(static_cast<uint32_t>(usage));
 }
 
 inline void GlesSpy::glBufferSubData(uint32_t target, int32_t offset, int32_t size, void* data) {
     GAPID_INFO("glBufferSubData()\n");
     mImports.glBufferSubData(target, offset, size, data);
-    mState.glBufferSubData(target, offset, size, data);
+
+    do {
+        read(slice(data, (uint64_t)(0), (uint64_t)(size)));
+    } while (false);
 
     mEncoder->Uint16(133);  // Type ID -- TODO: mEncoder->Id(GL_BUFFER_SUB_DATA_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(offset);
     mEncoder->Int32(size);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(data));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glDeleteBuffers(int32_t count, uint32_t* buffers) {
     GAPID_INFO("glDeleteBuffers()\n");
     mImports.glDeleteBuffers(count, buffers);
-    mState.glDeleteBuffers(count, buffers);
+
+    do {
+        Slice<BufferId> l_b = slice(buffers, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_81_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_81_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            l_ctx->mInstances.mBuffers[read(l_b, (uint64_t)(l_i))] = std::shared_ptr<Buffer>();
+        }
+    } while (false);
 
     mEncoder->Uint16(134);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_BUFFERS_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(buffers));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline bool GlesSpy::glIsBuffer(uint32_t buffer) {
     GAPID_INFO("glIsBuffer()\n");
     bool result = mImports.glIsBuffer(buffer);
-    mState.glIsBuffer(buffer, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_82_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_82_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(135);  // Type ID -- TODO: mEncoder->Id(GL_IS_BUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(buffer);
     mEncoder->Bool(result);
 
@@ -1960,20 +3616,45 @@
 inline void GlesSpy::glGetBufferParameteriv(uint32_t target, uint32_t parameter, int32_t* value) {
     GAPID_INFO("glGetBufferParameteriv()\n");
     mImports.glGetBufferParameteriv(target, parameter, value);
-    mState.glGetBufferParameteriv(target, parameter, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_83_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_83_result;
+        BufferId l_id = l_ctx->mBoundBuffers[target];
+        std::shared_ptr<Buffer> l_b = l_ctx->mInstances.mBuffers[l_id];
+        write(slice(value, 0, 1), 0, /* clang-format off */
+        /* switch(parameter) */
+            /* case BufferParameter::GL_BUFFER_SIZE: */(((parameter) == (BufferParameter::GL_BUFFER_SIZE))) ? (l_b->mSize) :
+            /* case BufferParameter::GL_BUFFER_USAGE: */(((parameter) == (BufferParameter::GL_BUFFER_USAGE))) ? ((int32_t)(l_b->mUsage)) :
+            /* default: */ 0 /* clang-format on */);
+    } while (false);
 
     mEncoder->Uint16(136);  // Type ID -- TODO: mEncoder->Id(GL_GET_BUFFER_PARAMETERIV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline uint32_t GlesSpy::glCreateShader(uint32_t type) {
     GAPID_INFO("glCreateShader()\n");
     uint32_t result = mImports.glCreateShader(type);
-    mState.glCreateShader(type, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_84_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_84_result;
+        ShaderId l_id = (ShaderId)(result);
+        l_ctx->mInstances.mShaders[l_id] = std::shared_ptr<Shader>((new Shader()));
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[l_id];
+        l_s->mType = type;
+        break;
+    } while (false);
 
     mEncoder->Uint16(137);  // Type ID -- TODO: mEncoder->Id(GL_CREATE_SHADER_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(type));
     mEncoder->Uint32(result);
 
@@ -1983,9 +3664,18 @@
 inline void GlesSpy::glDeleteShader(uint32_t shader) {
     GAPID_INFO("glDeleteShader()\n");
     mImports.glDeleteShader(shader);
-    mState.glDeleteShader(shader);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_85_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_85_result;
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
+        l_s->mDeletable = true;
+        l_ctx->mInstances.mShaders[shader] = std::shared_ptr<Shader>();
+    } while (false);
 
     mEncoder->Uint16(138);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_SHADER_ID);
+    encodeObservations();
     mEncoder->Uint32(shader);
 }
 
@@ -1993,26 +3683,53 @@
                                     int32_t* length) {
     GAPID_INFO("glShaderSource()\n");
     mImports.glShaderSource(shader, count, source, length);
-    mState.glShaderSource(shader, count, source, length);
+
+    do {
+        Slice<char*> l_sources = slice(source, (uint64_t)(0), (uint64_t)(count));
+        Slice<int32_t> l_lengths = slice(length, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_86_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_86_result;
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            uint32_t l_l = /* clang-format off */
+            /* switch(length == nullptr || read(l_lengths, (uint64_t)(l_i)) < 0) */
+                /* case true: */(((length == nullptr || read(l_lengths, (uint64_t)(l_i)) < 0) == (true))) ? (strlen(read(l_sources, (uint64_t)(l_i)))) :
+                /* case false: */(((length == nullptr || read(l_lengths, (uint64_t)(l_i)) < 0) == (false))) ? ((uint32_t)(read(l_lengths, (uint64_t)(l_i)))) :
+                /* default: */ 0 /* clang-format on */;
+            l_s->mSource +=
+                    string(slice(read(l_sources, (uint64_t)(l_i)), (uint64_t)(0), (uint64_t)(l_l)));
+        }
+    } while (false);
 
     mEncoder->Uint16(139);  // Type ID -- TODO: mEncoder->Id(GL_SHADER_SOURCE_ID);
+    encodeObservations();
     mEncoder->Uint32(shader);
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(source));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(length));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glShaderBinary(int32_t count, uint32_t* shaders, uint32_t binary_format,
                                     void* binary, int32_t binary_size) {
     GAPID_INFO("glShaderBinary()\n");
     mImports.glShaderBinary(count, shaders, binary_format, binary, binary_size);
-    mState.glShaderBinary(count, shaders, binary_format, binary, binary_size);
+
+    do {
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+        }
+    } while (false);
 
     mEncoder->Uint16(140);  // Type ID -- TODO: mEncoder->Id(GL_SHADER_BINARY_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(shaders));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint32(binary_format);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(binary));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Int32(binary_size);
 }
 
@@ -2020,51 +3737,104 @@
                                         int32_t* string_length_written, char* info) {
     GAPID_INFO("glGetShaderInfoLog()\n");
     mImports.glGetShaderInfoLog(shader, buffer_length, string_length_written, info);
-    mState.glGetShaderInfoLog(shader, buffer_length, string_length_written, info);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_87_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_87_result;
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
+        int32_t l_min_88_a = buffer_length;
+        int32_t l_min_88_b = (int32_t)(strlen(l_s->mInfoLog));
+        int32_t l_min_88_result = /* clang-format off */
+        /* switch(l_min_88_a < l_min_88_b) */
+            /* case true: */(((l_min_88_a < l_min_88_b) == (true))) ? (l_min_88_a) :
+            /* case false: */(((l_min_88_a < l_min_88_b) == (false))) ? (l_min_88_b) :
+            /* default: */ 0 /* clang-format on */;
+        int32_t l_l = l_min_88_result;
+        write(slice(string_length_written, 0, 1), 0, l_l);
+        copy(slice(info, (uint64_t)(0), (uint64_t)(l_l)),
+             slice(l_s->mInfoLog, (uint64_t)(0), (uint64_t)(l_l)));
+    } while (false);
 
     mEncoder->Uint16(141);  // Type ID -- TODO: mEncoder->Id(GL_GET_SHADER_INFO_LOG_ID);
+    encodeObservations();
     mEncoder->Uint32(shader);
     mEncoder->Int32(buffer_length);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(string_length_written));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(info));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetShaderSource(uint32_t shader, int32_t buffer_length,
                                        int32_t* string_length_written, char* source) {
     GAPID_INFO("glGetShaderSource()\n");
     mImports.glGetShaderSource(shader, buffer_length, string_length_written, source);
-    mState.glGetShaderSource(shader, buffer_length, string_length_written, source);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_89_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_89_result;
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
+        int32_t l_min_90_a = buffer_length;
+        int32_t l_min_90_b = (int32_t)(strlen(l_s->mSource));
+        int32_t l_min_90_result = /* clang-format off */
+        /* switch(l_min_90_a < l_min_90_b) */
+            /* case true: */(((l_min_90_a < l_min_90_b) == (true))) ? (l_min_90_a) :
+            /* case false: */(((l_min_90_a < l_min_90_b) == (false))) ? (l_min_90_b) :
+            /* default: */ 0 /* clang-format on */;
+        int32_t l_l = l_min_90_result;
+        write(slice(string_length_written, 0, 1), 0, l_l);
+        copy(slice(source, (uint64_t)(0), (uint64_t)(l_l)),
+             slice(slice(l_s->mSource), (uint64_t)(0), (uint64_t)(l_l)));
+    } while (false);
 
     mEncoder->Uint16(142);  // Type ID -- TODO: mEncoder->Id(GL_GET_SHADER_SOURCE_ID);
+    encodeObservations();
     mEncoder->Uint32(shader);
     mEncoder->Int32(buffer_length);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(string_length_written));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(source));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glReleaseShaderCompiler() {
     GAPID_INFO("glReleaseShaderCompiler()\n");
     mImports.glReleaseShaderCompiler();
-    mState.glReleaseShaderCompiler();
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(143);  // Type ID -- TODO: mEncoder->Id(GL_RELEASE_SHADER_COMPILER_ID);
+    encodeObservations();
 }
 
 inline void GlesSpy::glCompileShader(uint32_t shader) {
     GAPID_INFO("glCompileShader()\n");
     mImports.glCompileShader(shader);
-    mState.glCompileShader(shader);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(144);  // Type ID -- TODO: mEncoder->Id(GL_COMPILE_SHADER_ID);
+    encodeObservations();
     mEncoder->Uint32(shader);
 }
 
 inline bool GlesSpy::glIsShader(uint32_t shader) {
     GAPID_INFO("glIsShader()\n");
     bool result = mImports.glIsShader(shader);
-    mState.glIsShader(shader, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_91_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_91_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(145);  // Type ID -- TODO: mEncoder->Id(GL_IS_SHADER_ID);
+    encodeObservations();
     mEncoder->Uint32(shader);
     mEncoder->Bool(result);
 
@@ -2074,9 +3844,18 @@
 inline uint32_t GlesSpy::glCreateProgram() {
     GAPID_INFO("glCreateProgram()\n");
     uint32_t result = mImports.glCreateProgram();
-    mState.glCreateProgram(result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_92_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_92_result;
+        ProgramId l_id = (ProgramId)(result);
+        l_ctx->mInstances.mPrograms[l_id] = std::shared_ptr<Program>((new Program()));
+        break;
+    } while (false);
 
     mEncoder->Uint16(146);  // Type ID -- TODO: mEncoder->Id(GL_CREATE_PROGRAM_ID);
+    encodeObservations();
     mEncoder->Uint32(result);
 
     return result;
@@ -2085,18 +3864,34 @@
 inline void GlesSpy::glDeleteProgram(uint32_t program) {
     GAPID_INFO("glDeleteProgram()\n");
     mImports.glDeleteProgram(program);
-    mState.glDeleteProgram(program);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_93_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_93_result;
+        l_ctx->mInstances.mPrograms[program] = std::shared_ptr<Program>();
+    } while (false);
 
     mEncoder->Uint16(147);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_PROGRAM_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
 }
 
 inline void GlesSpy::glAttachShader(uint32_t program, uint32_t shader) {
     GAPID_INFO("glAttachShader()\n");
     mImports.glAttachShader(program, shader);
-    mState.glAttachShader(program, shader);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_94_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_94_result;
+        std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
+        l_p->mShaders[l_s->mType] = shader;
+    } while (false);
 
     mEncoder->Uint16(148);  // Type ID -- TODO: mEncoder->Id(GL_ATTACH_SHADER_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Uint32(shader);
 }
@@ -2104,9 +3899,18 @@
 inline void GlesSpy::glDetachShader(uint32_t program, uint32_t shader) {
     GAPID_INFO("glDetachShader()\n");
     mImports.glDetachShader(program, shader);
-    mState.glDetachShader(program, shader);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_95_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_95_result;
+        std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
+        std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
+        l_p->mShaders[l_s->mType] = 0;
+    } while (false);
 
     mEncoder->Uint16(149);  // Type ID -- TODO: mEncoder->Id(GL_DETACH_SHADER_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Uint32(shader);
 }
@@ -2115,21 +3919,42 @@
                                           int32_t* shaders_length_written, uint32_t* shaders) {
     GAPID_INFO("glGetAttachedShaders()\n");
     mImports.glGetAttachedShaders(program, buffer_length, shaders_length_written, shaders);
-    mState.glGetAttachedShaders(program, buffer_length, shaders_length_written, shaders);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_96_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_96_result;
+        std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
+        int32_t l_min_97_a = buffer_length;
+        int32_t l_min_97_b = l_p->mShaders.size();
+        int32_t l_min_97_result = /* clang-format off */
+        /* switch(l_min_97_a < l_min_97_b) */
+            /* case true: */(((l_min_97_a < l_min_97_b) == (true))) ? (l_min_97_a) :
+            /* case false: */(((l_min_97_a < l_min_97_b) == (false))) ? (l_min_97_b) :
+            /* default: */ 0 /* clang-format on */;
+        int32_t l_l = l_min_97_result;
+        write(slice(shaders_length_written, 0, 1), 0, l_l);
+    } while (false);
 
     mEncoder->Uint16(150);  // Type ID -- TODO: mEncoder->Id(GL_GET_ATTACHED_SHADERS_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Int32(buffer_length);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(shaders_length_written));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(shaders));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glLinkProgram(uint32_t program) {
     GAPID_INFO("glLinkProgram()\n");
     mImports.glLinkProgram(program);
-    mState.glLinkProgram(program);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(151);  // Type ID -- TODO: mEncoder->Id(GL_LINK_PROGRAM_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
 }
 
@@ -2137,30 +3962,64 @@
                                          int32_t* string_length_written, char* info) {
     GAPID_INFO("glGetProgramInfoLog()\n");
     mImports.glGetProgramInfoLog(program, buffer_length, string_length_written, info);
-    mState.glGetProgramInfoLog(program, buffer_length, string_length_written, info);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_98_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_98_result;
+        std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
+        int32_t l_min_99_a = buffer_length;
+        int32_t l_min_99_b = (int32_t)(strlen(l_p->mInfoLog));
+        int32_t l_min_99_result = /* clang-format off */
+        /* switch(l_min_99_a < l_min_99_b) */
+            /* case true: */(((l_min_99_a < l_min_99_b) == (true))) ? (l_min_99_a) :
+            /* case false: */(((l_min_99_a < l_min_99_b) == (false))) ? (l_min_99_b) :
+            /* default: */ 0 /* clang-format on */;
+        int32_t l_l = l_min_99_result;
+        write(slice(string_length_written, 0, 1), 0, l_l);
+        copy(slice(info, (uint64_t)(0), (uint64_t)(l_l)),
+             slice(l_p->mInfoLog, (uint64_t)(0), (uint64_t)(l_l)));
+    } while (false);
 
     mEncoder->Uint16(152);  // Type ID -- TODO: mEncoder->Id(GL_GET_PROGRAM_INFO_LOG_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Int32(buffer_length);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(string_length_written));
+    mEncoder->Uint32(0);  // PoolID
     mEncoder->Uint64(reinterpret_cast<uint64_t>(info));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glUseProgram(uint32_t program) {
     GAPID_INFO("glUseProgram()\n");
     mImports.glUseProgram(program);
-    mState.glUseProgram(program);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_100_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_100_result;
+        l_ctx->mBoundProgram = program;
+    } while (false);
 
     mEncoder->Uint16(153);  // Type ID -- TODO: mEncoder->Id(GL_USE_PROGRAM_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
 }
 
 inline bool GlesSpy::glIsProgram(uint32_t program) {
     GAPID_INFO("glIsProgram()\n");
     bool result = mImports.glIsProgram(program);
-    mState.glIsProgram(program, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_101_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_101_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(154);  // Type ID -- TODO: mEncoder->Id(GL_IS_PROGRAM_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
     mEncoder->Bool(result);
 
@@ -2170,18 +4029,28 @@
 inline void GlesSpy::glValidateProgram(uint32_t program) {
     GAPID_INFO("glValidateProgram()\n");
     mImports.glValidateProgram(program);
-    mState.glValidateProgram(program);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(155);  // Type ID -- TODO: mEncoder->Id(GL_VALIDATE_PROGRAM_ID);
+    encodeObservations();
     mEncoder->Uint32(program);
 }
 
 inline void GlesSpy::glClearColor(float r, float g, float b, float a) {
     GAPID_INFO("glClearColor()\n");
     mImports.glClearColor(r, g, b, a);
-    mState.glClearColor(r, g, b, a);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_102_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_102_result;
+        l_ctx->mClearing.mClearColor = Color().SetRed(r).SetGreen(g).SetBlue(b).SetAlpha(a);
+    } while (false);
 
     mEncoder->Uint16(156);  // Type ID -- TODO: mEncoder->Id(GL_CLEAR_COLOR_ID);
+    encodeObservations();
     mEncoder->Float32(r);
     mEncoder->Float32(g);
     mEncoder->Float32(b);
@@ -2191,45 +4060,79 @@
 inline void GlesSpy::glClearDepthf(float depth) {
     GAPID_INFO("glClearDepthf()\n");
     mImports.glClearDepthf(depth);
-    mState.glClearDepthf(depth);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_103_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_103_result;
+        l_ctx->mClearing.mClearDepth = depth;
+    } while (false);
 
     mEncoder->Uint16(157);  // Type ID -- TODO: mEncoder->Id(GL_CLEAR_DEPTHF_ID);
+    encodeObservations();
     mEncoder->Float32(depth);
 }
 
 inline void GlesSpy::glClearStencil(int32_t stencil) {
     GAPID_INFO("glClearStencil()\n");
     mImports.glClearStencil(stencil);
-    mState.glClearStencil(stencil);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_104_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_104_result;
+        l_ctx->mClearing.mClearStencil = stencil;
+    } while (false);
 
     mEncoder->Uint16(158);  // Type ID -- TODO: mEncoder->Id(GL_CLEAR_STENCIL_ID);
+    encodeObservations();
     mEncoder->Int32(stencil);
 }
 
 inline void GlesSpy::glClear(uint32_t mask) {
     GAPID_INFO("glClear()\n");
     mImports.glClear(mask);
-    mState.glClear(mask);
+
+    do {
+        if ((mask & ClearMask::GL_COLOR_BUFFER_BIT) != 0) {
+        }
+    } while (false);
 
     mEncoder->Uint16(159);  // Type ID -- TODO: mEncoder->Id(GL_CLEAR_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(mask));
 }
 
 inline void GlesSpy::glCullFace(uint32_t mode) {
     GAPID_INFO("glCullFace()\n");
     mImports.glCullFace(mode);
-    mState.glCullFace(mode);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_105_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_105_result;
+        l_ctx->mRasterizing.mCullFace = mode;
+    } while (false);
 
     mEncoder->Uint16(160);  // Type ID -- TODO: mEncoder->Id(GL_CULL_FACE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(mode));
 }
 
 inline void GlesSpy::glPolygonOffset(float scale_factor, float units) {
     GAPID_INFO("glPolygonOffset()\n");
     mImports.glPolygonOffset(scale_factor, units);
-    mState.glPolygonOffset(scale_factor, units);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_106_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_106_result;
+        l_ctx->mRasterizing.mPolygonOffsetUnits = units;
+        l_ctx->mRasterizing.mPolygonOffsetFactor = scale_factor;
+    } while (false);
 
     mEncoder->Uint16(161);  // Type ID -- TODO: mEncoder->Id(GL_POLYGON_OFFSET_ID);
+    encodeObservations();
     mEncoder->Float32(scale_factor);
     mEncoder->Float32(units);
 }
@@ -2237,18 +4140,33 @@
 inline void GlesSpy::glLineWidth(float width) {
     GAPID_INFO("glLineWidth()\n");
     mImports.glLineWidth(width);
-    mState.glLineWidth(width);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_107_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_107_result;
+        l_ctx->mRasterizing.mLineWidth = width;
+    } while (false);
 
     mEncoder->Uint16(162);  // Type ID -- TODO: mEncoder->Id(GL_LINE_WIDTH_ID);
+    encodeObservations();
     mEncoder->Float32(width);
 }
 
 inline void GlesSpy::glSampleCoverage(float value, bool invert) {
     GAPID_INFO("glSampleCoverage()\n");
     mImports.glSampleCoverage(value, invert);
-    mState.glSampleCoverage(value, invert);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_108_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_108_result;
+        l_ctx->mRasterizing.mSampleCoverageValue = value;
+        l_ctx->mRasterizing.mSampleCoverageInvert = invert;
+    } while (false);
 
     mEncoder->Uint16(163);  // Type ID -- TODO: mEncoder->Id(GL_SAMPLE_COVERAGE_ID);
+    encodeObservations();
     mEncoder->Float32(value);
     mEncoder->Bool(invert);
 }
@@ -2256,9 +4174,16 @@
 inline void GlesSpy::glHint(uint32_t target, uint32_t mode) {
     GAPID_INFO("glHint()\n");
     mImports.glHint(target, mode);
-    mState.glHint(target, mode);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_109_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_109_result;
+        l_ctx->mGenerateMipmapHint = mode;
+    } while (false);
 
     mEncoder->Uint16(164);  // Type ID -- TODO: mEncoder->Id(GL_HINT_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(mode));
 }
@@ -2270,10 +4195,35 @@
     GAPID_INFO("glFramebufferRenderbuffer()\n");
     mImports.glFramebufferRenderbuffer(framebuffer_target, framebuffer_attachment,
                                        renderbuffer_target, renderbuffer);
-    mState.glFramebufferRenderbuffer(framebuffer_target, framebuffer_attachment,
-                                     renderbuffer_target, renderbuffer);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_110_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_110_result;
+        uint32_t l_target = /* clang-format off */
+        /* switch(framebuffer_target) */
+            /* case FramebufferTarget::GL_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
+            /* case FramebufferTarget::GL_DRAW_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_DRAW_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
+            /* case FramebufferTarget::GL_READ_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_READ_FRAMEBUFFER))) ? (FramebufferTarget::GL_READ_FRAMEBUFFER) :
+            /* default: */ 0 /* clang-format on */;
+        FramebufferId l_framebufferId = l_ctx->mBoundFramebuffers[l_target];
+        std::shared_ptr<Framebuffer> l_framebuffer =
+                l_ctx->mInstances.mFramebuffers[l_framebufferId];
+        FramebufferAttachmentInfo l_attachment =
+                l_framebuffer->mAttachments[framebuffer_attachment];
+        if (renderbuffer == (RenderbufferId)(0)) {
+            l_attachment.mType = FramebufferAttachmentType::GL_NONE;
+        } else {
+            l_attachment.mType = FramebufferAttachmentType::GL_RENDERBUFFER;
+        }
+        l_attachment.mObject = (uint32_t)(renderbuffer);
+        l_attachment.mTextureLevel = 0;
+        l_attachment.mCubeMapFace = CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+        l_framebuffer->mAttachments[framebuffer_attachment] = l_attachment;
+    } while (false);
 
     mEncoder->Uint16(165);  // Type ID -- TODO: mEncoder->Id(GL_FRAMEBUFFER_RENDERBUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(framebuffer_target));
     mEncoder->Uint32(static_cast<uint32_t>(framebuffer_attachment));
     mEncoder->Uint32(static_cast<uint32_t>(renderbuffer_target));
@@ -2287,10 +4237,47 @@
     GAPID_INFO("glFramebufferTexture2D()\n");
     mImports.glFramebufferTexture2D(framebuffer_target, framebuffer_attachment, texture_target,
                                     texture, level);
-    mState.glFramebufferTexture2D(framebuffer_target, framebuffer_attachment, texture_target,
-                                  texture, level);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_111_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_111_result;
+        uint32_t l_target = /* clang-format off */
+        /* switch(framebuffer_target) */
+            /* case FramebufferTarget::GL_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
+            /* case FramebufferTarget::GL_DRAW_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_DRAW_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
+            /* case FramebufferTarget::GL_READ_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_READ_FRAMEBUFFER))) ? (FramebufferTarget::GL_READ_FRAMEBUFFER) :
+            /* default: */ 0 /* clang-format on */;
+        FramebufferId l_framebufferId = l_ctx->mBoundFramebuffers[l_target];
+        std::shared_ptr<Framebuffer> l_framebuffer =
+                l_ctx->mInstances.mFramebuffers[l_framebufferId];
+        FramebufferAttachmentInfo l_attachment =
+                l_framebuffer->mAttachments[framebuffer_attachment];
+        if (texture == (TextureId)(0)) {
+            l_attachment.mType = FramebufferAttachmentType::GL_NONE;
+            l_attachment.mObject = 0;
+            l_attachment.mTextureLevel = 0;
+            l_attachment.mCubeMapFace = CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+        } else {
+            l_attachment.mType = FramebufferAttachmentType::GL_TEXTURE;
+            l_attachment.mObject = (uint32_t)(texture);
+            l_attachment.mTextureLevel = level;
+            l_attachment.mCubeMapFace = /* clang-format off */
+            /* switch(texture_target) */
+                /* case TextureImageTarget::GL_TEXTURE_2D: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_2D))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X) :
+                /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X) :
+                /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y) :
+                /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z) :
+                /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X) :
+                /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) :
+                /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) :
+                /* default: */ 0 /* clang-format on */;
+        }
+        l_framebuffer->mAttachments[framebuffer_attachment] = l_attachment;
+    } while (false);
 
     mEncoder->Uint16(166);  // Type ID -- TODO: mEncoder->Id(GL_FRAMEBUFFER_TEXTURE2D_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(framebuffer_target));
     mEncoder->Uint32(static_cast<uint32_t>(framebuffer_attachment));
     mEncoder->Uint32(static_cast<uint32_t>(texture_target));
@@ -2304,35 +4291,198 @@
     GAPID_INFO("glGetFramebufferAttachmentParameteriv()\n");
     mImports.glGetFramebufferAttachmentParameteriv(framebuffer_target, attachment, parameter,
                                                    value);
-    mState.glGetFramebufferAttachmentParameteriv(framebuffer_target, attachment, parameter, value);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_112_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_112_result;
+        uint32_t l_target = /* clang-format off */
+        /* switch(framebuffer_target) */
+            /* case FramebufferTarget::GL_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
+            /* case FramebufferTarget::GL_DRAW_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_DRAW_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
+            /* case FramebufferTarget::GL_READ_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_READ_FRAMEBUFFER))) ? (FramebufferTarget::GL_READ_FRAMEBUFFER) :
+            /* default: */ 0 /* clang-format on */;
+        FramebufferId l_framebufferId = l_ctx->mBoundFramebuffers[l_target];
+        std::shared_ptr<Framebuffer> l_framebuffer =
+                l_ctx->mInstances.mFramebuffers[l_framebufferId];
+        FramebufferAttachmentInfo l_a = l_framebuffer->mAttachments[attachment];
+        write(slice(value, 0, 1), 0, /* clang-format off */
+        /* switch(parameter) */
+            /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE))) ? ((int32_t)(l_a.mType)) :
+            /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME))) ? ((int32_t)(l_a.mObject)) :
+            /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL))) ? (l_a.mTextureLevel) :
+            /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE))) ? ((int32_t)(l_a.mCubeMapFace)) :
+            /* default: */ 0 /* clang-format on */);
+    } while (false);
 
     mEncoder->Uint16(
             167);  // Type ID -- TODO: mEncoder->Id(GL_GET_FRAMEBUFFER_ATTACHMENT_PARAMETERIV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(framebuffer_target));
     mEncoder->Uint32(static_cast<uint32_t>(attachment));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glDrawElements(uint32_t draw_mode, int32_t element_count,
                                     uint32_t indices_type, void* indices) {
     GAPID_INFO("glDrawElements()\n");
     mImports.glDrawElements(draw_mode, element_count, indices_type, indices);
-    mState.glDrawElements(draw_mode, element_count, indices_type, indices);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_113_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_113_result;
+        uint32_t l_count = (uint32_t)(element_count);
+        BufferId l_id = l_ctx->mBoundBuffers[BufferTarget::GL_ELEMENT_ARRAY_BUFFER];
+        if (l_id != (BufferId)(0)) {
+            Slice<uint8_t> l_index_data = l_ctx->mInstances.mBuffers[l_id]->mData;
+            uint32_t l_offset = (uint32_t)((uint64_t)(indices));
+            uint32_t l_first = minIndex(l_index_data.begin(), indices_type, l_offset, l_count);
+            uint32_t l_last = maxIndex(l_index_data.begin(), indices_type, l_offset, l_count);
+            std::shared_ptr<Context> l_ReadVertexArrays_114_ctx = l_ctx;
+            uint32_t l_ReadVertexArrays_114_first_index = l_first;
+            uint32_t l_ReadVertexArrays_114_last_index = l_last;
+            for (int32_t l_i = 0; l_i < l_ReadVertexArrays_114_ctx->mVertexAttributeArrays.size();
+                 ++l_i) {
+                std::shared_ptr<VertexAttributeArray> l_arr =
+                        l_ReadVertexArrays_114_ctx
+                                ->mVertexAttributeArrays[(AttributeLocation)(l_i)];
+                if (l_arr->mEnabled && l_arr->mBuffer == (BufferId)(0)) {
+                    uint32_t l_vertexAttribTypeSize_115_t = l_arr->mType;
+                    uint32_t l_vertexAttribTypeSize_115_result = /* clang-format off */
+                    /* switch(l_vertexAttribTypeSize_115_t) */
+                        /* case VertexAttribType::GL_BYTE: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_BYTE))) ? (1) :
+                        /* case VertexAttribType::GL_UNSIGNED_BYTE: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_UNSIGNED_BYTE))) ? (1) :
+                        /* case VertexAttribType::GL_SHORT: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_SHORT))) ? (2) :
+                        /* case VertexAttribType::GL_UNSIGNED_SHORT: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_UNSIGNED_SHORT))) ? (2) :
+                        /* case VertexAttribType::GL_FIXED: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_FIXED))) ? (4) :
+                        /* case VertexAttribType::GL_FLOAT: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_FLOAT))) ? (4) :
+                        /* case VertexAttribType::GL_ARB_half_float_vertex: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_ARB_half_float_vertex))) ? (2) :
+                        /* case VertexAttribType::GL_HALF_FLOAT_OES: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_HALF_FLOAT_OES))) ? (2) :
+                        /* default: */ 0 /* clang-format on */;
+                    uint32_t l_elsize = l_vertexAttribTypeSize_115_result * l_arr->mSize;
+                    uint32_t l_elstride = /* clang-format off */
+                    /* switch(l_arr->mStride == 0) */
+                        /* case true: */(((l_arr->mStride == 0) == (true))) ? (l_elsize) :
+                        /* case false: */(((l_arr->mStride == 0) == (false))) ? ((uint32_t)(l_arr->mStride)) :
+                        /* default: */ 0 /* clang-format on */;
+                    for (uint32_t l_v = l_ReadVertexArrays_114_first_index;
+                         l_v < l_ReadVertexArrays_114_last_index + 1; ++l_v) {
+                        uint32_t l_offset = l_elstride * l_v;
+                        read(slice(l_arr->mPointer, (uint64_t)(l_offset),
+                                   (uint64_t)(l_offset + l_elsize)));
+                    }
+                }
+            }
+        } else {
+            uint8_t* l_index_data = (uint8_t*)(indices);
+            uint32_t l_first = minIndex(l_index_data, indices_type, 0, l_count);
+            uint32_t l_last = maxIndex(l_index_data, indices_type, 0, l_count);
+            std::shared_ptr<Context> l_ReadVertexArrays_116_ctx = l_ctx;
+            uint32_t l_ReadVertexArrays_116_first_index = l_first;
+            uint32_t l_ReadVertexArrays_116_last_index = l_last;
+            for (int32_t l_i = 0; l_i < l_ReadVertexArrays_116_ctx->mVertexAttributeArrays.size();
+                 ++l_i) {
+                std::shared_ptr<VertexAttributeArray> l_arr =
+                        l_ReadVertexArrays_116_ctx
+                                ->mVertexAttributeArrays[(AttributeLocation)(l_i)];
+                if (l_arr->mEnabled && l_arr->mBuffer == (BufferId)(0)) {
+                    uint32_t l_vertexAttribTypeSize_117_t = l_arr->mType;
+                    uint32_t l_vertexAttribTypeSize_117_result = /* clang-format off */
+                    /* switch(l_vertexAttribTypeSize_117_t) */
+                        /* case VertexAttribType::GL_BYTE: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_BYTE))) ? (1) :
+                        /* case VertexAttribType::GL_UNSIGNED_BYTE: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_UNSIGNED_BYTE))) ? (1) :
+                        /* case VertexAttribType::GL_SHORT: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_SHORT))) ? (2) :
+                        /* case VertexAttribType::GL_UNSIGNED_SHORT: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_UNSIGNED_SHORT))) ? (2) :
+                        /* case VertexAttribType::GL_FIXED: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_FIXED))) ? (4) :
+                        /* case VertexAttribType::GL_FLOAT: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_FLOAT))) ? (4) :
+                        /* case VertexAttribType::GL_ARB_half_float_vertex: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_ARB_half_float_vertex))) ? (2) :
+                        /* case VertexAttribType::GL_HALF_FLOAT_OES: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_HALF_FLOAT_OES))) ? (2) :
+                        /* default: */ 0 /* clang-format on */;
+                    uint32_t l_elsize = l_vertexAttribTypeSize_117_result * l_arr->mSize;
+                    uint32_t l_elstride = /* clang-format off */
+                    /* switch(l_arr->mStride == 0) */
+                        /* case true: */(((l_arr->mStride == 0) == (true))) ? (l_elsize) :
+                        /* case false: */(((l_arr->mStride == 0) == (false))) ? ((uint32_t)(l_arr->mStride)) :
+                        /* default: */ 0 /* clang-format on */;
+                    for (uint32_t l_v = l_ReadVertexArrays_116_first_index;
+                         l_v < l_ReadVertexArrays_116_last_index + 1; ++l_v) {
+                        uint32_t l_offset = l_elstride * l_v;
+                        read(slice(l_arr->mPointer, (uint64_t)(l_offset),
+                                   (uint64_t)(l_offset + l_elsize)));
+                    }
+                }
+            }
+            uint32_t l_IndexSize_118_indices_type = indices_type;
+            uint32_t l_IndexSize_118_result = /* clang-format off */
+            /* switch(l_IndexSize_118_indices_type) */
+                /* case IndicesType::GL_UNSIGNED_BYTE: */(((l_IndexSize_118_indices_type) == (IndicesType::GL_UNSIGNED_BYTE))) ? (1) :
+                /* case IndicesType::GL_UNSIGNED_SHORT: */(((l_IndexSize_118_indices_type) == (IndicesType::GL_UNSIGNED_SHORT))) ? (2) :
+                /* case IndicesType::GL_UNSIGNED_INT: */(((l_IndexSize_118_indices_type) == (IndicesType::GL_UNSIGNED_INT))) ? (4) :
+                /* default: */ 0 /* clang-format on */;
+            read(slice(l_index_data, (uint64_t)(0),
+                       (uint64_t)((uint32_t)(element_count)*l_IndexSize_118_result)));
+        }
+    } while (false);
 
     mEncoder->Uint16(168);  // Type ID -- TODO: mEncoder->Id(GL_DRAW_ELEMENTS_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(draw_mode));
     mEncoder->Int32(element_count);
     mEncoder->Uint32(static_cast<uint32_t>(indices_type));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(indices));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glDrawArrays(uint32_t draw_mode, int32_t first_index, int32_t index_count) {
     GAPID_INFO("glDrawArrays()\n");
     mImports.glDrawArrays(draw_mode, first_index, index_count);
-    mState.glDrawArrays(draw_mode, first_index, index_count);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_119_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_119_result;
+        int32_t l_last_index = first_index + index_count - 1;
+        std::shared_ptr<Context> l_ReadVertexArrays_120_ctx = l_ctx;
+        uint32_t l_ReadVertexArrays_120_first_index = (uint32_t)(first_index);
+        uint32_t l_ReadVertexArrays_120_last_index = (uint32_t)(l_last_index);
+        for (int32_t l_i = 0; l_i < l_ReadVertexArrays_120_ctx->mVertexAttributeArrays.size();
+             ++l_i) {
+            std::shared_ptr<VertexAttributeArray> l_arr =
+                    l_ReadVertexArrays_120_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)];
+            if (l_arr->mEnabled && l_arr->mBuffer == (BufferId)(0)) {
+                uint32_t l_vertexAttribTypeSize_121_t = l_arr->mType;
+                uint32_t l_vertexAttribTypeSize_121_result = /* clang-format off */
+                /* switch(l_vertexAttribTypeSize_121_t) */
+                    /* case VertexAttribType::GL_BYTE: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_BYTE))) ? (1) :
+                    /* case VertexAttribType::GL_UNSIGNED_BYTE: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_UNSIGNED_BYTE))) ? (1) :
+                    /* case VertexAttribType::GL_SHORT: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_SHORT))) ? (2) :
+                    /* case VertexAttribType::GL_UNSIGNED_SHORT: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_UNSIGNED_SHORT))) ? (2) :
+                    /* case VertexAttribType::GL_FIXED: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_FIXED))) ? (4) :
+                    /* case VertexAttribType::GL_FLOAT: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_FLOAT))) ? (4) :
+                    /* case VertexAttribType::GL_ARB_half_float_vertex: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_ARB_half_float_vertex))) ? (2) :
+                    /* case VertexAttribType::GL_HALF_FLOAT_OES: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_HALF_FLOAT_OES))) ? (2) :
+                    /* default: */ 0 /* clang-format on */;
+                uint32_t l_elsize = l_vertexAttribTypeSize_121_result * l_arr->mSize;
+                uint32_t l_elstride = /* clang-format off */
+                /* switch(l_arr->mStride == 0) */
+                    /* case true: */(((l_arr->mStride == 0) == (true))) ? (l_elsize) :
+                    /* case false: */(((l_arr->mStride == 0) == (false))) ? ((uint32_t)(l_arr->mStride)) :
+                    /* default: */ 0 /* clang-format on */;
+                for (uint32_t l_v = l_ReadVertexArrays_120_first_index;
+                     l_v < l_ReadVertexArrays_120_last_index + 1; ++l_v) {
+                    uint32_t l_offset = l_elstride * l_v;
+                    read(slice(l_arr->mPointer, (uint64_t)(l_offset),
+                               (uint64_t)(l_offset + l_elsize)));
+                }
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(169);  // Type ID -- TODO: mEncoder->Id(GL_DRAW_ARRAYS_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(draw_mode));
     mEncoder->Int32(first_index);
     mEncoder->Int32(index_count);
@@ -2341,57 +4491,469 @@
 inline void GlesSpy::glFlush() {
     GAPID_INFO("glFlush()\n");
     mImports.glFlush();
-    mState.glFlush();
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(170);  // Type ID -- TODO: mEncoder->Id(GL_FLUSH_ID);
+    encodeObservations();
 }
 
 inline void GlesSpy::glFinish() {
     GAPID_INFO("glFinish()\n");
     mImports.glFinish();
-    mState.glFinish();
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(171);  // Type ID -- TODO: mEncoder->Id(GL_FINISH_ID);
+    encodeObservations();
 }
 
 inline void GlesSpy::glGetBooleanv(uint32_t param, bool* values) {
     GAPID_INFO("glGetBooleanv()\n");
     mImports.glGetBooleanv(param, values);
-    mState.glGetBooleanv(param, values);
+
+    do {
+        Slice<bool> l_v = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_122_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_122_result;
+        switch (param) {
+            case StateVariable::GL_BLEND: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_BLEND]);
+                break;
+            }
+            case StateVariable::GL_CULL_FACE: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_CULL_FACE]);
+                break;
+            }
+            case StateVariable::GL_DEPTH_TEST: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_DEPTH_TEST]);
+                break;
+            }
+            case StateVariable::GL_DITHER: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_DITHER]);
+                break;
+            }
+            case StateVariable::GL_POLYGON_OFFSET_FILL: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_POLYGON_OFFSET_FILL]);
+                break;
+            }
+            case StateVariable::GL_SAMPLE_ALPHA_TO_COVERAGE: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_SAMPLE_ALPHA_TO_COVERAGE]);
+                break;
+            }
+            case StateVariable::GL_SAMPLE_COVERAGE: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_SAMPLE_COVERAGE]);
+                break;
+            }
+            case StateVariable::GL_SCISSOR_TEST: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_SCISSOR_TEST]);
+                break;
+            }
+            case StateVariable::GL_STENCIL_TEST: {
+                write(l_v, 0, l_ctx->mCapabilities[Capability::GL_STENCIL_TEST]);
+                break;
+            }
+            case StateVariable::GL_DEPTH_WRITEMASK: {
+                write(l_v, 0, l_ctx->mRasterizing.mDepthMask);
+                break;
+            }
+            case StateVariable::GL_COLOR_WRITEMASK: {
+                write(l_v, 0, l_ctx->mRasterizing.mColorMaskRed);
+                write(l_v, 1, l_ctx->mRasterizing.mColorMaskGreen);
+                write(l_v, 2, l_ctx->mRasterizing.mColorMaskBlue);
+                write(l_v, 3, l_ctx->mRasterizing.mColorMaskAlpha);
+                break;
+            }
+            case StateVariable::GL_SAMPLE_COVERAGE_INVERT: {
+                write(l_v, 0, l_ctx->mRasterizing.mSampleCoverageInvert);
+                break;
+            }
+            case StateVariable::GL_SHADER_COMPILER: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(172);  // Type ID -- TODO: mEncoder->Id(GL_GET_BOOLEANV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(param));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetFloatv(uint32_t param, float* values) {
     GAPID_INFO("glGetFloatv()\n");
     mImports.glGetFloatv(param, values);
-    mState.glGetFloatv(param, values);
+
+    do {
+        Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_123_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_123_result;
+        switch (param) {
+            case StateVariable::GL_DEPTH_RANGE: {
+                write(l_v, 0, l_ctx->mRasterizing.mDepthNear);
+                write(l_v, 1, l_ctx->mRasterizing.mDepthFar);
+                break;
+            }
+            case StateVariable::GL_LINE_WIDTH: {
+                write(l_v, 0, l_ctx->mRasterizing.mLineWidth);
+                break;
+            }
+            case StateVariable::GL_POLYGON_OFFSET_FACTOR: {
+                write(l_v, 0, l_ctx->mRasterizing.mPolygonOffsetFactor);
+                break;
+            }
+            case StateVariable::GL_POLYGON_OFFSET_UNITS: {
+                write(l_v, 0, l_ctx->mRasterizing.mPolygonOffsetUnits);
+                break;
+            }
+            case StateVariable::GL_SAMPLE_COVERAGE_VALUE: {
+                write(l_v, 0, l_ctx->mRasterizing.mSampleCoverageValue);
+                break;
+            }
+            case StateVariable::GL_COLOR_CLEAR_VALUE: {
+                write(l_v, 0, l_ctx->mClearing.mClearColor.mRed);
+                write(l_v, 1, l_ctx->mClearing.mClearColor.mGreen);
+                write(l_v, 2, l_ctx->mClearing.mClearColor.mBlue);
+                write(l_v, 3, l_ctx->mClearing.mClearColor.mAlpha);
+                break;
+            }
+            case StateVariable::GL_DEPTH_CLEAR_VALUE: {
+                write(l_v, 0, l_ctx->mClearing.mClearDepth);
+                break;
+            }
+            case StateVariable::GL_ALIASED_LINE_WIDTH_RANGE: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                write(l_v, 1,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 1));
+                break;
+            }
+            case StateVariable::GL_ALIASED_POINT_SIZE_RANGE: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                write(l_v, 1,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 1));
+                break;
+            }
+            case StateVariable::GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(173);  // Type ID -- TODO: mEncoder->Id(GL_GET_FLOATV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(param));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetIntegerv(uint32_t param, int32_t* values) {
     GAPID_INFO("glGetIntegerv()\n");
     mImports.glGetIntegerv(param, values);
-    mState.glGetIntegerv(param, values);
+
+    do {
+        Slice<int32_t> l_v = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_124_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_124_result;
+        switch (param) {
+            case StateVariable::GL_ACTIVE_TEXTURE: {
+                write(l_v, 0, (int32_t)(l_ctx->mActiveTextureUnit));
+                break;
+            }
+            case StateVariable::GL_ARRAY_BUFFER_BINDING: {
+                write(l_v, 0, (int32_t)(l_ctx->mBoundBuffers[BufferTarget::GL_ARRAY_BUFFER]));
+                break;
+            }
+            case StateVariable::GL_ELEMENT_ARRAY_BUFFER_BINDING: {
+                write(l_v, 0,
+                      (int32_t)(l_ctx->mBoundBuffers[BufferTarget::GL_ELEMENT_ARRAY_BUFFER]));
+                break;
+            }
+            case StateVariable::GL_BLEND_SRC_ALPHA: {
+                write(l_v, 0, (int32_t)(l_ctx->mBlending.mSrcAlphaBlendFactor));
+                break;
+            }
+            case StateVariable::GL_BLEND_SRC_RGB: {
+                write(l_v, 0, (int32_t)(l_ctx->mBlending.mSrcRgbBlendFactor));
+                break;
+            }
+            case StateVariable::GL_BLEND_DST_ALPHA: {
+                write(l_v, 0, (int32_t)(l_ctx->mBlending.mDstAlphaBlendFactor));
+                break;
+            }
+            case StateVariable::GL_BLEND_DST_RGB: {
+                write(l_v, 0, (int32_t)(l_ctx->mBlending.mDstRgbBlendFactor));
+                break;
+            }
+            case StateVariable::GL_BLEND_EQUATION_RGB: {
+                write(l_v, 0, (int32_t)(l_ctx->mBlending.mBlendEquationRgb));
+                break;
+            }
+            case StateVariable::GL_BLEND_EQUATION_ALPHA: {
+                write(l_v, 0, (int32_t)(l_ctx->mBlending.mBlendEquationAlpha));
+                break;
+            }
+            case StateVariable::GL_BLEND_COLOR: {
+                write(l_v, 0, (int32_t)(l_ctx->mBlending.mBlendColor.mRed));
+                write(l_v, 1, (int32_t)(l_ctx->mBlending.mBlendColor.mGreen));
+                write(l_v, 2, (int32_t)(l_ctx->mBlending.mBlendColor.mBlue));
+                write(l_v, 3, (int32_t)(l_ctx->mBlending.mBlendColor.mAlpha));
+                break;
+            }
+            case StateVariable::GL_DEPTH_FUNC: {
+                write(l_v, 0, (int32_t)(l_ctx->mRasterizing.mDepthTestFunction));
+                break;
+            }
+            case StateVariable::GL_DEPTH_CLEAR_VALUE: {
+                write(l_v, 0, (int32_t)(l_ctx->mClearing.mClearDepth));
+                break;
+            }
+            case StateVariable::GL_STENCIL_WRITEMASK: {
+                write(l_v, 0, (int32_t)(l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT]));
+                break;
+            }
+            case StateVariable::GL_STENCIL_BACK_WRITEMASK: {
+                write(l_v, 0, (int32_t)(l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK]));
+                break;
+            }
+            case StateVariable::GL_VIEWPORT: {
+                write(l_v, 0, l_ctx->mRasterizing.mViewport.mX);
+                write(l_v, 1, l_ctx->mRasterizing.mViewport.mY);
+                write(l_v, 2, l_ctx->mRasterizing.mViewport.mWidth);
+                write(l_v, 3, l_ctx->mRasterizing.mViewport.mHeight);
+                break;
+            }
+            case StateVariable::GL_SCISSOR_BOX: {
+                write(l_v, 0, l_ctx->mRasterizing.mScissor.mX);
+                write(l_v, 1, l_ctx->mRasterizing.mScissor.mY);
+                write(l_v, 2, l_ctx->mRasterizing.mScissor.mWidth);
+                write(l_v, 3, l_ctx->mRasterizing.mScissor.mHeight);
+                break;
+            }
+            case StateVariable::GL_FRONT_FACE: {
+                write(l_v, 0, (int32_t)(l_ctx->mRasterizing.mFrontFace));
+                break;
+            }
+            case StateVariable::GL_CULL_FACE_MODE: {
+                write(l_v, 0, (int32_t)(l_ctx->mRasterizing.mCullFace));
+                break;
+            }
+            case StateVariable::GL_STENCIL_CLEAR_VALUE: {
+                write(l_v, 0, l_ctx->mClearing.mClearStencil);
+                break;
+            }
+            case StateVariable::GL_FRAMEBUFFER_BINDING: {
+                write(l_v, 0,
+                      (int32_t)(l_ctx->mBoundFramebuffers[FramebufferTarget::GL_FRAMEBUFFER]));
+                break;
+            }
+            case StateVariable::GL_READ_FRAMEBUFFER_BINDING: {
+                write(l_v, 0,
+                      (int32_t)(l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER]));
+                break;
+            }
+            case StateVariable::GL_RENDERBUFFER_BINDING: {
+                write(l_v, 0,
+                      (int32_t)(l_ctx->mBoundRenderbuffers[RenderbufferTarget::GL_RENDERBUFFER]));
+                break;
+            }
+            case StateVariable::GL_CURRENT_PROGRAM: {
+                write(l_v, 0, (int32_t)(l_ctx->mBoundProgram));
+                break;
+            }
+            case StateVariable::GL_TEXTURE_BINDING_2D: {
+                write(l_v, 0, (int32_t)(l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                            [TextureTarget::GL_TEXTURE_2D]));
+                break;
+            }
+            case StateVariable::GL_TEXTURE_BINDING_CUBE_MAP: {
+                write(l_v, 0, (int32_t)(l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
+                                                            [TextureTarget::GL_TEXTURE_CUBE_MAP]));
+                break;
+            }
+            case StateVariable::GL_GENERATE_MIPMAP_HINT: {
+                write(l_v, 0, (int32_t)(l_ctx->mGenerateMipmapHint));
+                break;
+            }
+            case StateVariable::GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_CUBE_MAP_TEXTURE_SIZE: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_FRAGMENT_UNIFORM_VECTORS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_RENDERBUFFER_SIZE: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_TEXTURE_IMAGE_UNITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_TEXTURE_SIZE: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_VARYING_VECTORS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_VERTEX_ATTRIBS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_VERTEX_UNIFORM_VECTORS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_VIEWPORT_DIMS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                write(l_v, 1,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 1));
+                break;
+            }
+            case StateVariable::GL_NUM_COMPRESSED_TEXTURE_FORMATS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_NUM_SHADER_BINARY_FORMATS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_PACK_ALIGNMENT: {
+                write(l_v, 0, l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT]);
+                break;
+            }
+            case StateVariable::GL_UNPACK_ALIGNMENT: {
+                write(l_v, 0, l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT]);
+                break;
+            }
+            case StateVariable::GL_ALPHA_BITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_BLUE_BITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_GREEN_BITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_RED_BITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_DEPTH_BITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_SAMPLE_BUFFERS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_SAMPLES: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_STENCIL_BITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_SUBPIXEL_BITS: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_IMPLEMENTATION_COLOR_READ_FORMAT: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_IMPLEMENTATION_COLOR_READ_TYPE: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+            case StateVariable::GL_GPU_DISJOINT_EXT: {
+                write(l_v, 0,
+                      read(slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param))), 0));
+                break;
+            }
+        }
+    } while (false);
 
     mEncoder->Uint16(174);  // Type ID -- TODO: mEncoder->Id(GL_GET_INTEGERV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(param));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(values));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline char* GlesSpy::glGetString(uint32_t param) {
     GAPID_INFO("glGetString()\n");
     char* result = mImports.glGetString(param);
-    mState.glGetString(param, result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(175);  // Type ID -- TODO: mEncoder->Id(GL_GET_STRING_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(param));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(result));
+    mEncoder->Uint32(0);  // PoolID
 
     return result;
 }
@@ -2399,27 +4961,48 @@
 inline void GlesSpy::glEnable(uint32_t capability) {
     GAPID_INFO("glEnable()\n");
     mImports.glEnable(capability);
-    mState.glEnable(capability);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_125_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_125_result;
+        l_ctx->mCapabilities[capability] = true;
+    } while (false);
 
     mEncoder->Uint16(176);  // Type ID -- TODO: mEncoder->Id(GL_ENABLE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(capability));
 }
 
 inline void GlesSpy::glDisable(uint32_t capability) {
     GAPID_INFO("glDisable()\n");
     mImports.glDisable(capability);
-    mState.glDisable(capability);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_126_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_126_result;
+        l_ctx->mCapabilities[capability] = false;
+    } while (false);
 
     mEncoder->Uint16(177);  // Type ID -- TODO: mEncoder->Id(GL_DISABLE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(capability));
 }
 
 inline bool GlesSpy::glIsEnabled(uint32_t capability) {
     GAPID_INFO("glIsEnabled()\n");
     bool result = mImports.glIsEnabled(capability);
-    mState.glIsEnabled(capability, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_127_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_127_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(178);  // Type ID -- TODO: mEncoder->Id(GL_IS_ENABLED_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(capability));
     mEncoder->Bool(result);
 
@@ -2430,14 +5013,19 @@
                                        uint32_t access) {
     GAPID_INFO("glMapBufferRange()\n");
     void* result = mImports.glMapBufferRange(target, offset, length, access);
-    mState.glMapBufferRange(target, offset, length, access, result);
+
+    do {
+        break;
+    } while (false);
 
     mEncoder->Uint16(179);  // Type ID -- TODO: mEncoder->Id(GL_MAP_BUFFER_RANGE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(offset);
     mEncoder->Int32(length);
     mEncoder->Uint32(static_cast<uint32_t>(access));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(result));
+    mEncoder->Uint32(0);  // PoolID
 
     return result;
 }
@@ -2445,9 +5033,12 @@
 inline void GlesSpy::glUnmapBuffer(uint32_t target) {
     GAPID_INFO("glUnmapBuffer()\n");
     mImports.glUnmapBuffer(target);
-    mState.glUnmapBuffer(target);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(180);  // Type ID -- TODO: mEncoder->Id(GL_UNMAP_BUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
 }
 
@@ -2455,12 +5046,16 @@
                                              uint32_t* attachments) {
     GAPID_INFO("glInvalidateFramebuffer()\n");
     mImports.glInvalidateFramebuffer(target, count, attachments);
-    mState.glInvalidateFramebuffer(target, count, attachments);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(181);  // Type ID -- TODO: mEncoder->Id(GL_INVALIDATE_FRAMEBUFFER_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(attachments));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glRenderbufferStorageMultisample(uint32_t target, int32_t samples,
@@ -2468,10 +5063,13 @@
                                                       int32_t height) {
     GAPID_INFO("glRenderbufferStorageMultisample()\n");
     mImports.glRenderbufferStorageMultisample(target, samples, format, width, height);
-    mState.glRenderbufferStorageMultisample(target, samples, format, width, height);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(
             182);  // Type ID -- TODO: mEncoder->Id(GL_RENDERBUFFER_STORAGE_MULTISAMPLE_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Int32(samples);
     mEncoder->Uint32(static_cast<uint32_t>(format));
@@ -2485,9 +5083,12 @@
     GAPID_INFO("glBlitFramebuffer()\n");
     mImports.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
                                filter);
-    mState.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(183);  // Type ID -- TODO: mEncoder->Id(GL_BLIT_FRAMEBUFFER_ID);
+    encodeObservations();
     mEncoder->Int32(srcX0);
     mEncoder->Int32(srcY0);
     mEncoder->Int32(srcX1);
@@ -2503,19 +5104,36 @@
 inline void GlesSpy::glGenQueries(int32_t count, uint32_t* queries) {
     GAPID_INFO("glGenQueries()\n");
     mImports.glGenQueries(count, queries);
-    mState.glGenQueries(count, queries);
+
+    do {
+        Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_128_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_128_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            QueryId l_id = (QueryId)(
+                    read(slice(queries, (uint64_t)(0), (uint64_t)(count)), (uint64_t)(l_i)));
+            l_ctx->mInstances.mQueries[l_id] = std::shared_ptr<Query>((new Query()));
+            write(l_q, (uint64_t)(l_i), l_id);
+        }
+    } while (false);
 
     mEncoder->Uint16(184);  // Type ID -- TODO: mEncoder->Id(GL_GEN_QUERIES_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(queries));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glBeginQuery(uint32_t target, uint32_t query) {
     GAPID_INFO("glBeginQuery()\n");
     mImports.glBeginQuery(target, query);
-    mState.glBeginQuery(target, query);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(185);  // Type ID -- TODO: mEncoder->Id(GL_BEGIN_QUERY_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(query);
 }
@@ -2523,28 +5141,49 @@
 inline void GlesSpy::glEndQuery(uint32_t target) {
     GAPID_INFO("glEndQuery()\n");
     mImports.glEndQuery(target);
-    mState.glEndQuery(target);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(186);  // Type ID -- TODO: mEncoder->Id(GL_END_QUERY_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
 }
 
 inline void GlesSpy::glDeleteQueries(int32_t count, uint32_t* queries) {
     GAPID_INFO("glDeleteQueries()\n");
     mImports.glDeleteQueries(count, queries);
-    mState.glDeleteQueries(count, queries);
+
+    do {
+        Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_129_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_129_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            l_ctx->mInstances.mQueries[read(l_q, (uint64_t)(l_i))] = std::shared_ptr<Query>();
+        }
+    } while (false);
 
     mEncoder->Uint16(187);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_QUERIES_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(queries));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline bool GlesSpy::glIsQuery(uint32_t query) {
     GAPID_INFO("glIsQuery()\n");
     bool result = mImports.glIsQuery(query);
-    mState.glIsQuery(query, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_130_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_130_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(188);  // Type ID -- TODO: mEncoder->Id(GL_IS_QUERY_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Bool(result);
 
@@ -2554,41 +5193,68 @@
 inline void GlesSpy::glGetQueryiv(uint32_t target, uint32_t parameter, int32_t* value) {
     GAPID_INFO("glGetQueryiv()\n");
     mImports.glGetQueryiv(target, parameter, value);
-    mState.glGetQueryiv(target, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(189);  // Type ID -- TODO: mEncoder->Id(GL_GET_QUERYIV_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetQueryObjectuiv(uint32_t query, uint32_t parameter, uint32_t* value) {
     GAPID_INFO("glGetQueryObjectuiv()\n");
     mImports.glGetQueryObjectuiv(query, parameter, value);
-    mState.glGetQueryObjectuiv(query, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(190);  // Type ID -- TODO: mEncoder->Id(GL_GET_QUERY_OBJECTUIV_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGenQueriesEXT(int32_t count, uint32_t* queries) {
     GAPID_INFO("glGenQueriesEXT()\n");
     mImports.glGenQueriesEXT(count, queries);
-    mState.glGenQueriesEXT(count, queries);
+
+    do {
+        Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_131_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_131_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            QueryId l_id = (QueryId)(
+                    read(slice(queries, (uint64_t)(0), (uint64_t)(count)), (uint64_t)(l_i)));
+            l_ctx->mInstances.mQueries[l_id] = std::shared_ptr<Query>((new Query()));
+            write(l_q, (uint64_t)(l_i), l_id);
+        }
+    } while (false);
 
     mEncoder->Uint16(191);  // Type ID -- TODO: mEncoder->Id(GL_GEN_QUERIES_E_X_T_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(queries));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glBeginQueryEXT(uint32_t target, uint32_t query) {
     GAPID_INFO("glBeginQueryEXT()\n");
     mImports.glBeginQueryEXT(target, query);
-    mState.glBeginQueryEXT(target, query);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(192);  // Type ID -- TODO: mEncoder->Id(GL_BEGIN_QUERY_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(query);
 }
@@ -2596,28 +5262,49 @@
 inline void GlesSpy::glEndQueryEXT(uint32_t target) {
     GAPID_INFO("glEndQueryEXT()\n");
     mImports.glEndQueryEXT(target);
-    mState.glEndQueryEXT(target);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(193);  // Type ID -- TODO: mEncoder->Id(GL_END_QUERY_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
 }
 
 inline void GlesSpy::glDeleteQueriesEXT(int32_t count, uint32_t* queries) {
     GAPID_INFO("glDeleteQueriesEXT()\n");
     mImports.glDeleteQueriesEXT(count, queries);
-    mState.glDeleteQueriesEXT(count, queries);
+
+    do {
+        Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_132_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_132_result;
+        for (int32_t l_i = 0; l_i < count; ++l_i) {
+            l_ctx->mInstances.mQueries[read(l_q, (uint64_t)(l_i))] = std::shared_ptr<Query>();
+        }
+    } while (false);
 
     mEncoder->Uint16(194);  // Type ID -- TODO: mEncoder->Id(GL_DELETE_QUERIES_E_X_T_ID);
+    encodeObservations();
     mEncoder->Int32(count);
     mEncoder->Uint64(reinterpret_cast<uint64_t>(queries));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline bool GlesSpy::glIsQueryEXT(uint32_t query) {
     GAPID_INFO("glIsQueryEXT()\n");
     bool result = mImports.glIsQueryEXT(query);
-    mState.glIsQueryEXT(query, result);
+
+    do {
+        std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
+        std::shared_ptr<Context> l_GetContext_133_result = l_context;
+        std::shared_ptr<Context> l_ctx = l_GetContext_133_result;
+        break;
+    } while (false);
 
     mEncoder->Uint16(195);  // Type ID -- TODO: mEncoder->Id(GL_IS_QUERY_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Bool(result);
 
@@ -2627,9 +5314,12 @@
 inline void GlesSpy::glQueryCounterEXT(uint32_t query, uint32_t target) {
     GAPID_INFO("glQueryCounterEXT()\n");
     mImports.glQueryCounterEXT(query, target);
-    mState.glQueryCounterEXT(query, target);
+
+    do {
+    } while (false);
 
     mEncoder->Uint16(196);  // Type ID -- TODO: mEncoder->Id(GL_QUERY_COUNTER_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Uint32(static_cast<uint32_t>(target));
 }
@@ -2637,56 +5327,81 @@
 inline void GlesSpy::glGetQueryivEXT(uint32_t target, uint32_t parameter, int32_t* value) {
     GAPID_INFO("glGetQueryivEXT()\n");
     mImports.glGetQueryivEXT(target, parameter, value);
-    mState.glGetQueryivEXT(target, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(197);  // Type ID -- TODO: mEncoder->Id(GL_GET_QUERYIV_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(static_cast<uint32_t>(target));
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetQueryObjectivEXT(uint32_t query, uint32_t parameter, int32_t* value) {
     GAPID_INFO("glGetQueryObjectivEXT()\n");
     mImports.glGetQueryObjectivEXT(query, parameter, value);
-    mState.glGetQueryObjectivEXT(query, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(198);  // Type ID -- TODO: mEncoder->Id(GL_GET_QUERY_OBJECTIV_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetQueryObjectuivEXT(uint32_t query, uint32_t parameter, uint32_t* value) {
     GAPID_INFO("glGetQueryObjectuivEXT()\n");
     mImports.glGetQueryObjectuivEXT(query, parameter, value);
-    mState.glGetQueryObjectuivEXT(query, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(199);  // Type ID -- TODO: mEncoder->Id(GL_GET_QUERY_OBJECTUIV_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetQueryObjecti64vEXT(uint32_t query, uint32_t parameter, int64_t* value) {
     GAPID_INFO("glGetQueryObjecti64vEXT()\n");
     mImports.glGetQueryObjecti64vEXT(query, parameter, value);
-    mState.glGetQueryObjecti64vEXT(query, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(200);  // Type ID -- TODO: mEncoder->Id(GL_GET_QUERY_OBJECTI64V_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 inline void GlesSpy::glGetQueryObjectui64vEXT(uint32_t query, uint32_t parameter, uint64_t* value) {
     GAPID_INFO("glGetQueryObjectui64vEXT()\n");
     mImports.glGetQueryObjectui64vEXT(query, parameter, value);
-    mState.glGetQueryObjectui64vEXT(query, parameter, value);
+
+    do {
+        write(slice(value, 0, 1), 0, read(slice(value, 0, 1), 0));
+    } while (false);
 
     mEncoder->Uint16(201);  // Type ID -- TODO: mEncoder->Id(GL_GET_QUERY_OBJECTUI64V_E_X_T_ID);
+    encodeObservations();
     mEncoder->Uint32(query);
     mEncoder->Uint32(static_cast<uint32_t>(parameter));
     mEncoder->Uint64(reinterpret_cast<uint64_t>(value));
+    mEncoder->Uint32(0);  // PoolID
 }
 
 }  // namespace gapii
diff --git a/cc/gapii/gles_state.h b/cc/gapii/gles_state.h
deleted file mode 100644
index 58d98a8..0000000
--- a/cc/gapii/gles_state.h
+++ /dev/null
@@ -1,2985 +0,0 @@
-/*
- * Copyright 2015, The Android Open Source Project
- *
- * 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.
- *
- * THIS FILE WAS GENERATED BY apic. DO NOT EDIT.
- */
-
-#ifndef GAPII_GLES_STATE_H
-#define GAPII_GLES_STATE_H
-
-#include "state_base.h"
-#include "gles_types.h"
-
-#include <gapic/encoder.h>
-
-#include <stdint.h>
-
-namespace gapii {
-
-class GlesState : public StateBase {
-public:
-    inline GlesState(ObserveFunc observe);
-
-    inline void replayCreateRenderer(uint32_t const id);
-    inline void replayBindRenderer(uint32_t const id);
-    inline void backbufferInfo(int32_t const width, int32_t const height, uint32_t const color_fmt,
-                               uint32_t const depth_fmt, uint32_t const stencil_fmt,
-                               bool const resetViewportScissor);
-    inline void startTimer(uint8_t const index);
-    inline void stopTimer(uint8_t const index, uint64_t const result);
-    inline void flushPostBuffer();
-    inline void eglInitialize(void* const dpy, int* const major, int* const minor,
-                              EGLBoolean const result);
-    inline void eglCreateContext(void* const display, void* const config, void* const share_context,
-                                 int* const attrib_list, EGLContext const result);
-    inline void eglMakeCurrent(void* const display, void* const draw, void* const read,
-                               void* const context, EGLBoolean const result);
-    inline void eglSwapBuffers(void* const display, void* const surface, EGLBoolean const result);
-    inline void eglQuerySurface(void* const display, void* const surface, int const attribute,
-                                int* const value, EGLBoolean const result);
-    inline void glXCreateContext(void* const dpy, void* const vis, void* const shareList,
-                                 bool const direct, GLXContext const result);
-    inline void glXCreateNewContext(void* const display, void* const fbconfig, uint32_t const type,
-                                    void* const shared, bool const direct, GLXContext const result);
-    inline void glXMakeContextCurrent(void* const display, void* const draw, void* const read,
-                                      void* const ctx);
-    inline void glXSwapBuffers(void* const display, void* const drawable);
-    inline void wglCreateContext(void* const hdc, HGLRC const result);
-    inline void wglCreateContextAttribsARB(void* const hdc, void* const hShareContext,
-                                           int* const attribList, HGLRC const result);
-    inline void wglMakeCurrent(void* const hdc, void* const hglrc, BOOL const result);
-    inline void wglSwapBuffers(void* const hdc);
-    inline void CGLCreateContext(void* const pix, void* const share, void** const ctx,
-                                 CGLError const result);
-    inline void CGLSetCurrentContext(void* const ctx, CGLError const result);
-    inline void glEnableClientState(uint32_t const type);
-    inline void glDisableClientState(uint32_t const type);
-    inline void glGetProgramBinaryOES(uint32_t const program, int32_t const buffer_size,
-                                      int32_t* const bytes_written, uint32_t* const binary_format,
-                                      void* const binary);
-    inline void glProgramBinaryOES(uint32_t const program, uint32_t const binary_format,
-                                   void* const binary, int32_t const binary_size);
-    inline void glStartTilingQCOM(int32_t const x, int32_t const y, int32_t const width,
-                                  int32_t const height, uint32_t const preserveMask);
-    inline void glEndTilingQCOM(uint32_t const preserve_mask);
-    inline void glDiscardFramebufferEXT(uint32_t const target, int32_t const numAttachments,
-                                        uint32_t* const attachments);
-    inline void glInsertEventMarkerEXT(int32_t const length, char* const marker);
-    inline void glPushGroupMarkerEXT(int32_t const length, char* const marker);
-    inline void glPopGroupMarkerEXT();
-    inline void glTexStorage1DEXT(uint32_t const target, int32_t const levels,
-                                  uint32_t const format, int32_t const width);
-    inline void glTexStorage2DEXT(uint32_t const target, int32_t const levels,
-                                  uint32_t const format, int32_t const width, int32_t const height);
-    inline void glTexStorage3DEXT(uint32_t const target, int32_t const levels,
-                                  uint32_t const format, int32_t const width, int32_t const height,
-                                  int32_t const depth);
-    inline void glTextureStorage1DEXT(uint32_t const texture, uint32_t const target,
-                                      int32_t const levels, uint32_t const format,
-                                      int32_t const width);
-    inline void glTextureStorage2DEXT(uint32_t const texture, uint32_t const target,
-                                      int32_t const levels, uint32_t const format,
-                                      int32_t const width, int32_t const height);
-    inline void glTextureStorage3DEXT(uint32_t const texture, uint32_t const target,
-                                      int32_t const levels, uint32_t const format,
-                                      int32_t const width, int32_t const height,
-                                      int32_t const depth);
-    inline void glGenVertexArraysOES(int32_t const count, uint32_t* const arrays);
-    inline void glBindVertexArrayOES(uint32_t const array);
-    inline void glDeleteVertexArraysOES(int32_t const count, uint32_t* const arrays);
-    inline void glIsVertexArrayOES(uint32_t const array, bool const result);
-    inline void glEGLImageTargetTexture2DOES(uint32_t const target, void* const image);
-    inline void glEGLImageTargetRenderbufferStorageOES(uint32_t const target, void* const image);
-    inline void glGetGraphicsResetStatusEXT(uint32_t const result);
-    inline void glBindAttribLocation(uint32_t const program, uint32_t const location,
-                                     char* const name);
-    inline void glBlendFunc(uint32_t const src_factor, uint32_t const dst_factor);
-    inline void glBlendFuncSeparate(uint32_t const src_factor_rgb, uint32_t const dst_factor_rgb,
-                                    uint32_t const src_factor_alpha,
-                                    uint32_t const dst_factor_alpha);
-    inline void glBlendEquation(uint32_t const equation);
-    inline void glBlendEquationSeparate(uint32_t const rgb, uint32_t const alpha);
-    inline void glBlendColor(float const red, float const green, float const blue,
-                             float const alpha);
-    inline void glEnableVertexAttribArray(uint32_t const location);
-    inline void glDisableVertexAttribArray(uint32_t const location);
-    inline void glVertexAttribPointer(uint32_t const location, int32_t const size,
-                                      uint32_t const type, bool const normalized,
-                                      int32_t const stride, void* const data);
-    inline void glGetActiveAttrib(uint32_t const program, uint32_t const location,
-                                  int32_t const buffer_size, int32_t* const buffer_bytes_written,
-                                  int32_t* const vector_count, uint32_t* const type,
-                                  char* const name);
-    inline void glGetActiveUniform(uint32_t const program, int32_t const location,
-                                   int32_t const buffer_size, int32_t* const buffer_bytes_written,
-                                   int32_t* const size, uint32_t* const type, char* const name);
-    inline void glGetError(uint32_t const result);
-    inline void glGetProgramiv(uint32_t const program, uint32_t const parameter,
-                               int32_t* const value);
-    inline void glGetShaderiv(uint32_t const shader, uint32_t const parameter,
-                              int32_t* const value);
-    inline void glGetUniformLocation(uint32_t const program, char* const name,
-                                     UniformLocation const result);
-    inline void glGetAttribLocation(uint32_t const program, char* const name,
-                                    AttributeLocation const result);
-    inline void glPixelStorei(uint32_t const parameter, int32_t const value);
-    inline void glTexParameteri(uint32_t const target, uint32_t const parameter,
-                                int32_t const value);
-    inline void glTexParameterf(uint32_t const target, uint32_t const parameter, float const value);
-    inline void glGetTexParameteriv(uint32_t const target, uint32_t const parameter,
-                                    int32_t* const values);
-    inline void glGetTexParameterfv(uint32_t const target, uint32_t const parameter,
-                                    float* const values);
-    inline void glUniform1i(int32_t const location, int32_t const value);
-    inline void glUniform2i(int32_t const location, int32_t const value0, int32_t const value1);
-    inline void glUniform3i(int32_t const location, int32_t const value0, int32_t const value1,
-                            int32_t const value2);
-    inline void glUniform4i(int32_t const location, int32_t const value0, int32_t const value1,
-                            int32_t const value2, int32_t const value3);
-    inline void glUniform1iv(int32_t const location, int32_t const count, int32_t* const value);
-    inline void glUniform2iv(int32_t const location, int32_t const count, int32_t* const value);
-    inline void glUniform3iv(int32_t const location, int32_t const count, int32_t* const value);
-    inline void glUniform4iv(int32_t const location, int32_t const count, int32_t* const value);
-    inline void glUniform1f(int32_t const location, float const value);
-    inline void glUniform2f(int32_t const location, float const value0, float const value1);
-    inline void glUniform3f(int32_t const location, float const value0, float const value1,
-                            float const value2);
-    inline void glUniform4f(int32_t const location, float const value0, float const value1,
-                            float const value2, float const value3);
-    inline void glUniform1fv(int32_t const location, int32_t const count, float* const value);
-    inline void glUniform2fv(int32_t const location, int32_t const count, float* const value);
-    inline void glUniform3fv(int32_t const location, int32_t const count, float* const value);
-    inline void glUniform4fv(int32_t const location, int32_t const count, float* const value);
-    inline void glUniformMatrix2fv(int32_t const location, int32_t const count,
-                                   bool const transpose, float* const values);
-    inline void glUniformMatrix3fv(int32_t const location, int32_t const count,
-                                   bool const transpose, float* const values);
-    inline void glUniformMatrix4fv(int32_t const location, int32_t const count,
-                                   bool const transpose, float* const values);
-    inline void glGetUniformfv(uint32_t const program, int32_t const location, float* const values);
-    inline void glGetUniformiv(uint32_t const program, int32_t const location,
-                               int32_t* const values);
-    inline void glVertexAttrib1f(uint32_t const location, float const value0);
-    inline void glVertexAttrib2f(uint32_t const location, float const value0, float const value1);
-    inline void glVertexAttrib3f(uint32_t const location, float const value0, float const value1,
-                                 float const value2);
-    inline void glVertexAttrib4f(uint32_t const location, float const value0, float const value1,
-                                 float const value2, float const value3);
-    inline void glVertexAttrib1fv(uint32_t const location, float* const value);
-    inline void glVertexAttrib2fv(uint32_t const location, float* const value);
-    inline void glVertexAttrib3fv(uint32_t const location, float* const value);
-    inline void glVertexAttrib4fv(uint32_t const location, float* const value);
-    inline void glGetShaderPrecisionFormat(uint32_t const shader_type,
-                                           uint32_t const precision_type, int32_t* const range,
-                                           int32_t* const precision);
-    inline void glDepthMask(bool const enabled);
-    inline void glDepthFunc(uint32_t const function);
-    inline void glDepthRangef(float const near, float const far);
-    inline void glColorMask(bool const red, bool const green, bool const blue, bool const alpha);
-    inline void glStencilMask(uint32_t const mask);
-    inline void glStencilMaskSeparate(uint32_t const face, uint32_t const mask);
-    inline void glStencilFuncSeparate(uint32_t const face, uint32_t const function,
-                                      int32_t const reference_value, int32_t const mask);
-    inline void glStencilOpSeparate(uint32_t const face, uint32_t const stencil_fail,
-                                    uint32_t const stencil_pass_depth_fail,
-                                    uint32_t const stencil_pass_depth_pass);
-    inline void glFrontFace(uint32_t const orientation);
-    inline void glViewport(int32_t const x, int32_t const y, int32_t const width,
-                           int32_t const height);
-    inline void glScissor(int32_t const x, int32_t const y, int32_t const width,
-                          int32_t const height);
-    inline void glActiveTexture(uint32_t const unit);
-    inline void glGenTextures(int32_t const count, uint32_t* const textures);
-    inline void glDeleteTextures(int32_t const count, uint32_t* const textures);
-    inline void glIsTexture(uint32_t const texture, bool const result);
-    inline void glBindTexture(uint32_t const target, uint32_t const texture);
-    inline void glTexImage2D(uint32_t const target, int32_t const level,
-                             uint32_t const internal_format, int32_t const width,
-                             int32_t const height, int32_t const border, uint32_t const format,
-                             uint32_t const type, void* const data);
-    inline void glTexSubImage2D(uint32_t const target, int32_t const level, int32_t const xoffset,
-                                int32_t const yoffset, int32_t const width, int32_t const height,
-                                uint32_t const format, uint32_t const type, void* const data);
-    inline void glCopyTexImage2D(uint32_t const target, int32_t const level, uint32_t const format,
-                                 int32_t const x, int32_t const y, int32_t const width,
-                                 int32_t const height, int32_t const border);
-    inline void glCopyTexSubImage2D(uint32_t const target, int32_t const level,
-                                    int32_t const xoffset, int32_t const yoffset, int32_t const x,
-                                    int32_t const y, int32_t const width, int32_t const height);
-    inline void glCompressedTexImage2D(uint32_t const target, int32_t const level,
-                                       uint32_t const format, int32_t const width,
-                                       int32_t const height, int32_t const border,
-                                       int32_t const image_size, void* const data);
-    inline void glCompressedTexSubImage2D(uint32_t const target, int32_t const level,
-                                          int32_t const xoffset, int32_t const yoffset,
-                                          int32_t const width, int32_t const height,
-                                          uint32_t const format, int32_t const image_size,
-                                          void* const data);
-    inline void glGenerateMipmap(uint32_t const target);
-    inline void glReadPixels(int32_t const x, int32_t const y, int32_t const width,
-                             int32_t const height, uint32_t const format, uint32_t const type,
-                             void* const data);
-    inline void glGenFramebuffers(int32_t const count, uint32_t* const framebuffers);
-    inline void glBindFramebuffer(uint32_t const target, uint32_t const framebuffer);
-    inline void glCheckFramebufferStatus(uint32_t const target, uint32_t const result);
-    inline void glDeleteFramebuffers(int32_t const count, uint32_t* const framebuffers);
-    inline void glIsFramebuffer(uint32_t const framebuffer, bool const result);
-    inline void glGenRenderbuffers(int32_t const count, uint32_t* const renderbuffers);
-    inline void glBindRenderbuffer(uint32_t const target, uint32_t const renderbuffer);
-    inline void glRenderbufferStorage(uint32_t const target, uint32_t const format,
-                                      int32_t const width, int32_t const height);
-    inline void glDeleteRenderbuffers(int32_t const count, uint32_t* const renderbuffers);
-    inline void glIsRenderbuffer(uint32_t const renderbuffer, bool const result);
-    inline void glGetRenderbufferParameteriv(uint32_t const target, uint32_t const parameter,
-                                             int32_t* const values);
-    inline void glGenBuffers(int32_t const count, uint32_t* const buffers);
-    inline void glBindBuffer(uint32_t const target, uint32_t const buffer);
-    inline void glBufferData(uint32_t const target, int32_t const size, void* const data,
-                             uint32_t const usage);
-    inline void glBufferSubData(uint32_t const target, int32_t const offset, int32_t const size,
-                                void* const data);
-    inline void glDeleteBuffers(int32_t const count, uint32_t* const buffers);
-    inline void glIsBuffer(uint32_t const buffer, bool const result);
-    inline void glGetBufferParameteriv(uint32_t const target, uint32_t const parameter,
-                                       int32_t* const value);
-    inline void glCreateShader(uint32_t const type, ShaderId const result);
-    inline void glDeleteShader(uint32_t const shader);
-    inline void glShaderSource(uint32_t const shader, int32_t const count, char** const source,
-                               int32_t* const length);
-    inline void glShaderBinary(int32_t const count, uint32_t* const shaders,
-                               uint32_t const binary_format, void* const binary,
-                               int32_t const binary_size);
-    inline void glGetShaderInfoLog(uint32_t const shader, int32_t const buffer_length,
-                                   int32_t* const string_length_written, char* const info);
-    inline void glGetShaderSource(uint32_t const shader, int32_t const buffer_length,
-                                  int32_t* const string_length_written, char* const source);
-    inline void glReleaseShaderCompiler();
-    inline void glCompileShader(uint32_t const shader);
-    inline void glIsShader(uint32_t const shader, bool const result);
-    inline void glCreateProgram(ProgramId const result);
-    inline void glDeleteProgram(uint32_t const program);
-    inline void glAttachShader(uint32_t const program, uint32_t const shader);
-    inline void glDetachShader(uint32_t const program, uint32_t const shader);
-    inline void glGetAttachedShaders(uint32_t const program, int32_t const buffer_length,
-                                     int32_t* const shaders_length_written,
-                                     uint32_t* const shaders);
-    inline void glLinkProgram(uint32_t const program);
-    inline void glGetProgramInfoLog(uint32_t const program, int32_t const buffer_length,
-                                    int32_t* const string_length_written, char* const info);
-    inline void glUseProgram(uint32_t const program);
-    inline void glIsProgram(uint32_t const program, bool const result);
-    inline void glValidateProgram(uint32_t const program);
-    inline void glClearColor(float const r, float const g, float const b, float const a);
-    inline void glClearDepthf(float const depth);
-    inline void glClearStencil(int32_t const stencil);
-    inline void glClear(uint32_t const mask);
-    inline void glCullFace(uint32_t const mode);
-    inline void glPolygonOffset(float const scale_factor, float const units);
-    inline void glLineWidth(float const width);
-    inline void glSampleCoverage(float const value, bool const invert);
-    inline void glHint(uint32_t const target, uint32_t const mode);
-    inline void glFramebufferRenderbuffer(uint32_t const framebuffer_target,
-                                          uint32_t const framebuffer_attachment,
-                                          uint32_t const renderbuffer_target,
-                                          uint32_t const renderbuffer);
-    inline void glFramebufferTexture2D(uint32_t const framebuffer_target,
-                                       uint32_t const framebuffer_attachment,
-                                       uint32_t const texture_target, uint32_t const texture,
-                                       int32_t const level);
-    inline void glGetFramebufferAttachmentParameteriv(uint32_t const framebuffer_target,
-                                                      uint32_t const attachment,
-                                                      uint32_t const parameter,
-                                                      int32_t* const value);
-    inline void glDrawElements(uint32_t const draw_mode, int32_t const element_count,
-                               uint32_t const indices_type, void* const indices);
-    inline void glDrawArrays(uint32_t const draw_mode, int32_t const first_index,
-                             int32_t const index_count);
-    inline void glFlush();
-    inline void glFinish();
-    inline void glGetBooleanv(uint32_t const param, bool* const values);
-    inline void glGetFloatv(uint32_t const param, float* const values);
-    inline void glGetIntegerv(uint32_t const param, int32_t* const values);
-    inline void glGetString(uint32_t const param, char* const result);
-    inline void glEnable(uint32_t const capability);
-    inline void glDisable(uint32_t const capability);
-    inline void glIsEnabled(uint32_t const capability, bool const result);
-    inline void glMapBufferRange(uint32_t const target, int32_t const offset, int32_t const length,
-                                 uint32_t const access, void* const result);
-    inline void glUnmapBuffer(uint32_t const target);
-    inline void glInvalidateFramebuffer(uint32_t const target, int32_t const count,
-                                        uint32_t* const attachments);
-    inline void glRenderbufferStorageMultisample(uint32_t const target, int32_t const samples,
-                                                 uint32_t const format, int32_t const width,
-                                                 int32_t const height);
-    inline void glBlitFramebuffer(int32_t const srcX0, int32_t const srcY0, int32_t const srcX1,
-                                  int32_t const srcY1, int32_t const dstX0, int32_t const dstY0,
-                                  int32_t const dstX1, int32_t const dstY1, uint32_t const mask,
-                                  uint32_t const filter);
-    inline void glGenQueries(int32_t const count, uint32_t* const queries);
-    inline void glBeginQuery(uint32_t const target, uint32_t const query);
-    inline void glEndQuery(uint32_t const target);
-    inline void glDeleteQueries(int32_t const count, uint32_t* const queries);
-    inline void glIsQuery(uint32_t const query, bool const result);
-    inline void glGetQueryiv(uint32_t const target, uint32_t const parameter, int32_t* const value);
-    inline void glGetQueryObjectuiv(uint32_t const query, uint32_t const parameter,
-                                    uint32_t* const value);
-    inline void glGenQueriesEXT(int32_t const count, uint32_t* const queries);
-    inline void glBeginQueryEXT(uint32_t const target, uint32_t const query);
-    inline void glEndQueryEXT(uint32_t const target);
-    inline void glDeleteQueriesEXT(int32_t const count, uint32_t* const queries);
-    inline void glIsQueryEXT(uint32_t const query, bool const result);
-    inline void glQueryCounterEXT(uint32_t const query, uint32_t const target);
-    inline void glGetQueryivEXT(uint32_t const target, uint32_t const parameter,
-                                int32_t* const value);
-    inline void glGetQueryObjectivEXT(uint32_t const query, uint32_t const parameter,
-                                      int32_t* const value);
-    inline void glGetQueryObjectuivEXT(uint32_t const query, uint32_t const parameter,
-                                       uint32_t* const value);
-    inline void glGetQueryObjecti64vEXT(uint32_t const query, uint32_t const parameter,
-                                        int64_t* const value);
-    inline void glGetQueryObjectui64vEXT(uint32_t const query, uint32_t const parameter,
-                                         uint64_t* const value);
-
-    ContextID NextContextID;
-    ThreadID CurrentThread;
-    ThreadIDToContextRef Contexts;
-    EGLContextToContextRef EGLContexts;
-    GLXContextToContextRef GLXContexts;
-    HGLRCToContextRef WGLContexts;
-    CGLContextObjToContextRef CGLContexts;
-
-#include "gles_state_externs.inl"
-};
-
-inline GlesState::GlesState(ObserveFunc observe) : StateBase(observe) {}
-
-inline void GlesState::replayCreateRenderer(uint32_t const id) {}
-
-inline void GlesState::replayBindRenderer(uint32_t const id) {}
-
-inline void GlesState::backbufferInfo(int32_t const width, int32_t const height,
-                                      uint32_t const color_fmt, uint32_t const depth_fmt,
-                                      uint32_t const stencil_fmt, bool const resetViewportScissor) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_0_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_0_result;
-    std::shared_ptr<Framebuffer> l_backbuffer = l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)];
-    RenderbufferId l_color_id = (RenderbufferId)(
-            l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0].mObject);
-    std::shared_ptr<Renderbuffer> l_color_buffer = l_ctx->mInstances.mRenderbuffers[l_color_id];
-    RenderbufferId l_depth_id = (RenderbufferId)(
-            l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT].mObject);
-    std::shared_ptr<Renderbuffer> l_depth_buffer = l_ctx->mInstances.mRenderbuffers[l_depth_id];
-    RenderbufferId l_stencil_id = (RenderbufferId)(
-            l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT].mObject);
-    std::shared_ptr<Renderbuffer> l_stencil_buffer = l_ctx->mInstances.mRenderbuffers[l_stencil_id];
-    l_color_buffer->mWidth = width;
-    l_color_buffer->mHeight = height;
-    l_color_buffer->mFormat = color_fmt;
-    l_depth_buffer->mWidth = width;
-    l_depth_buffer->mHeight = height;
-    l_depth_buffer->mFormat = depth_fmt;
-    l_stencil_buffer->mWidth = width;
-    l_stencil_buffer->mHeight = height;
-    l_stencil_buffer->mFormat = stencil_fmt;
-    if (resetViewportScissor) {
-        l_ctx->mRasterizing.mScissor.mWidth = width;
-        l_ctx->mRasterizing.mScissor.mHeight = height;
-        l_ctx->mRasterizing.mViewport.mWidth = width;
-        l_ctx->mRasterizing.mViewport.mHeight = height;
-    }
-}
-
-inline void GlesState::startTimer(uint8_t const index) {}
-
-inline void GlesState::stopTimer(uint8_t const index, uint64_t const result) { return; }
-
-inline void GlesState::flushPostBuffer() {}
-
-inline void GlesState::eglInitialize(void* const dpy, int* const major, int* const minor,
-                                     EGLBoolean const result) {
-    slice(major, 0, 1)[0] = slice(major, 0, 1)[0];
-    slice(minor, 0, 1)[0] = slice(minor, 0, 1)[0];
-    return;
-}
-
-inline void GlesState::eglCreateContext(void* const display, void* const config,
-                                        void* const share_context, int* const attrib_list,
-                                        EGLContext const result) {
-    EGLContext l_context = (EGLContext)(result);
-    ContextID l_identifier = this->NextContextID;
-    this->NextContextID = this->NextContextID + (ContextID)(1);
-    std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
-    l_ctx->mIdentifier = l_identifier;
-    l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
-    l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
-    l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    RenderbufferId l_color_id = (RenderbufferId)(4294967295);
-    RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
-    RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
-    l_ctx->mInstances.mRenderbuffers[l_color_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_depth_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    std::shared_ptr<Framebuffer> l_backbuffer = std::shared_ptr<Framebuffer>((new Framebuffer()));
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_color_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_depth_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_stencil_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
-    for (int32_t l_i = 0; l_i < 64; ++l_i) {
-        l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
-                std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
-    }
-    std::shared_ptr<Context> l_CreateContext_1_result = l_ctx;
-    this->EGLContexts[l_context] = l_CreateContext_1_result;
-    return;
-}
-
-inline void GlesState::eglMakeCurrent(void* const display, void* const draw, void* const read,
-                                      void* const context, EGLBoolean const result) {
-    std::shared_ptr<Context> l_SetContext_2_context = this->EGLContexts[context];
-    this->Contexts[this->CurrentThread] = l_SetContext_2_context;
-    return;
-}
-
-inline void GlesState::eglSwapBuffers(void* const display, void* const surface,
-                                      EGLBoolean const result) {
-    return;
-}
-
-inline void GlesState::eglQuerySurface(void* const display, void* const surface,
-                                       int const attribute, int* const value,
-                                       EGLBoolean const result) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-    return;
-}
-
-inline void GlesState::glXCreateContext(void* const dpy, void* const vis, void* const shareList,
-                                        bool const direct, GLXContext const result) {
-    GLXContext l_context = (GLXContext)(result);
-    ContextID l_identifier = this->NextContextID;
-    this->NextContextID = this->NextContextID + (ContextID)(1);
-    std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
-    l_ctx->mIdentifier = l_identifier;
-    l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
-    l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
-    l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    RenderbufferId l_color_id = (RenderbufferId)(4294967295);
-    RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
-    RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
-    l_ctx->mInstances.mRenderbuffers[l_color_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_depth_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    std::shared_ptr<Framebuffer> l_backbuffer = std::shared_ptr<Framebuffer>((new Framebuffer()));
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_color_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_depth_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_stencil_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
-    for (int32_t l_i = 0; l_i < 64; ++l_i) {
-        l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
-                std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
-    }
-    std::shared_ptr<Context> l_CreateContext_3_result = l_ctx;
-    this->GLXContexts[l_context] = l_CreateContext_3_result;
-    return;
-}
-
-inline void GlesState::glXCreateNewContext(void* const display, void* const fbconfig,
-                                           uint32_t const type, void* const shared,
-                                           bool const direct, GLXContext const result) {
-    GLXContext l_context = (GLXContext)(result);
-    ContextID l_identifier = this->NextContextID;
-    this->NextContextID = this->NextContextID + (ContextID)(1);
-    std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
-    l_ctx->mIdentifier = l_identifier;
-    l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
-    l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
-    l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    RenderbufferId l_color_id = (RenderbufferId)(4294967295);
-    RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
-    RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
-    l_ctx->mInstances.mRenderbuffers[l_color_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_depth_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    std::shared_ptr<Framebuffer> l_backbuffer = std::shared_ptr<Framebuffer>((new Framebuffer()));
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_color_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_depth_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_stencil_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
-    for (int32_t l_i = 0; l_i < 64; ++l_i) {
-        l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
-                std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
-    }
-    std::shared_ptr<Context> l_CreateContext_4_result = l_ctx;
-    this->GLXContexts[l_context] = l_CreateContext_4_result;
-    return;
-}
-
-inline void GlesState::glXMakeContextCurrent(void* const display, void* const draw,
-                                             void* const read, void* const ctx) {
-    std::shared_ptr<Context> l_SetContext_5_context = this->GLXContexts[ctx];
-    this->Contexts[this->CurrentThread] = l_SetContext_5_context;
-}
-
-inline void GlesState::glXSwapBuffers(void* const display, void* const drawable) {}
-
-inline void GlesState::wglCreateContext(void* const hdc, HGLRC const result) {
-    HGLRC l_context = (HGLRC)(result);
-    ContextID l_identifier = this->NextContextID;
-    this->NextContextID = this->NextContextID + (ContextID)(1);
-    std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
-    l_ctx->mIdentifier = l_identifier;
-    l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
-    l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
-    l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    RenderbufferId l_color_id = (RenderbufferId)(4294967295);
-    RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
-    RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
-    l_ctx->mInstances.mRenderbuffers[l_color_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_depth_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    std::shared_ptr<Framebuffer> l_backbuffer = std::shared_ptr<Framebuffer>((new Framebuffer()));
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_color_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_depth_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_stencil_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
-    for (int32_t l_i = 0; l_i < 64; ++l_i) {
-        l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
-                std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
-    }
-    std::shared_ptr<Context> l_CreateContext_6_result = l_ctx;
-    this->WGLContexts[l_context] = l_CreateContext_6_result;
-    return;
-}
-
-inline void GlesState::wglCreateContextAttribsARB(void* const hdc, void* const hShareContext,
-                                                  int* const attribList, HGLRC const result) {
-    HGLRC l_context = (HGLRC)(result);
-    ContextID l_identifier = this->NextContextID;
-    this->NextContextID = this->NextContextID + (ContextID)(1);
-    std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
-    l_ctx->mIdentifier = l_identifier;
-    l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
-    l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
-    l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    RenderbufferId l_color_id = (RenderbufferId)(4294967295);
-    RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
-    RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
-    l_ctx->mInstances.mRenderbuffers[l_color_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_depth_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    std::shared_ptr<Framebuffer> l_backbuffer = std::shared_ptr<Framebuffer>((new Framebuffer()));
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_color_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_depth_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_stencil_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
-    for (int32_t l_i = 0; l_i < 64; ++l_i) {
-        l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
-                std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
-    }
-    std::shared_ptr<Context> l_CreateContext_7_result = l_ctx;
-    this->WGLContexts[l_context] = l_CreateContext_7_result;
-    return;
-}
-
-inline void GlesState::wglMakeCurrent(void* const hdc, void* const hglrc, BOOL const result) {
-    std::shared_ptr<Context> l_SetContext_8_context = this->WGLContexts[hglrc];
-    this->Contexts[this->CurrentThread] = l_SetContext_8_context;
-    return;
-}
-
-inline void GlesState::wglSwapBuffers(void* const hdc) {}
-
-inline void GlesState::CGLCreateContext(void* const pix, void* const share, void** const ctx,
-                                        CGLError const result) {
-    CGLContextObj l_context = (CGLContextObj)(slice(ctx, 0, 1)[0]);
-    ContextID l_identifier = this->NextContextID;
-    this->NextContextID = this->NextContextID + (ContextID)(1);
-    std::shared_ptr<Context> l_ctx = std::shared_ptr<Context>((new Context()));
-    l_ctx->mIdentifier = l_identifier;
-    l_ctx->mInstances.mBuffers[(BufferId)(0)] = std::shared_ptr<Buffer>((new Buffer()));
-    l_ctx->mInstances.mTextures[(TextureId)(0)] = std::shared_ptr<Texture>((new Texture()));
-    l_ctx->mInstances.mRenderbuffers[(RenderbufferId)(0)] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    RenderbufferId l_color_id = (RenderbufferId)(4294967295);
-    RenderbufferId l_depth_id = (RenderbufferId)(4294967294);
-    RenderbufferId l_stencil_id = (RenderbufferId)(4294967293);
-    l_ctx->mInstances.mRenderbuffers[l_color_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_depth_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    l_ctx->mInstances.mRenderbuffers[l_stencil_id] =
-            std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    std::shared_ptr<Framebuffer> l_backbuffer = std::shared_ptr<Framebuffer>((new Framebuffer()));
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_COLOR_ATTACHMENT0] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_color_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_DEPTH_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_depth_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_backbuffer->mAttachments[FramebufferAttachment::GL_STENCIL_ATTACHMENT] =
-            FramebufferAttachmentInfo()
-                    .SetObject((uint32_t)(l_stencil_id))
-                    .SetType(FramebufferAttachmentType::GL_RENDERBUFFER)
-                    .SetCubeMapFace(CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X);
-    l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)] = l_backbuffer;
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = (FramebufferId)(0);
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = 4294967295;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = 4294967295;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT] = 4;
-    l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT] = 4;
-    for (int32_t l_i = 0; l_i < 64; ++l_i) {
-        l_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)] =
-                std::shared_ptr<VertexAttributeArray>((new VertexAttributeArray()));
-    }
-    std::shared_ptr<Context> l_CreateContext_9_result = l_ctx;
-    this->CGLContexts[l_context] = l_CreateContext_9_result;
-    slice(ctx, 0, 1)[0] = l_context;
-    return;
-}
-
-inline void GlesState::CGLSetCurrentContext(void* const ctx, CGLError const result) {
-    std::shared_ptr<Context> l_SetContext_10_context = this->CGLContexts[ctx];
-    this->Contexts[this->CurrentThread] = l_SetContext_10_context;
-    return;
-}
-
-inline void GlesState::glEnableClientState(uint32_t const type) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_11_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_11_result;
-    l_ctx->mCapabilities[(uint32_t)(type)] = true;
-}
-
-inline void GlesState::glDisableClientState(uint32_t const type) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_12_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_12_result;
-    l_ctx->mCapabilities[(uint32_t)(type)] = false;
-}
-
-inline void GlesState::glGetProgramBinaryOES(uint32_t const program, int32_t const buffer_size,
-                                             int32_t* const bytes_written,
-                                             uint32_t* const binary_format, void* const binary) {
-    int32_t l_l = (int32_t)(slice(bytes_written, 0, 1)[0]);
-    slice(bytes_written, 0, 1)[0] = l_l;
-    slice(binary_format, 0, 1)[0] = slice(binary_format, 0, 1)[0];
-    write(slice(binary, (uint64_t)(0), (uint64_t)(l_l)));
-}
-
-inline void GlesState::glProgramBinaryOES(uint32_t const program, uint32_t const binary_format,
-                                          void* const binary, int32_t const binary_size) {}
-
-inline void GlesState::glStartTilingQCOM(int32_t const x, int32_t const y, int32_t const width,
-                                         int32_t const height, uint32_t const preserveMask) {}
-
-inline void GlesState::glEndTilingQCOM(uint32_t const preserve_mask) {}
-
-inline void GlesState::glDiscardFramebufferEXT(uint32_t const target, int32_t const numAttachments,
-                                               uint32_t* const attachments) {}
-
-inline void GlesState::glInsertEventMarkerEXT(int32_t const length, char* const marker) {}
-
-inline void GlesState::glPushGroupMarkerEXT(int32_t const length, char* const marker) {}
-
-inline void GlesState::glPopGroupMarkerEXT() {}
-
-inline void GlesState::glTexStorage1DEXT(uint32_t const target, int32_t const levels,
-                                         uint32_t const format, int32_t const width) {}
-
-inline void GlesState::glTexStorage2DEXT(uint32_t const target, int32_t const levels,
-                                         uint32_t const format, int32_t const width,
-                                         int32_t const height) {}
-
-inline void GlesState::glTexStorage3DEXT(uint32_t const target, int32_t const levels,
-                                         uint32_t const format, int32_t const width,
-                                         int32_t const height, int32_t const depth) {}
-
-inline void GlesState::glTextureStorage1DEXT(uint32_t const texture, uint32_t const target,
-                                             int32_t const levels, uint32_t const format,
-                                             int32_t const width) {}
-
-inline void GlesState::glTextureStorage2DEXT(uint32_t const texture, uint32_t const target,
-                                             int32_t const levels, uint32_t const format,
-                                             int32_t const width, int32_t const height) {}
-
-inline void GlesState::glTextureStorage3DEXT(uint32_t const texture, uint32_t const target,
-                                             int32_t const levels, uint32_t const format,
-                                             int32_t const width, int32_t const height,
-                                             int32_t const depth) {}
-
-inline void GlesState::glGenVertexArraysOES(int32_t const count, uint32_t* const arrays) {
-    Slice<VertexArrayId> l_a = slice(arrays, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_13_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_13_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        VertexArrayId l_id =
-                (VertexArrayId)(slice(arrays, (uint64_t)(0), (uint64_t)(count))[(uint64_t)(l_i)]);
-        l_ctx->mInstances.mVertexArrays[l_id] = std::shared_ptr<VertexArray>((new VertexArray()));
-        l_a[(uint64_t)(l_i)] = l_id;
-    }
-}
-
-inline void GlesState::glBindVertexArrayOES(uint32_t const array) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_14_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_14_result;
-    if (!(l_ctx->mInstances.mVertexArrays.count(array) > 0)) {
-        l_ctx->mInstances.mVertexArrays[array] = std::shared_ptr<VertexArray>((new VertexArray()));
-    }
-    l_ctx->mBoundVertexArray = array;
-}
-
-inline void GlesState::glDeleteVertexArraysOES(int32_t const count, uint32_t* const arrays) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_15_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_15_result;
-    Slice<VertexArrayId> l_a = slice(arrays, (uint64_t)(0), (uint64_t)(count));
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        l_ctx->mInstances.mVertexArrays[l_a[(uint64_t)(l_i)]] = std::shared_ptr<VertexArray>();
-    }
-}
-
-inline void GlesState::glIsVertexArrayOES(uint32_t const array, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_16_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_16_result;
-    return;
-}
-
-inline void GlesState::glEGLImageTargetTexture2DOES(uint32_t const target, void* const image) {}
-
-inline void GlesState::glEGLImageTargetRenderbufferStorageOES(uint32_t const target,
-                                                              void* const image) {}
-
-inline void GlesState::glGetGraphicsResetStatusEXT(uint32_t const result) { return; }
-
-inline void GlesState::glBindAttribLocation(uint32_t const program, uint32_t const location,
-                                            char* const name) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_17_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_17_result;
-    std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
-    l_p->mAttributeBindings[name] = location;
-}
-
-inline void GlesState::glBlendFunc(uint32_t const src_factor, uint32_t const dst_factor) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_18_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_18_result;
-    l_ctx->mBlending.mSrcRgbBlendFactor = src_factor;
-    l_ctx->mBlending.mSrcAlphaBlendFactor = src_factor;
-    l_ctx->mBlending.mDstRgbBlendFactor = dst_factor;
-    l_ctx->mBlending.mDstAlphaBlendFactor = dst_factor;
-}
-
-inline void GlesState::glBlendFuncSeparate(uint32_t const src_factor_rgb,
-                                           uint32_t const dst_factor_rgb,
-                                           uint32_t const src_factor_alpha,
-                                           uint32_t const dst_factor_alpha) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_19_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_19_result;
-    l_ctx->mBlending.mSrcRgbBlendFactor = src_factor_rgb;
-    l_ctx->mBlending.mDstRgbBlendFactor = dst_factor_rgb;
-    l_ctx->mBlending.mSrcAlphaBlendFactor = src_factor_alpha;
-    l_ctx->mBlending.mDstAlphaBlendFactor = dst_factor_alpha;
-}
-
-inline void GlesState::glBlendEquation(uint32_t const equation) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_20_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_20_result;
-    l_ctx->mBlending.mBlendEquationRgb = equation;
-    l_ctx->mBlending.mBlendEquationAlpha = equation;
-}
-
-inline void GlesState::glBlendEquationSeparate(uint32_t const rgb, uint32_t const alpha) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_21_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_21_result;
-    l_ctx->mBlending.mBlendEquationRgb = rgb;
-    l_ctx->mBlending.mBlendEquationAlpha = alpha;
-}
-
-inline void GlesState::glBlendColor(float const red, float const green, float const blue,
-                                    float const alpha) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_22_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_22_result;
-    l_ctx->mBlending.mBlendColor =
-            Color().SetRed(red).SetGreen(green).SetBlue(blue).SetAlpha(alpha);
-}
-
-inline void GlesState::glEnableVertexAttribArray(uint32_t const location) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_23_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_23_result;
-    l_ctx->mVertexAttributeArrays[location]->mEnabled = true;
-}
-
-inline void GlesState::glDisableVertexAttribArray(uint32_t const location) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_24_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_24_result;
-    l_ctx->mVertexAttributeArrays[location]->mEnabled = false;
-}
-
-inline void GlesState::glVertexAttribPointer(uint32_t const location, int32_t const size,
-                                             uint32_t const type, bool const normalized,
-                                             int32_t const stride, void* const data) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_25_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_25_result;
-    std::shared_ptr<VertexAttributeArray> l_a = l_ctx->mVertexAttributeArrays[location];
-    l_a->mSize = (uint32_t)(size);
-    l_a->mType = type;
-    l_a->mNormalized = normalized;
-    l_a->mStride = stride;
-    l_a->mPointer = data;
-    l_a->mBuffer = l_ctx->mBoundBuffers[BufferTarget::GL_ARRAY_BUFFER];
-}
-
-inline void GlesState::glGetActiveAttrib(uint32_t const program, uint32_t const location,
-                                         int32_t const buffer_size,
-                                         int32_t* const buffer_bytes_written,
-                                         int32_t* const vector_count, uint32_t* const type,
-                                         char* const name) {}
-
-inline void GlesState::glGetActiveUniform(uint32_t const program, int32_t const location,
-                                          int32_t const buffer_size,
-                                          int32_t* const buffer_bytes_written, int32_t* const size,
-                                          uint32_t* const type, char* const name) {}
-
-inline void GlesState::glGetError(uint32_t const result) { return; }
-
-inline void GlesState::glGetProgramiv(uint32_t const program, uint32_t const parameter,
-                                      int32_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-inline void GlesState::glGetShaderiv(uint32_t const shader, uint32_t const parameter,
-                                     int32_t* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_26_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_26_result;
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
-    slice(value, 0, 1)[0] = /* clang-format off */
-    /* switch(parameter) */
-        /* case ShaderParameter::GL_SHADER_TYPE: */(((parameter) == (ShaderParameter::GL_SHADER_TYPE))) ? ((int32_t)(l_s->mType)) :
-        /* case ShaderParameter::GL_DELETE_STATUS: */(((parameter) == (ShaderParameter::GL_DELETE_STATUS))) ? (/* clang-format off */
-        /* switch(l_s->mDeletable) */
-            /* case true: */(((l_s->mDeletable) == (true))) ? (1) :
-            /* case false: */(((l_s->mDeletable) == (false))) ? (0) :
-            /* default: */ 0 /* clang-format on */)
-                            :
-                            /* case ShaderParameter::GL_COMPILE_STATUS: */ (
-                                    ((parameter) == (ShaderParameter::GL_COMPILE_STATUS)))
-                                    ? (/* clang-format off */
-        /* switch(l_s->mCompiled) */
-            /* case true: */(((l_s->mCompiled) == (true))) ? (1) :
-            /* case false: */(((l_s->mCompiled) == (false))) ? (0) :
-            /* default: */ 0 /* clang-format on */)
-                                    :
-                                    /* case ShaderParameter::GL_INFO_LOG_LENGTH: */ (
-                                            ((parameter) == (ShaderParameter::GL_INFO_LOG_LENGTH)))
-                                            ? ((int32_t)(strlen(l_s->mInfoLog)))
-                                            :
-                                            /* case ShaderParameter::GL_SHADER_SOURCE_LENGTH: */ (
-                                                    ((parameter) ==
-                                                     (ShaderParameter::GL_SHADER_SOURCE_LENGTH)))
-                                                    ? ((int32_t)(strlen(l_s->mSource)))
-                                                    :
-                                                    /* default: */ 0 /* clang-format on */;
-}
-
-inline void GlesState::glGetUniformLocation(uint32_t const program, char* const name,
-                                            UniformLocation const result) {
-    return;
-}
-
-inline void GlesState::glGetAttribLocation(uint32_t const program, char* const name,
-                                           AttributeLocation const result) {
-    return;
-}
-
-inline void GlesState::glPixelStorei(uint32_t const parameter, int32_t const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_27_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_27_result;
-    l_ctx->mPixelStorage[parameter] = value;
-}
-
-inline void GlesState::glTexParameteri(uint32_t const target, uint32_t const parameter,
-                                       int32_t const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_28_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_28_result;
-    TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
-    std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-    switch (parameter) {
-        case TextureParameter::GL_TEXTURE_MAG_FILTER: {
-            l_t->mMagFilter = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_MIN_FILTER: {
-            l_t->mMinFilter = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_WRAP_S: {
-            l_t->mWrapS = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_WRAP_T: {
-            l_t->mWrapT = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: {
-            l_t->mMaxAnisotropy = (float)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_R: {
-            l_t->mSwizzleR = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_G: {
-            l_t->mSwizzleG = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_B: {
-            l_t->mSwizzleB = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_A: {
-            l_t->mSwizzleA = (uint32_t)(value);
-            break;
-        }
-    }
-}
-
-inline void GlesState::glTexParameterf(uint32_t const target, uint32_t const parameter,
-                                       float const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_29_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_29_result;
-    TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
-    std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-    switch (parameter) {
-        case TextureParameter::GL_TEXTURE_MAG_FILTER: {
-            l_t->mMagFilter = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_MIN_FILTER: {
-            l_t->mMinFilter = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_WRAP_S: {
-            l_t->mWrapS = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_WRAP_T: {
-            l_t->mWrapT = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: {
-            l_t->mMaxAnisotropy = value;
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_R: {
-            l_t->mSwizzleR = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_G: {
-            l_t->mSwizzleG = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_B: {
-            l_t->mSwizzleB = (uint32_t)(value);
-            break;
-        }
-        case TextureParameter::GL_TEXTURE_SWIZZLE_A: {
-            l_t->mSwizzleA = (uint32_t)(value);
-            break;
-        }
-    }
-}
-
-inline void GlesState::glGetTexParameteriv(uint32_t const target, uint32_t const parameter,
-                                           int32_t* const values) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_30_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_30_result;
-    TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
-    std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-    slice(values, 0, 1)[0] = /* clang-format off */
-    /* switch(parameter) */
-        /* case TextureParameter::GL_TEXTURE_MAG_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MAG_FILTER))) ? ((int32_t)(l_t->mMagFilter)) :
-        /* case TextureParameter::GL_TEXTURE_MIN_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MIN_FILTER))) ? ((int32_t)(l_t->mMinFilter)) :
-        /* case TextureParameter::GL_TEXTURE_WRAP_S: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_S))) ? ((int32_t)(l_t->mWrapS)) :
-        /* case TextureParameter::GL_TEXTURE_WRAP_T: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_T))) ? ((int32_t)(l_t->mWrapT)) :
-        /* case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: */(((parameter) == (TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT))) ? ((int32_t)(l_t->mMaxAnisotropy)) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_R: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_R))) ? ((int32_t)(l_t->mSwizzleR)) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_G: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_G))) ? ((int32_t)(l_t->mSwizzleG)) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_B: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_B))) ? ((int32_t)(l_t->mSwizzleB)) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_A: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_A))) ? ((int32_t)(l_t->mSwizzleA)) :
-        /* default: */ 0 /* clang-format on */;
-}
-
-inline void GlesState::glGetTexParameterfv(uint32_t const target, uint32_t const parameter,
-                                           float* const values) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_31_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_31_result;
-    TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target];
-    std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-    slice(values, 0, 1)[0] = /* clang-format off */
-    /* switch(parameter) */
-        /* case TextureParameter::GL_TEXTURE_MAG_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MAG_FILTER))) ? ((float)(l_t->mMagFilter)) :
-        /* case TextureParameter::GL_TEXTURE_MIN_FILTER: */(((parameter) == (TextureParameter::GL_TEXTURE_MIN_FILTER))) ? ((float)(l_t->mMinFilter)) :
-        /* case TextureParameter::GL_TEXTURE_WRAP_S: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_S))) ? ((float)(l_t->mWrapS)) :
-        /* case TextureParameter::GL_TEXTURE_WRAP_T: */(((parameter) == (TextureParameter::GL_TEXTURE_WRAP_T))) ? ((float)(l_t->mWrapT)) :
-        /* case TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT: */(((parameter) == (TextureParameter::GL_TEXTURE_MAX_ANISOTROPY_EXT))) ? (l_t->mMaxAnisotropy) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_R: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_R))) ? ((float)(l_t->mSwizzleR)) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_G: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_G))) ? ((float)(l_t->mSwizzleG)) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_B: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_B))) ? ((float)(l_t->mSwizzleB)) :
-        /* case TextureParameter::GL_TEXTURE_SWIZZLE_A: */(((parameter) == (TextureParameter::GL_TEXTURE_SWIZZLE_A))) ? ((float)(l_t->mSwizzleA)) :
-        /* default: */ 0 /* clang-format on */;
-}
-
-inline void GlesState::glUniform1i(int32_t const location, int32_t const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_32_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_32_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT;
-    l_uniform.mValue.mS32 = value;
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform2i(int32_t const location, int32_t const value0,
-                                   int32_t const value1) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_33_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_33_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT_VEC2;
-    l_uniform.mValue.mVec2i = Vec2i().SetX(value0).SetY(value1);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform3i(int32_t const location, int32_t const value0,
-                                   int32_t const value1, int32_t const value2) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_34_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_34_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT_VEC3;
-    l_uniform.mValue.mVec3i = Vec3i().SetX(value0).SetY(value1).SetZ(value2);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform4i(int32_t const location, int32_t const value0,
-                                   int32_t const value1, int32_t const value2,
-                                   int32_t const value3) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_35_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_35_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT_VEC4;
-    l_uniform.mValue.mVec4i = Vec4i().SetX(value0).SetY(value1).SetZ(value2).SetW(value3);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform1iv(int32_t const location, int32_t const count,
-                                    int32_t* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_36_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_36_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT;
-    l_uniform.mValue.mS32 = slice(value, 0, 1)[0];
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform2iv(int32_t const location, int32_t const count,
-                                    int32_t* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_37_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_37_result;
-    Slice<int32_t> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 2));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT_VEC2;
-    l_uniform.mValue.mVec2i = Vec2i().SetX(l_v[0]).SetY(l_v[1]);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform3iv(int32_t const location, int32_t const count,
-                                    int32_t* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_38_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_38_result;
-    Slice<int32_t> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 3));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT_VEC3;
-    l_uniform.mValue.mVec3i = Vec3i().SetX(l_v[0]).SetY(l_v[1]).SetZ(l_v[2]);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform4iv(int32_t const location, int32_t const count,
-                                    int32_t* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_39_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_39_result;
-    Slice<int32_t> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 4));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_INT_VEC4;
-    l_uniform.mValue.mVec4i = Vec4i().SetX(l_v[0]).SetY(l_v[1]).SetZ(l_v[2]).SetW(l_v[3]);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform1f(int32_t const location, float const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_40_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_40_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT;
-    l_uniform.mValue.mF32 = value;
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform2f(int32_t const location, float const value0, float const value1) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_41_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_41_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC2;
-    l_uniform.mValue.mVec2f = Vec2f().SetX(value0).SetY(value1);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform3f(int32_t const location, float const value0, float const value1,
-                                   float const value2) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_42_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_42_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC3;
-    l_uniform.mValue.mVec3f = Vec3f().SetX(value0).SetY(value1).SetZ(value2);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform4f(int32_t const location, float const value0, float const value1,
-                                   float const value2, float const value3) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_43_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_43_result;
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC4;
-    l_uniform.mValue.mVec4f = Vec4f().SetX(value0).SetY(value1).SetZ(value2).SetW(value3);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform1fv(int32_t const location, int32_t const count,
-                                    float* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_44_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_44_result;
-    Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT;
-    l_uniform.mValue.mF32 = l_v[0];
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform2fv(int32_t const location, int32_t const count,
-                                    float* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_45_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_45_result;
-    Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 2));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC2;
-    l_uniform.mValue.mVec2f = Vec2f().SetX(l_v[0]).SetY(l_v[1]);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform3fv(int32_t const location, int32_t const count,
-                                    float* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_46_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_46_result;
-    Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 3));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC3;
-    l_uniform.mValue.mVec3f = Vec3f().SetX(l_v[0]).SetY(l_v[1]).SetZ(l_v[2]);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniform4fv(int32_t const location, int32_t const count,
-                                    float* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_47_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_47_result;
-    Slice<float> l_v = slice(value, (uint64_t)(0), (uint64_t)(count * 4));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_VEC4;
-    l_uniform.mValue.mVec4f = Vec4f().SetX(l_v[0]).SetY(l_v[1]).SetZ(l_v[2]).SetW(l_v[3]);
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniformMatrix2fv(int32_t const location, int32_t const count,
-                                          bool const transpose, float* const values) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_48_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_48_result;
-    Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(count * 4));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_MAT2;
-    l_uniform.mValue.mMat2f = Mat2f()
-                                      .SetCol0(Vec2f().SetX(l_v[0]).SetY(l_v[1]))
-                                      .SetCol1(Vec2f().SetX(l_v[3]).SetY(l_v[4]));
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniformMatrix3fv(int32_t const location, int32_t const count,
-                                          bool const transpose, float* const values) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_49_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_49_result;
-    Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(count * 9));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mType = ShaderUniformType::GL_FLOAT_MAT3;
-    l_uniform.mValue.mMat3f = Mat3f()
-                                      .SetCol0(Vec3f().SetX(l_v[0]).SetY(l_v[1]).SetZ(l_v[2]))
-                                      .SetCol1(Vec3f().SetX(l_v[3]).SetY(l_v[4]).SetZ(l_v[5]))
-                                      .SetCol2(Vec3f().SetX(l_v[6]).SetY(l_v[7]).SetZ(l_v[8]));
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glUniformMatrix4fv(int32_t const location, int32_t const count,
-                                          bool const transpose, float* const values) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_50_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_50_result;
-    Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(count * 16));
-    std::shared_ptr<Program> l_program = l_ctx->mInstances.mPrograms[l_ctx->mBoundProgram];
-    Uniform l_uniform = l_program->mUniforms[location];
-    l_uniform.mValue.mMat4f =
-            Mat4f()
-                    .SetCol0(Vec4f().SetX(l_v[0]).SetY(l_v[1]).SetZ(l_v[2]).SetW(l_v[3]))
-                    .SetCol1(Vec4f().SetX(l_v[4]).SetY(l_v[5]).SetZ(l_v[6]).SetW(l_v[7]))
-                    .SetCol2(Vec4f().SetX(l_v[8]).SetY(l_v[9]).SetZ(l_v[10]).SetW(l_v[11]))
-                    .SetCol3(Vec4f().SetX(l_v[12]).SetY(l_v[13]).SetZ(l_v[14]).SetW(l_v[15]));
-    l_program->mUniforms[location] = l_uniform;
-}
-
-inline void GlesState::glGetUniformfv(uint32_t const program, int32_t const location,
-                                      float* const values) {}
-
-inline void GlesState::glGetUniformiv(uint32_t const program, int32_t const location,
-                                      int32_t* const values) {}
-
-inline void GlesState::glVertexAttrib1f(uint32_t const location, float const value0) {}
-
-inline void GlesState::glVertexAttrib2f(uint32_t const location, float const value0,
-                                        float const value1) {}
-
-inline void GlesState::glVertexAttrib3f(uint32_t const location, float const value0,
-                                        float const value1, float const value2) {}
-
-inline void GlesState::glVertexAttrib4f(uint32_t const location, float const value0,
-                                        float const value1, float const value2,
-                                        float const value3) {}
-
-inline void GlesState::glVertexAttrib1fv(uint32_t const location, float* const value) {
-    read(slice(value, 0, 1));
-}
-
-inline void GlesState::glVertexAttrib2fv(uint32_t const location, float* const value) {
-    read(slice(value, 0, 2));
-}
-
-inline void GlesState::glVertexAttrib3fv(uint32_t const location, float* const value) {
-    read(slice(value, 0, 3));
-}
-
-inline void GlesState::glVertexAttrib4fv(uint32_t const location, float* const value) {
-    read(slice(value, 0, 4));
-}
-
-inline void GlesState::glGetShaderPrecisionFormat(uint32_t const shader_type,
-                                                  uint32_t const precision_type,
-                                                  int32_t* const range, int32_t* const precision) {
-    write(slice(range, 0, 2));
-    slice(precision, 0, 1)[0] = slice(precision, 0, 1)[0];
-}
-
-inline void GlesState::glDepthMask(bool const enabled) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_51_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_51_result;
-    l_ctx->mRasterizing.mDepthMask = enabled;
-}
-
-inline void GlesState::glDepthFunc(uint32_t const function) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_52_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_52_result;
-    l_ctx->mRasterizing.mDepthTestFunction = function;
-}
-
-inline void GlesState::glDepthRangef(float const near, float const far) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_53_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_53_result;
-    l_ctx->mRasterizing.mDepthNear = near;
-    l_ctx->mRasterizing.mDepthFar = far;
-}
-
-inline void GlesState::glColorMask(bool const red, bool const green, bool const blue,
-                                   bool const alpha) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_54_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_54_result;
-    l_ctx->mRasterizing.mColorMaskRed = red;
-    l_ctx->mRasterizing.mColorMaskGreen = green;
-    l_ctx->mRasterizing.mColorMaskBlue = blue;
-    l_ctx->mRasterizing.mColorMaskAlpha = alpha;
-}
-
-inline void GlesState::glStencilMask(uint32_t const mask) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_55_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_55_result;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = mask;
-    l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = mask;
-}
-
-inline void GlesState::glStencilMaskSeparate(uint32_t const face, uint32_t const mask) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_56_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_56_result;
-    switch (face) {
-        case FaceMode::GL_FRONT: {
-            l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = mask;
-            break;
-        }
-        case FaceMode::GL_BACK: {
-            l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = mask;
-            break;
-        }
-        case FaceMode::GL_FRONT_AND_BACK: {
-            l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT] = mask;
-            l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK] = mask;
-            break;
-        }
-    }
-}
-
-inline void GlesState::glStencilFuncSeparate(uint32_t const face, uint32_t const function,
-                                             int32_t const reference_value, int32_t const mask) {}
-
-inline void GlesState::glStencilOpSeparate(uint32_t const face, uint32_t const stencil_fail,
-                                           uint32_t const stencil_pass_depth_fail,
-                                           uint32_t const stencil_pass_depth_pass) {}
-
-inline void GlesState::glFrontFace(uint32_t const orientation) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_57_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_57_result;
-    l_ctx->mRasterizing.mFrontFace = orientation;
-}
-
-inline void GlesState::glViewport(int32_t const x, int32_t const y, int32_t const width,
-                                  int32_t const height) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_58_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_58_result;
-    l_ctx->mRasterizing.mViewport = Rect().SetX(x).SetY(y).SetWidth(width).SetHeight(height);
-}
-
-inline void GlesState::glScissor(int32_t const x, int32_t const y, int32_t const width,
-                                 int32_t const height) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_59_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_59_result;
-    l_ctx->mRasterizing.mScissor = Rect().SetX(x).SetY(y).SetWidth(width).SetHeight(height);
-}
-
-inline void GlesState::glActiveTexture(uint32_t const unit) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_60_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_60_result;
-    l_ctx->mActiveTextureUnit = unit;
-    if (!(l_ctx->mTextureUnits.count(unit) > 0)) {
-        l_ctx->mTextureUnits[unit] = l_ctx->mTextureUnits[unit];
-    }
-}
-
-inline void GlesState::glGenTextures(int32_t const count, uint32_t* const textures) {
-    Slice<TextureId> l_t = slice(textures, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_61_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_61_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        TextureId l_id =
-                (TextureId)(slice(textures, (uint64_t)(0), (uint64_t)(count))[(uint64_t)(l_i)]);
-        l_ctx->mInstances.mTextures[l_id] = std::shared_ptr<Texture>((new Texture()));
-        l_t[(uint64_t)(l_i)] = l_id;
-    }
-}
-
-inline void GlesState::glDeleteTextures(int32_t const count, uint32_t* const textures) {
-    Slice<TextureId> l_t = slice(textures, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_62_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_62_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        l_ctx->mInstances.mTextures[l_t[(uint64_t)(l_i)]] = std::shared_ptr<Texture>();
-    }
-}
-
-inline void GlesState::glIsTexture(uint32_t const texture, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_63_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_63_result;
-    return;
-}
-
-inline void GlesState::glBindTexture(uint32_t const target, uint32_t const texture) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_64_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_64_result;
-    if (!(l_ctx->mInstances.mTextures.count(texture) > 0)) {
-        l_ctx->mInstances.mTextures[texture] = std::shared_ptr<Texture>((new Texture()));
-    }
-    l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][target] = texture;
-}
-
-inline void GlesState::glTexImage2D(uint32_t const target, int32_t const level,
-                                    uint32_t const internal_format, int32_t const width,
-                                    int32_t const height, int32_t const border,
-                                    uint32_t const format, uint32_t const type, void* const data) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_65_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_65_result;
-    switch (target) {
-        case TextureImageTarget::GL_TEXTURE_2D: {
-            TextureId l_id =
-                    l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][TextureTarget::GL_TEXTURE_2D];
-            std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-            Image l_l =
-                    Image()
-                            .SetWidth(width)
-                            .SetHeight(height)
-                            .SetSize(imageSize((uint32_t)(width), (uint32_t)(height), format, type))
-                            .SetFormat((uint32_t)(format));
-            if (data != nullptr) {
-                if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0)) {
-                    l_l.mData =
-                            clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
-                }
-            } else {
-                l_l.mData = make<uint8_t>((uint64_t)(l_l.mSize));
-            }
-            l_t->mTexture2D[level] = l_l;
-            l_t->mKind = TextureKind::TEXTURE2D;
-            l_t->mFormat = (uint32_t)(format);
-            break;
-        }
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: {
-            TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
-                                                 [TextureTarget::GL_TEXTURE_CUBE_MAP];
-            std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-            Image l_l =
-                    Image()
-                            .SetWidth(width)
-                            .SetHeight(height)
-                            .SetSize(imageSize((uint32_t)(width), (uint32_t)(height), format, type))
-                            .SetFormat((uint32_t)(format));
-            if (data != nullptr) {
-                if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0)) {
-                    l_l.mData =
-                            clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
-                }
-            } else {
-                l_l.mData = make<uint8_t>((uint64_t)(l_l.mSize));
-            }
-            CubemapLevel l_cube = l_t->mCubemap[level];
-            l_cube.mFaces[(uint32_t)(target)] = l_l;
-            l_t->mCubemap[level] = l_cube;
-            l_t->mKind = TextureKind::CUBEMAP;
-            l_t->mFormat = (uint32_t)(format);
-            break;
-        }
-    }
-}
-
-inline void GlesState::glTexSubImage2D(uint32_t const target, int32_t const level,
-                                       int32_t const xoffset, int32_t const yoffset,
-                                       int32_t const width, int32_t const height,
-                                       uint32_t const format, uint32_t const type,
-                                       void* const data) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_66_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_66_result;
-    switch (target) {
-        case TextureImageTarget::GL_TEXTURE_2D: {
-            TextureId l_id =
-                    l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][TextureTarget::GL_TEXTURE_2D];
-            std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-            Image l_l =
-                    Image()
-                            .SetWidth(width)
-                            .SetHeight(height)
-                            .SetSize(imageSize((uint32_t)(width), (uint32_t)(height), format, type))
-                            .SetFormat((uint32_t)(format));
-            if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
-                data != nullptr) {
-                l_l.mData = clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
-            }
-            l_t->mTexture2D[level] = l_l;
-            l_t->mKind = TextureKind::TEXTURE2D;
-            l_t->mFormat = (uint32_t)(format);
-            break;
-        }
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: {
-            TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
-                                                 [TextureTarget::GL_TEXTURE_CUBE_MAP];
-            std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-            Image l_l =
-                    Image()
-                            .SetWidth(width)
-                            .SetHeight(height)
-                            .SetSize(imageSize((uint32_t)(width), (uint32_t)(height), format, type))
-                            .SetFormat((uint32_t)(format));
-            if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
-                data != nullptr) {
-                l_l.mData = clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
-            }
-            CubemapLevel l_cube = l_t->mCubemap[level];
-            l_cube.mFaces[(uint32_t)(target)] = l_l;
-            l_t->mCubemap[level] = l_cube;
-            l_t->mKind = TextureKind::CUBEMAP;
-            l_t->mFormat = (uint32_t)(format);
-            break;
-        }
-    }
-}
-
-inline void GlesState::glCopyTexImage2D(uint32_t const target, int32_t const level,
-                                        uint32_t const format, int32_t const x, int32_t const y,
-                                        int32_t const width, int32_t const height,
-                                        int32_t const border) {}
-
-inline void GlesState::glCopyTexSubImage2D(uint32_t const target, int32_t const level,
-                                           int32_t const xoffset, int32_t const yoffset,
-                                           int32_t const x, int32_t const y, int32_t const width,
-                                           int32_t const height) {}
-
-inline void GlesState::glCompressedTexImage2D(uint32_t const target, int32_t const level,
-                                              uint32_t const format, int32_t const width,
-                                              int32_t const height, int32_t const border,
-                                              int32_t const image_size, void* const data) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_67_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_67_result;
-    switch (target) {
-        case TextureImageTarget::GL_TEXTURE_2D: {
-            TextureId l_id =
-                    l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][TextureTarget::GL_TEXTURE_2D];
-            std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-            Image l_l = Image()
-                                .SetWidth(width)
-                                .SetHeight(height)
-                                .SetSize((uint32_t)(image_size))
-                                .SetFormat((uint32_t)(format));
-            if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
-                data != nullptr) {
-                l_l.mData = clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
-            }
-            l_t->mTexture2D[level] = l_l;
-            l_t->mKind = TextureKind::TEXTURE2D;
-            l_t->mFormat = (uint32_t)(format);
-            break;
-        }
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:  // fall-through...
-        case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: {
-            TextureId l_id = l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
-                                                 [TextureTarget::GL_TEXTURE_CUBE_MAP];
-            std::shared_ptr<Texture> l_t = l_ctx->mInstances.mTextures[l_id];
-            Image l_l = Image()
-                                .SetWidth(width)
-                                .SetHeight(height)
-                                .SetSize((uint32_t)(image_size))
-                                .SetFormat((uint32_t)(format));
-            if (l_ctx->mBoundBuffers[BufferTarget::GL_PIXEL_UNPACK_BUFFER] == (BufferId)(0) &&
-                data != nullptr) {
-                l_l.mData = clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(l_l.mSize)));
-            }
-            CubemapLevel l_cube = l_t->mCubemap[level];
-            l_cube.mFaces[(uint32_t)(target)] = l_l;
-            l_t->mCubemap[level] = l_cube;
-            l_t->mKind = TextureKind::CUBEMAP;
-            l_t->mFormat = (uint32_t)(format);
-            break;
-        }
-    }
-}
-
-inline void GlesState::glCompressedTexSubImage2D(uint32_t const target, int32_t const level,
-                                                 int32_t const xoffset, int32_t const yoffset,
-                                                 int32_t const width, int32_t const height,
-                                                 uint32_t const format, int32_t const image_size,
-                                                 void* const data) {}
-
-inline void GlesState::glGenerateMipmap(uint32_t const target) {}
-
-inline void GlesState::glReadPixels(int32_t const x, int32_t const y, int32_t const width,
-                                    int32_t const height, uint32_t const format,
-                                    uint32_t const type, void* const data) {
-    write(slice(data, (uint64_t)(0), (uint64_t)(imageSize((uint32_t)(width), (uint32_t)(height),
-                                                          (uint32_t)(format), type))));
-}
-
-inline void GlesState::glGenFramebuffers(int32_t const count, uint32_t* const framebuffers) {
-    Slice<FramebufferId> l_f = slice(framebuffers, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_68_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_68_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        FramebufferId l_id = (FramebufferId)(
-                slice(framebuffers, (uint64_t)(0), (uint64_t)(count))[(uint64_t)(l_i)]);
-        l_ctx->mInstances.mFramebuffers[l_id] = std::shared_ptr<Framebuffer>((new Framebuffer()));
-        l_f[(uint64_t)(l_i)] = l_id;
-    }
-}
-
-inline void GlesState::glBindFramebuffer(uint32_t const target, uint32_t const framebuffer) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_69_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_69_result;
-    if (!(l_ctx->mInstances.mFramebuffers.count(framebuffer) > 0)) {
-        l_ctx->mInstances.mFramebuffers[framebuffer] =
-                std::shared_ptr<Framebuffer>((new Framebuffer()));
-    }
-    if (target == FramebufferTarget::GL_FRAMEBUFFER) {
-        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER] = framebuffer;
-        l_ctx->mBoundFramebuffers[FramebufferTarget::GL_DRAW_FRAMEBUFFER] = framebuffer;
-    } else {
-        l_ctx->mBoundFramebuffers[target] = framebuffer;
-    }
-}
-
-inline void GlesState::glCheckFramebufferStatus(uint32_t const target, uint32_t const result) {
-    return;
-}
-
-inline void GlesState::glDeleteFramebuffers(int32_t const count, uint32_t* const framebuffers) {
-    Slice<FramebufferId> l_f = slice(framebuffers, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_70_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_70_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        l_ctx->mInstances.mFramebuffers[l_f[(uint64_t)(l_i)]] = std::shared_ptr<Framebuffer>();
-    }
-}
-
-inline void GlesState::glIsFramebuffer(uint32_t const framebuffer, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_71_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_71_result;
-    return;
-}
-
-inline void GlesState::glGenRenderbuffers(int32_t const count, uint32_t* const renderbuffers) {
-    Slice<RenderbufferId> l_r = slice(renderbuffers, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_72_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_72_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        RenderbufferId l_id = (RenderbufferId)(
-                slice(renderbuffers, (uint64_t)(0), (uint64_t)(count))[(uint64_t)(l_i)]);
-        l_ctx->mInstances.mRenderbuffers[l_id] =
-                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-        l_r[(uint64_t)(l_i)] = l_id;
-    }
-}
-
-inline void GlesState::glBindRenderbuffer(uint32_t const target, uint32_t const renderbuffer) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_73_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_73_result;
-    if (!(l_ctx->mInstances.mRenderbuffers.count(renderbuffer) > 0)) {
-        l_ctx->mInstances.mRenderbuffers[renderbuffer] =
-                std::shared_ptr<Renderbuffer>((new Renderbuffer()));
-    }
-    l_ctx->mBoundRenderbuffers[target] = renderbuffer;
-}
-
-inline void GlesState::glRenderbufferStorage(uint32_t const target, uint32_t const format,
-                                             int32_t const width, int32_t const height) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_74_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_74_result;
-    RenderbufferId l_id = l_ctx->mBoundRenderbuffers[target];
-    std::shared_ptr<Renderbuffer> l_rb = l_ctx->mInstances.mRenderbuffers[l_id];
-    l_rb->mFormat = format;
-    l_rb->mWidth = width;
-    l_rb->mHeight = height;
-}
-
-inline void GlesState::glDeleteRenderbuffers(int32_t const count, uint32_t* const renderbuffers) {
-    Slice<RenderbufferId> l_r = slice(renderbuffers, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_75_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_75_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        l_ctx->mInstances.mRenderbuffers[l_r[(uint64_t)(l_i)]] = std::shared_ptr<Renderbuffer>();
-    }
-}
-
-inline void GlesState::glIsRenderbuffer(uint32_t const renderbuffer, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_76_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_76_result;
-    return;
-}
-
-inline void GlesState::glGetRenderbufferParameteriv(uint32_t const target, uint32_t const parameter,
-                                                    int32_t* const values) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_77_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_77_result;
-    RenderbufferId l_id = l_ctx->mBoundRenderbuffers[target];
-    std::shared_ptr<Renderbuffer> l_rb = l_ctx->mInstances.mRenderbuffers[l_id];
-    slice(values, 0, 1)[0] = /* clang-format off */
-    /* switch(parameter) */
-        /* case RenderbufferParameter::GL_RENDERBUFFER_WIDTH: */(((parameter) == (RenderbufferParameter::GL_RENDERBUFFER_WIDTH))) ? (l_rb->mWidth) :
-        /* case RenderbufferParameter::GL_RENDERBUFFER_HEIGHT: */(((parameter) == (RenderbufferParameter::GL_RENDERBUFFER_HEIGHT))) ? (l_rb->mHeight) :
-        /* case RenderbufferParameter::GL_RENDERBUFFER_INTERNAL_FORMAT: */(((parameter) == (RenderbufferParameter::GL_RENDERBUFFER_INTERNAL_FORMAT))) ? ((int32_t)(l_rb->mFormat)) :
-        /* default: */ 0 /* clang-format on */;
-}
-
-inline void GlesState::glGenBuffers(int32_t const count, uint32_t* const buffers) {
-    Slice<BufferId> l_b = slice(buffers, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_78_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_78_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        BufferId l_id =
-                (BufferId)(slice(buffers, (uint64_t)(0), (uint64_t)(count))[(uint64_t)(l_i)]);
-        l_ctx->mInstances.mBuffers[l_id] = std::shared_ptr<Buffer>((new Buffer()));
-        l_b[(uint64_t)(l_i)] = l_id;
-    }
-}
-
-inline void GlesState::glBindBuffer(uint32_t const target, uint32_t const buffer) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_79_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_79_result;
-    if (!(l_ctx->mInstances.mBuffers.count(buffer) > 0)) {
-        l_ctx->mInstances.mBuffers[buffer] = std::shared_ptr<Buffer>((new Buffer()));
-    }
-    l_ctx->mBoundBuffers[target] = buffer;
-}
-
-inline void GlesState::glBufferData(uint32_t const target, int32_t const size, void* const data,
-                                    uint32_t const usage) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_80_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_80_result;
-    BufferId l_id = l_ctx->mBoundBuffers[target];
-    std::shared_ptr<Buffer> l_b = l_ctx->mInstances.mBuffers[l_id];
-    l_b->mData = /* clang-format off */
-    /* switch(data != nullptr) */
-        /* case true: */(((data != nullptr) == (true))) ? (clone(slice((uint8_t*)(data), (uint64_t)(0), (uint64_t)(size)))) :
-        /* case false: */(((data != nullptr) == (false))) ? (make<uint8_t>((uint64_t)(size))) :
-        /* default: */ Slice<uint8_t>() /* clang-format on */;
-    l_b->mSize = size;
-    l_b->mUsage = usage;
-}
-
-inline void GlesState::glBufferSubData(uint32_t const target, int32_t const offset,
-                                       int32_t const size, void* const data) {
-    read(slice(data, (uint64_t)(0), (uint64_t)(size)));
-}
-
-inline void GlesState::glDeleteBuffers(int32_t const count, uint32_t* const buffers) {
-    Slice<BufferId> l_b = slice(buffers, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_81_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_81_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        l_ctx->mInstances.mBuffers[l_b[(uint64_t)(l_i)]] = std::shared_ptr<Buffer>();
-    }
-}
-
-inline void GlesState::glIsBuffer(uint32_t const buffer, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_82_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_82_result;
-    return;
-}
-
-inline void GlesState::glGetBufferParameteriv(uint32_t const target, uint32_t const parameter,
-                                              int32_t* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_83_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_83_result;
-    BufferId l_id = l_ctx->mBoundBuffers[target];
-    std::shared_ptr<Buffer> l_b = l_ctx->mInstances.mBuffers[l_id];
-    slice(value, 0, 1)[0] = /* clang-format off */
-    /* switch(parameter) */
-        /* case BufferParameter::GL_BUFFER_SIZE: */(((parameter) == (BufferParameter::GL_BUFFER_SIZE))) ? (l_b->mSize) :
-        /* case BufferParameter::GL_BUFFER_USAGE: */(((parameter) == (BufferParameter::GL_BUFFER_USAGE))) ? ((int32_t)(l_b->mUsage)) :
-        /* default: */ 0 /* clang-format on */;
-}
-
-inline void GlesState::glCreateShader(uint32_t const type, ShaderId const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_84_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_84_result;
-    ShaderId l_id = (ShaderId)(result);
-    l_ctx->mInstances.mShaders[l_id] = std::shared_ptr<Shader>((new Shader()));
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[l_id];
-    l_s->mType = type;
-    return;
-}
-
-inline void GlesState::glDeleteShader(uint32_t const shader) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_85_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_85_result;
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
-    l_s->mDeletable = true;
-    l_ctx->mInstances.mShaders[shader] = std::shared_ptr<Shader>();
-}
-
-inline void GlesState::glShaderSource(uint32_t const shader, int32_t const count,
-                                      char** const source, int32_t* const length) {
-    Slice<char*> l_sources = slice(source, (uint64_t)(0), (uint64_t)(count));
-    Slice<int32_t> l_lengths = slice(length, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_86_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_86_result;
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        uint32_t l_l = /* clang-format off */
-        /* switch(length == nullptr || l_lengths[(uint64_t)(l_i)] < 0) */
-            /* case true: */(((length == nullptr || l_lengths[(uint64_t)(l_i)] < 0) == (true))) ? (strlen(l_sources[(uint64_t)(l_i)])) :
-            /* case false: */(((length == nullptr || l_lengths[(uint64_t)(l_i)] < 0) == (false))) ? ((uint32_t)(l_lengths[(uint64_t)(l_i)])) :
-            /* default: */ 0 /* clang-format on */;
-        l_s->mSource += string(slice(l_sources[(uint64_t)(l_i)], (uint64_t)(0), (uint64_t)(l_l)));
-    }
-}
-
-inline void GlesState::glShaderBinary(int32_t const count, uint32_t* const shaders,
-                                      uint32_t const binary_format, void* const binary,
-                                      int32_t const binary_size) {
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-    }
-}
-
-inline void GlesState::glGetShaderInfoLog(uint32_t const shader, int32_t const buffer_length,
-                                          int32_t* const string_length_written, char* const info) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_87_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_87_result;
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
-    int32_t l_min_88_a = buffer_length;
-    int32_t l_min_88_b = (int32_t)(strlen(l_s->mInfoLog));
-    int32_t l_min_88_result = /* clang-format off */
-    /* switch(l_min_88_a < l_min_88_b) */
-        /* case true: */(((l_min_88_a < l_min_88_b) == (true))) ? (l_min_88_a) :
-        /* case false: */(((l_min_88_a < l_min_88_b) == (false))) ? (l_min_88_b) :
-        /* default: */ 0 /* clang-format on */;
-    int32_t l_l = l_min_88_result;
-    slice(string_length_written, 0, 1)[0] = l_l;
-    copy(slice(info, (uint64_t)(0), (uint64_t)(l_l)),
-         slice(l_s->mInfoLog, (uint64_t)(0), (uint64_t)(l_l)));
-}
-
-inline void GlesState::glGetShaderSource(uint32_t const shader, int32_t const buffer_length,
-                                         int32_t* const string_length_written, char* const source) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_89_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_89_result;
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
-    int32_t l_min_90_a = buffer_length;
-    int32_t l_min_90_b = (int32_t)(strlen(l_s->mSource));
-    int32_t l_min_90_result = /* clang-format off */
-    /* switch(l_min_90_a < l_min_90_b) */
-        /* case true: */(((l_min_90_a < l_min_90_b) == (true))) ? (l_min_90_a) :
-        /* case false: */(((l_min_90_a < l_min_90_b) == (false))) ? (l_min_90_b) :
-        /* default: */ 0 /* clang-format on */;
-    int32_t l_l = l_min_90_result;
-    slice(string_length_written, 0, 1)[0] = l_l;
-    copy(slice(source, (uint64_t)(0), (uint64_t)(l_l)),
-         slice(slice(l_s->mSource), (uint64_t)(0), (uint64_t)(l_l)));
-}
-
-inline void GlesState::glReleaseShaderCompiler() {}
-
-inline void GlesState::glCompileShader(uint32_t const shader) {}
-
-inline void GlesState::glIsShader(uint32_t const shader, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_91_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_91_result;
-    return;
-}
-
-inline void GlesState::glCreateProgram(ProgramId const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_92_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_92_result;
-    ProgramId l_id = (ProgramId)(result);
-    l_ctx->mInstances.mPrograms[l_id] = std::shared_ptr<Program>((new Program()));
-    return;
-}
-
-inline void GlesState::glDeleteProgram(uint32_t const program) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_93_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_93_result;
-    l_ctx->mInstances.mPrograms[program] = std::shared_ptr<Program>();
-}
-
-inline void GlesState::glAttachShader(uint32_t const program, uint32_t const shader) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_94_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_94_result;
-    std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
-    l_p->mShaders[l_s->mType] = shader;
-}
-
-inline void GlesState::glDetachShader(uint32_t const program, uint32_t const shader) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_95_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_95_result;
-    std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
-    std::shared_ptr<Shader> l_s = l_ctx->mInstances.mShaders[shader];
-    l_p->mShaders[l_s->mType] = 0;
-}
-
-inline void GlesState::glGetAttachedShaders(uint32_t const program, int32_t const buffer_length,
-                                            int32_t* const shaders_length_written,
-                                            uint32_t* const shaders) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_96_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_96_result;
-    std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
-    int32_t l_min_97_a = buffer_length;
-    int32_t l_min_97_b = l_p->mShaders.size();
-    int32_t l_min_97_result = /* clang-format off */
-    /* switch(l_min_97_a < l_min_97_b) */
-        /* case true: */(((l_min_97_a < l_min_97_b) == (true))) ? (l_min_97_a) :
-        /* case false: */(((l_min_97_a < l_min_97_b) == (false))) ? (l_min_97_b) :
-        /* default: */ 0 /* clang-format on */;
-    int32_t l_l = l_min_97_result;
-    slice(shaders_length_written, 0, 1)[0] = l_l;
-}
-
-inline void GlesState::glLinkProgram(uint32_t const program) {}
-
-inline void GlesState::glGetProgramInfoLog(uint32_t const program, int32_t const buffer_length,
-                                           int32_t* const string_length_written, char* const info) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_98_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_98_result;
-    std::shared_ptr<Program> l_p = l_ctx->mInstances.mPrograms[program];
-    int32_t l_min_99_a = buffer_length;
-    int32_t l_min_99_b = (int32_t)(strlen(l_p->mInfoLog));
-    int32_t l_min_99_result = /* clang-format off */
-    /* switch(l_min_99_a < l_min_99_b) */
-        /* case true: */(((l_min_99_a < l_min_99_b) == (true))) ? (l_min_99_a) :
-        /* case false: */(((l_min_99_a < l_min_99_b) == (false))) ? (l_min_99_b) :
-        /* default: */ 0 /* clang-format on */;
-    int32_t l_l = l_min_99_result;
-    slice(string_length_written, 0, 1)[0] = l_l;
-    copy(slice(info, (uint64_t)(0), (uint64_t)(l_l)),
-         slice(l_p->mInfoLog, (uint64_t)(0), (uint64_t)(l_l)));
-}
-
-inline void GlesState::glUseProgram(uint32_t const program) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_100_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_100_result;
-    l_ctx->mBoundProgram = program;
-}
-
-inline void GlesState::glIsProgram(uint32_t const program, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_101_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_101_result;
-    return;
-}
-
-inline void GlesState::glValidateProgram(uint32_t const program) {}
-
-inline void GlesState::glClearColor(float const r, float const g, float const b, float const a) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_102_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_102_result;
-    l_ctx->mClearing.mClearColor = Color().SetRed(r).SetGreen(g).SetBlue(b).SetAlpha(a);
-}
-
-inline void GlesState::glClearDepthf(float const depth) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_103_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_103_result;
-    l_ctx->mClearing.mClearDepth = depth;
-}
-
-inline void GlesState::glClearStencil(int32_t const stencil) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_104_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_104_result;
-    l_ctx->mClearing.mClearStencil = stencil;
-}
-
-inline void GlesState::glClear(uint32_t const mask) {
-    if ((mask & ClearMask::GL_COLOR_BUFFER_BIT) != 0) {
-    }
-}
-
-inline void GlesState::glCullFace(uint32_t const mode) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_105_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_105_result;
-    l_ctx->mRasterizing.mCullFace = mode;
-}
-
-inline void GlesState::glPolygonOffset(float const scale_factor, float const units) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_106_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_106_result;
-    l_ctx->mRasterizing.mPolygonOffsetUnits = units;
-    l_ctx->mRasterizing.mPolygonOffsetFactor = scale_factor;
-}
-
-inline void GlesState::glLineWidth(float const width) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_107_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_107_result;
-    l_ctx->mRasterizing.mLineWidth = width;
-}
-
-inline void GlesState::glSampleCoverage(float const value, bool const invert) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_108_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_108_result;
-    l_ctx->mRasterizing.mSampleCoverageValue = value;
-    l_ctx->mRasterizing.mSampleCoverageInvert = invert;
-}
-
-inline void GlesState::glHint(uint32_t const target, uint32_t const mode) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_109_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_109_result;
-    l_ctx->mGenerateMipmapHint = mode;
-}
-
-inline void GlesState::glFramebufferRenderbuffer(uint32_t const framebuffer_target,
-                                                 uint32_t const framebuffer_attachment,
-                                                 uint32_t const renderbuffer_target,
-                                                 uint32_t const renderbuffer) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_110_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_110_result;
-    uint32_t l_target = /* clang-format off */
-    /* switch(framebuffer_target) */
-        /* case FramebufferTarget::GL_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
-        /* case FramebufferTarget::GL_DRAW_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_DRAW_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
-        /* case FramebufferTarget::GL_READ_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_READ_FRAMEBUFFER))) ? (FramebufferTarget::GL_READ_FRAMEBUFFER) :
-        /* default: */ 0 /* clang-format on */;
-    FramebufferId l_framebufferId = l_ctx->mBoundFramebuffers[l_target];
-    std::shared_ptr<Framebuffer> l_framebuffer = l_ctx->mInstances.mFramebuffers[l_framebufferId];
-    FramebufferAttachmentInfo l_attachment = l_framebuffer->mAttachments[framebuffer_attachment];
-    if (renderbuffer == (RenderbufferId)(0)) {
-        l_attachment.mType = FramebufferAttachmentType::GL_NONE;
-    } else {
-        l_attachment.mType = FramebufferAttachmentType::GL_RENDERBUFFER;
-    }
-    l_attachment.mObject = (uint32_t)(renderbuffer);
-    l_attachment.mTextureLevel = 0;
-    l_attachment.mCubeMapFace = CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-    l_framebuffer->mAttachments[framebuffer_attachment] = l_attachment;
-}
-
-inline void GlesState::glFramebufferTexture2D(uint32_t const framebuffer_target,
-                                              uint32_t const framebuffer_attachment,
-                                              uint32_t const texture_target, uint32_t const texture,
-                                              int32_t const level) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_111_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_111_result;
-    uint32_t l_target = /* clang-format off */
-    /* switch(framebuffer_target) */
-        /* case FramebufferTarget::GL_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
-        /* case FramebufferTarget::GL_DRAW_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_DRAW_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
-        /* case FramebufferTarget::GL_READ_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_READ_FRAMEBUFFER))) ? (FramebufferTarget::GL_READ_FRAMEBUFFER) :
-        /* default: */ 0 /* clang-format on */;
-    FramebufferId l_framebufferId = l_ctx->mBoundFramebuffers[l_target];
-    std::shared_ptr<Framebuffer> l_framebuffer = l_ctx->mInstances.mFramebuffers[l_framebufferId];
-    FramebufferAttachmentInfo l_attachment = l_framebuffer->mAttachments[framebuffer_attachment];
-    if (texture == (TextureId)(0)) {
-        l_attachment.mType = FramebufferAttachmentType::GL_NONE;
-        l_attachment.mObject = 0;
-        l_attachment.mTextureLevel = 0;
-        l_attachment.mCubeMapFace = CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-    } else {
-        l_attachment.mType = FramebufferAttachmentType::GL_TEXTURE;
-        l_attachment.mObject = (uint32_t)(texture);
-        l_attachment.mTextureLevel = level;
-        l_attachment.mCubeMapFace = /* clang-format off */
-        /* switch(texture_target) */
-            /* case TextureImageTarget::GL_TEXTURE_2D: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_2D))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X) :
-            /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_X) :
-            /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Y) :
-            /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_POSITIVE_Z) :
-            /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_X) :
-            /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) :
-            /* case TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: */(((texture_target) == (TextureImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) ? (CubeMapImageTarget::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) :
-            /* default: */ 0 /* clang-format on */;
-    }
-    l_framebuffer->mAttachments[framebuffer_attachment] = l_attachment;
-}
-
-inline void GlesState::glGetFramebufferAttachmentParameteriv(uint32_t const framebuffer_target,
-                                                             uint32_t const attachment,
-                                                             uint32_t const parameter,
-                                                             int32_t* const value) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_112_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_112_result;
-    uint32_t l_target = /* clang-format off */
-    /* switch(framebuffer_target) */
-        /* case FramebufferTarget::GL_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
-        /* case FramebufferTarget::GL_DRAW_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_DRAW_FRAMEBUFFER))) ? (FramebufferTarget::GL_DRAW_FRAMEBUFFER) :
-        /* case FramebufferTarget::GL_READ_FRAMEBUFFER: */(((framebuffer_target) == (FramebufferTarget::GL_READ_FRAMEBUFFER))) ? (FramebufferTarget::GL_READ_FRAMEBUFFER) :
-        /* default: */ 0 /* clang-format on */;
-    FramebufferId l_framebufferId = l_ctx->mBoundFramebuffers[l_target];
-    std::shared_ptr<Framebuffer> l_framebuffer = l_ctx->mInstances.mFramebuffers[l_framebufferId];
-    FramebufferAttachmentInfo l_a = l_framebuffer->mAttachments[attachment];
-    slice(value, 0, 1)[0] = /* clang-format off */
-    /* switch(parameter) */
-        /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE))) ? ((int32_t)(l_a.mType)) :
-        /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME))) ? ((int32_t)(l_a.mObject)) :
-        /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL))) ? (l_a.mTextureLevel) :
-        /* case FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: */(((parameter) == (FramebufferAttachmentParameter::GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE))) ? ((int32_t)(l_a.mCubeMapFace)) :
-        /* default: */ 0 /* clang-format on */;
-}
-
-inline void GlesState::glDrawElements(uint32_t const draw_mode, int32_t const element_count,
-                                      uint32_t const indices_type, void* const indices) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_113_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_113_result;
-    uint32_t l_count = (uint32_t)(element_count);
-    BufferId l_id = l_ctx->mBoundBuffers[BufferTarget::GL_ELEMENT_ARRAY_BUFFER];
-    if (l_id != (BufferId)(0)) {
-        Slice<uint8_t> l_index_data = l_ctx->mInstances.mBuffers[l_id]->mData;
-        uint32_t l_offset = (uint32_t)((uint64_t)(indices));
-        uint32_t l_first = minIndex(l_index_data.begin(), indices_type, l_offset, l_count);
-        uint32_t l_last = maxIndex(l_index_data.begin(), indices_type, l_offset, l_count);
-        std::shared_ptr<Context> l_ReadVertexArrays_114_ctx = l_ctx;
-        uint32_t l_ReadVertexArrays_114_first_index = l_first;
-        uint32_t l_ReadVertexArrays_114_last_index = l_last;
-        for (int32_t l_i = 0; l_i < l_ReadVertexArrays_114_ctx->mVertexAttributeArrays.size();
-             ++l_i) {
-            std::shared_ptr<VertexAttributeArray> l_arr =
-                    l_ReadVertexArrays_114_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)];
-            if (l_arr->mEnabled && l_arr->mBuffer == (BufferId)(0)) {
-                uint32_t l_vertexAttribTypeSize_115_t = l_arr->mType;
-                uint32_t l_vertexAttribTypeSize_115_result = /* clang-format off */
-                /* switch(l_vertexAttribTypeSize_115_t) */
-                    /* case VertexAttribType::GL_BYTE: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_BYTE))) ? (1) :
-                    /* case VertexAttribType::GL_UNSIGNED_BYTE: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_UNSIGNED_BYTE))) ? (1) :
-                    /* case VertexAttribType::GL_SHORT: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_SHORT))) ? (2) :
-                    /* case VertexAttribType::GL_UNSIGNED_SHORT: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_UNSIGNED_SHORT))) ? (2) :
-                    /* case VertexAttribType::GL_FIXED: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_FIXED))) ? (4) :
-                    /* case VertexAttribType::GL_FLOAT: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_FLOAT))) ? (4) :
-                    /* case VertexAttribType::GL_ARB_half_float_vertex: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_ARB_half_float_vertex))) ? (2) :
-                    /* case VertexAttribType::GL_HALF_FLOAT_OES: */(((l_vertexAttribTypeSize_115_t) == (VertexAttribType::GL_HALF_FLOAT_OES))) ? (2) :
-                    /* default: */ 0 /* clang-format on */;
-                uint32_t l_elsize = l_vertexAttribTypeSize_115_result * l_arr->mSize;
-                uint32_t l_elstride = /* clang-format off */
-                /* switch(l_arr->mStride == 0) */
-                    /* case true: */(((l_arr->mStride == 0) == (true))) ? (l_elsize) :
-                    /* case false: */(((l_arr->mStride == 0) == (false))) ? ((uint32_t)(l_arr->mStride)) :
-                    /* default: */ 0 /* clang-format on */;
-                for (uint32_t l_v = l_ReadVertexArrays_114_first_index;
-                     l_v < l_ReadVertexArrays_114_last_index + 1; ++l_v) {
-                    uint32_t l_offset = l_elstride * l_v;
-                    read(slice(l_arr->mPointer, (uint64_t)(l_offset),
-                               (uint64_t)(l_offset + l_elsize)));
-                }
-            }
-        }
-    } else {
-        uint8_t* l_index_data = (uint8_t*)(indices);
-        uint32_t l_first = minIndex(l_index_data, indices_type, 0, l_count);
-        uint32_t l_last = maxIndex(l_index_data, indices_type, 0, l_count);
-        std::shared_ptr<Context> l_ReadVertexArrays_116_ctx = l_ctx;
-        uint32_t l_ReadVertexArrays_116_first_index = l_first;
-        uint32_t l_ReadVertexArrays_116_last_index = l_last;
-        for (int32_t l_i = 0; l_i < l_ReadVertexArrays_116_ctx->mVertexAttributeArrays.size();
-             ++l_i) {
-            std::shared_ptr<VertexAttributeArray> l_arr =
-                    l_ReadVertexArrays_116_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)];
-            if (l_arr->mEnabled && l_arr->mBuffer == (BufferId)(0)) {
-                uint32_t l_vertexAttribTypeSize_117_t = l_arr->mType;
-                uint32_t l_vertexAttribTypeSize_117_result = /* clang-format off */
-                /* switch(l_vertexAttribTypeSize_117_t) */
-                    /* case VertexAttribType::GL_BYTE: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_BYTE))) ? (1) :
-                    /* case VertexAttribType::GL_UNSIGNED_BYTE: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_UNSIGNED_BYTE))) ? (1) :
-                    /* case VertexAttribType::GL_SHORT: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_SHORT))) ? (2) :
-                    /* case VertexAttribType::GL_UNSIGNED_SHORT: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_UNSIGNED_SHORT))) ? (2) :
-                    /* case VertexAttribType::GL_FIXED: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_FIXED))) ? (4) :
-                    /* case VertexAttribType::GL_FLOAT: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_FLOAT))) ? (4) :
-                    /* case VertexAttribType::GL_ARB_half_float_vertex: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_ARB_half_float_vertex))) ? (2) :
-                    /* case VertexAttribType::GL_HALF_FLOAT_OES: */(((l_vertexAttribTypeSize_117_t) == (VertexAttribType::GL_HALF_FLOAT_OES))) ? (2) :
-                    /* default: */ 0 /* clang-format on */;
-                uint32_t l_elsize = l_vertexAttribTypeSize_117_result * l_arr->mSize;
-                uint32_t l_elstride = /* clang-format off */
-                /* switch(l_arr->mStride == 0) */
-                    /* case true: */(((l_arr->mStride == 0) == (true))) ? (l_elsize) :
-                    /* case false: */(((l_arr->mStride == 0) == (false))) ? ((uint32_t)(l_arr->mStride)) :
-                    /* default: */ 0 /* clang-format on */;
-                for (uint32_t l_v = l_ReadVertexArrays_116_first_index;
-                     l_v < l_ReadVertexArrays_116_last_index + 1; ++l_v) {
-                    uint32_t l_offset = l_elstride * l_v;
-                    read(slice(l_arr->mPointer, (uint64_t)(l_offset),
-                               (uint64_t)(l_offset + l_elsize)));
-                }
-            }
-        }
-        uint32_t l_IndexSize_118_indices_type = indices_type;
-        uint32_t l_IndexSize_118_result = /* clang-format off */
-        /* switch(l_IndexSize_118_indices_type) */
-            /* case IndicesType::GL_UNSIGNED_BYTE: */(((l_IndexSize_118_indices_type) == (IndicesType::GL_UNSIGNED_BYTE))) ? (1) :
-            /* case IndicesType::GL_UNSIGNED_SHORT: */(((l_IndexSize_118_indices_type) == (IndicesType::GL_UNSIGNED_SHORT))) ? (2) :
-            /* case IndicesType::GL_UNSIGNED_INT: */(((l_IndexSize_118_indices_type) == (IndicesType::GL_UNSIGNED_INT))) ? (4) :
-            /* default: */ 0 /* clang-format on */;
-        read(slice(l_index_data, (uint64_t)(0),
-                   (uint64_t)((uint32_t)(element_count)*l_IndexSize_118_result)));
-    }
-}
-
-inline void GlesState::glDrawArrays(uint32_t const draw_mode, int32_t const first_index,
-                                    int32_t const index_count) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_119_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_119_result;
-    int32_t l_last_index = first_index + index_count - 1;
-    std::shared_ptr<Context> l_ReadVertexArrays_120_ctx = l_ctx;
-    uint32_t l_ReadVertexArrays_120_first_index = (uint32_t)(first_index);
-    uint32_t l_ReadVertexArrays_120_last_index = (uint32_t)(l_last_index);
-    for (int32_t l_i = 0; l_i < l_ReadVertexArrays_120_ctx->mVertexAttributeArrays.size(); ++l_i) {
-        std::shared_ptr<VertexAttributeArray> l_arr =
-                l_ReadVertexArrays_120_ctx->mVertexAttributeArrays[(AttributeLocation)(l_i)];
-        if (l_arr->mEnabled && l_arr->mBuffer == (BufferId)(0)) {
-            uint32_t l_vertexAttribTypeSize_121_t = l_arr->mType;
-            uint32_t l_vertexAttribTypeSize_121_result = /* clang-format off */
-            /* switch(l_vertexAttribTypeSize_121_t) */
-                /* case VertexAttribType::GL_BYTE: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_BYTE))) ? (1) :
-                /* case VertexAttribType::GL_UNSIGNED_BYTE: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_UNSIGNED_BYTE))) ? (1) :
-                /* case VertexAttribType::GL_SHORT: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_SHORT))) ? (2) :
-                /* case VertexAttribType::GL_UNSIGNED_SHORT: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_UNSIGNED_SHORT))) ? (2) :
-                /* case VertexAttribType::GL_FIXED: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_FIXED))) ? (4) :
-                /* case VertexAttribType::GL_FLOAT: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_FLOAT))) ? (4) :
-                /* case VertexAttribType::GL_ARB_half_float_vertex: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_ARB_half_float_vertex))) ? (2) :
-                /* case VertexAttribType::GL_HALF_FLOAT_OES: */(((l_vertexAttribTypeSize_121_t) == (VertexAttribType::GL_HALF_FLOAT_OES))) ? (2) :
-                /* default: */ 0 /* clang-format on */;
-            uint32_t l_elsize = l_vertexAttribTypeSize_121_result * l_arr->mSize;
-            uint32_t l_elstride = /* clang-format off */
-            /* switch(l_arr->mStride == 0) */
-                /* case true: */(((l_arr->mStride == 0) == (true))) ? (l_elsize) :
-                /* case false: */(((l_arr->mStride == 0) == (false))) ? ((uint32_t)(l_arr->mStride)) :
-                /* default: */ 0 /* clang-format on */;
-            for (uint32_t l_v = l_ReadVertexArrays_120_first_index;
-                 l_v < l_ReadVertexArrays_120_last_index + 1; ++l_v) {
-                uint32_t l_offset = l_elstride * l_v;
-                read(slice(l_arr->mPointer, (uint64_t)(l_offset), (uint64_t)(l_offset + l_elsize)));
-            }
-        }
-    }
-}
-
-inline void GlesState::glFlush() {}
-
-inline void GlesState::glFinish() {}
-
-inline void GlesState::glGetBooleanv(uint32_t const param, bool* const values) {
-    Slice<bool> l_v = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_122_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_122_result;
-    switch (param) {
-        case StateVariable::GL_BLEND: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_BLEND];
-            break;
-        }
-        case StateVariable::GL_CULL_FACE: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_CULL_FACE];
-            break;
-        }
-        case StateVariable::GL_DEPTH_TEST: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_DEPTH_TEST];
-            break;
-        }
-        case StateVariable::GL_DITHER: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_DITHER];
-            break;
-        }
-        case StateVariable::GL_POLYGON_OFFSET_FILL: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_POLYGON_OFFSET_FILL];
-            break;
-        }
-        case StateVariable::GL_SAMPLE_ALPHA_TO_COVERAGE: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_SAMPLE_ALPHA_TO_COVERAGE];
-            break;
-        }
-        case StateVariable::GL_SAMPLE_COVERAGE: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_SAMPLE_COVERAGE];
-            break;
-        }
-        case StateVariable::GL_SCISSOR_TEST: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_SCISSOR_TEST];
-            break;
-        }
-        case StateVariable::GL_STENCIL_TEST: {
-            l_v[0] = l_ctx->mCapabilities[Capability::GL_STENCIL_TEST];
-            break;
-        }
-        case StateVariable::GL_DEPTH_WRITEMASK: {
-            l_v[0] = l_ctx->mRasterizing.mDepthMask;
-            break;
-        }
-        case StateVariable::GL_COLOR_WRITEMASK: {
-            l_v[0] = l_ctx->mRasterizing.mColorMaskRed;
-            l_v[1] = l_ctx->mRasterizing.mColorMaskGreen;
-            l_v[2] = l_ctx->mRasterizing.mColorMaskBlue;
-            l_v[3] = l_ctx->mRasterizing.mColorMaskAlpha;
-            break;
-        }
-        case StateVariable::GL_SAMPLE_COVERAGE_INVERT: {
-            l_v[0] = l_ctx->mRasterizing.mSampleCoverageInvert;
-            break;
-        }
-        case StateVariable::GL_SHADER_COMPILER: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-    }
-}
-
-inline void GlesState::glGetFloatv(uint32_t const param, float* const values) {
-    Slice<float> l_v = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_123_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_123_result;
-    switch (param) {
-        case StateVariable::GL_DEPTH_RANGE: {
-            l_v[0] = l_ctx->mRasterizing.mDepthNear;
-            l_v[1] = l_ctx->mRasterizing.mDepthFar;
-            break;
-        }
-        case StateVariable::GL_LINE_WIDTH: {
-            l_v[0] = l_ctx->mRasterizing.mLineWidth;
-            break;
-        }
-        case StateVariable::GL_POLYGON_OFFSET_FACTOR: {
-            l_v[0] = l_ctx->mRasterizing.mPolygonOffsetFactor;
-            break;
-        }
-        case StateVariable::GL_POLYGON_OFFSET_UNITS: {
-            l_v[0] = l_ctx->mRasterizing.mPolygonOffsetUnits;
-            break;
-        }
-        case StateVariable::GL_SAMPLE_COVERAGE_VALUE: {
-            l_v[0] = l_ctx->mRasterizing.mSampleCoverageValue;
-            break;
-        }
-        case StateVariable::GL_COLOR_CLEAR_VALUE: {
-            l_v[0] = l_ctx->mClearing.mClearColor.mRed;
-            l_v[1] = l_ctx->mClearing.mClearColor.mGreen;
-            l_v[2] = l_ctx->mClearing.mClearColor.mBlue;
-            l_v[3] = l_ctx->mClearing.mClearColor.mAlpha;
-            break;
-        }
-        case StateVariable::GL_DEPTH_CLEAR_VALUE: {
-            l_v[0] = l_ctx->mClearing.mClearDepth;
-            break;
-        }
-        case StateVariable::GL_ALIASED_LINE_WIDTH_RANGE: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            l_v[1] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[1];
-            break;
-        }
-        case StateVariable::GL_ALIASED_POINT_SIZE_RANGE: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            l_v[1] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[1];
-            break;
-        }
-        case StateVariable::GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-    }
-}
-
-inline void GlesState::glGetIntegerv(uint32_t const param, int32_t* const values) {
-    Slice<int32_t> l_v = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_124_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_124_result;
-    switch (param) {
-        case StateVariable::GL_ACTIVE_TEXTURE: {
-            l_v[0] = (int32_t)(l_ctx->mActiveTextureUnit);
-            break;
-        }
-        case StateVariable::GL_ARRAY_BUFFER_BINDING: {
-            l_v[0] = (int32_t)(l_ctx->mBoundBuffers[BufferTarget::GL_ARRAY_BUFFER]);
-            break;
-        }
-        case StateVariable::GL_ELEMENT_ARRAY_BUFFER_BINDING: {
-            l_v[0] = (int32_t)(l_ctx->mBoundBuffers[BufferTarget::GL_ELEMENT_ARRAY_BUFFER]);
-            break;
-        }
-        case StateVariable::GL_BLEND_SRC_ALPHA: {
-            l_v[0] = (int32_t)(l_ctx->mBlending.mSrcAlphaBlendFactor);
-            break;
-        }
-        case StateVariable::GL_BLEND_SRC_RGB: {
-            l_v[0] = (int32_t)(l_ctx->mBlending.mSrcRgbBlendFactor);
-            break;
-        }
-        case StateVariable::GL_BLEND_DST_ALPHA: {
-            l_v[0] = (int32_t)(l_ctx->mBlending.mDstAlphaBlendFactor);
-            break;
-        }
-        case StateVariable::GL_BLEND_DST_RGB: {
-            l_v[0] = (int32_t)(l_ctx->mBlending.mDstRgbBlendFactor);
-            break;
-        }
-        case StateVariable::GL_BLEND_EQUATION_RGB: {
-            l_v[0] = (int32_t)(l_ctx->mBlending.mBlendEquationRgb);
-            break;
-        }
-        case StateVariable::GL_BLEND_EQUATION_ALPHA: {
-            l_v[0] = (int32_t)(l_ctx->mBlending.mBlendEquationAlpha);
-            break;
-        }
-        case StateVariable::GL_BLEND_COLOR: {
-            l_v[0] = (int32_t)(l_ctx->mBlending.mBlendColor.mRed);
-            l_v[1] = (int32_t)(l_ctx->mBlending.mBlendColor.mGreen);
-            l_v[2] = (int32_t)(l_ctx->mBlending.mBlendColor.mBlue);
-            l_v[3] = (int32_t)(l_ctx->mBlending.mBlendColor.mAlpha);
-            break;
-        }
-        case StateVariable::GL_DEPTH_FUNC: {
-            l_v[0] = (int32_t)(l_ctx->mRasterizing.mDepthTestFunction);
-            break;
-        }
-        case StateVariable::GL_DEPTH_CLEAR_VALUE: {
-            l_v[0] = (int32_t)(l_ctx->mClearing.mClearDepth);
-            break;
-        }
-        case StateVariable::GL_STENCIL_WRITEMASK: {
-            l_v[0] = (int32_t)(l_ctx->mRasterizing.mStencilMask[FaceMode::GL_FRONT]);
-            break;
-        }
-        case StateVariable::GL_STENCIL_BACK_WRITEMASK: {
-            l_v[0] = (int32_t)(l_ctx->mRasterizing.mStencilMask[FaceMode::GL_BACK]);
-            break;
-        }
-        case StateVariable::GL_VIEWPORT: {
-            l_v[0] = l_ctx->mRasterizing.mViewport.mX;
-            l_v[1] = l_ctx->mRasterizing.mViewport.mY;
-            l_v[2] = l_ctx->mRasterizing.mViewport.mWidth;
-            l_v[3] = l_ctx->mRasterizing.mViewport.mHeight;
-            break;
-        }
-        case StateVariable::GL_SCISSOR_BOX: {
-            l_v[0] = l_ctx->mRasterizing.mScissor.mX;
-            l_v[1] = l_ctx->mRasterizing.mScissor.mY;
-            l_v[2] = l_ctx->mRasterizing.mScissor.mWidth;
-            l_v[3] = l_ctx->mRasterizing.mScissor.mHeight;
-            break;
-        }
-        case StateVariable::GL_FRONT_FACE: {
-            l_v[0] = (int32_t)(l_ctx->mRasterizing.mFrontFace);
-            break;
-        }
-        case StateVariable::GL_CULL_FACE_MODE: {
-            l_v[0] = (int32_t)(l_ctx->mRasterizing.mCullFace);
-            break;
-        }
-        case StateVariable::GL_STENCIL_CLEAR_VALUE: {
-            l_v[0] = l_ctx->mClearing.mClearStencil;
-            break;
-        }
-        case StateVariable::GL_FRAMEBUFFER_BINDING: {
-            l_v[0] = (int32_t)(l_ctx->mBoundFramebuffers[FramebufferTarget::GL_FRAMEBUFFER]);
-            break;
-        }
-        case StateVariable::GL_READ_FRAMEBUFFER_BINDING: {
-            l_v[0] = (int32_t)(l_ctx->mBoundFramebuffers[FramebufferTarget::GL_READ_FRAMEBUFFER]);
-            break;
-        }
-        case StateVariable::GL_RENDERBUFFER_BINDING: {
-            l_v[0] = (int32_t)(l_ctx->mBoundRenderbuffers[RenderbufferTarget::GL_RENDERBUFFER]);
-            break;
-        }
-        case StateVariable::GL_CURRENT_PROGRAM: {
-            l_v[0] = (int32_t)(l_ctx->mBoundProgram);
-            break;
-        }
-        case StateVariable::GL_TEXTURE_BINDING_2D: {
-            l_v[0] = (int32_t)(
-                    l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit][TextureTarget::GL_TEXTURE_2D]);
-            break;
-        }
-        case StateVariable::GL_TEXTURE_BINDING_CUBE_MAP: {
-            l_v[0] = (int32_t)(l_ctx->mTextureUnits[l_ctx->mActiveTextureUnit]
-                                                   [TextureTarget::GL_TEXTURE_CUBE_MAP]);
-            break;
-        }
-        case StateVariable::GL_GENERATE_MIPMAP_HINT: {
-            l_v[0] = (int32_t)(l_ctx->mGenerateMipmapHint);
-            break;
-        }
-        case StateVariable::GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_CUBE_MAP_TEXTURE_SIZE: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_FRAGMENT_UNIFORM_VECTORS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_RENDERBUFFER_SIZE: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_TEXTURE_IMAGE_UNITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_TEXTURE_SIZE: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_VARYING_VECTORS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_VERTEX_ATTRIBS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_VERTEX_UNIFORM_VECTORS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_VIEWPORT_DIMS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            l_v[1] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[1];
-            break;
-        }
-        case StateVariable::GL_NUM_COMPRESSED_TEXTURE_FORMATS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_NUM_SHADER_BINARY_FORMATS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_PACK_ALIGNMENT: {
-            l_v[0] = l_ctx->mPixelStorage[PixelStoreParameter::GL_PACK_ALIGNMENT];
-            break;
-        }
-        case StateVariable::GL_UNPACK_ALIGNMENT: {
-            l_v[0] = l_ctx->mPixelStorage[PixelStoreParameter::GL_UNPACK_ALIGNMENT];
-            break;
-        }
-        case StateVariable::GL_ALPHA_BITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_BLUE_BITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_GREEN_BITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_RED_BITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_DEPTH_BITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_SAMPLE_BUFFERS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_SAMPLES: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_STENCIL_BITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_SUBPIXEL_BITS: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_IMPLEMENTATION_COLOR_READ_FORMAT: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_IMPLEMENTATION_COLOR_READ_TYPE: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-        case StateVariable::GL_GPU_DISJOINT_EXT: {
-            l_v[0] = slice(values, (uint64_t)(0), (uint64_t)(stateVariableSize(param)))[0];
-            break;
-        }
-    }
-}
-
-inline void GlesState::glGetString(uint32_t const param, char* const result) { return; }
-
-inline void GlesState::glEnable(uint32_t const capability) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_125_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_125_result;
-    l_ctx->mCapabilities[capability] = true;
-}
-
-inline void GlesState::glDisable(uint32_t const capability) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_126_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_126_result;
-    l_ctx->mCapabilities[capability] = false;
-}
-
-inline void GlesState::glIsEnabled(uint32_t const capability, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_127_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_127_result;
-    return;
-}
-
-inline void GlesState::glMapBufferRange(uint32_t const target, int32_t const offset,
-                                        int32_t const length, uint32_t const access,
-                                        void* const result) {
-    return;
-}
-
-inline void GlesState::glUnmapBuffer(uint32_t const target) {}
-
-inline void GlesState::glInvalidateFramebuffer(uint32_t const target, int32_t const count,
-                                               uint32_t* const attachments) {}
-
-inline void GlesState::glRenderbufferStorageMultisample(uint32_t const target,
-                                                        int32_t const samples,
-                                                        uint32_t const format, int32_t const width,
-                                                        int32_t const height) {}
-
-inline void GlesState::glBlitFramebuffer(int32_t const srcX0, int32_t const srcY0,
-                                         int32_t const srcX1, int32_t const srcY1,
-                                         int32_t const dstX0, int32_t const dstY0,
-                                         int32_t const dstX1, int32_t const dstY1,
-                                         uint32_t const mask, uint32_t const filter) {}
-
-inline void GlesState::glGenQueries(int32_t const count, uint32_t* const queries) {
-    Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_128_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_128_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        QueryId l_id = (QueryId)(slice(queries, (uint64_t)(0), (uint64_t)(count))[(uint64_t)(l_i)]);
-        l_ctx->mInstances.mQueries[l_id] = std::shared_ptr<Query>((new Query()));
-        l_q[(uint64_t)(l_i)] = l_id;
-    }
-}
-
-inline void GlesState::glBeginQuery(uint32_t const target, uint32_t const query) {}
-
-inline void GlesState::glEndQuery(uint32_t const target) {}
-
-inline void GlesState::glDeleteQueries(int32_t const count, uint32_t* const queries) {
-    Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_129_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_129_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        l_ctx->mInstances.mQueries[l_q[(uint64_t)(l_i)]] = std::shared_ptr<Query>();
-    }
-}
-
-inline void GlesState::glIsQuery(uint32_t const query, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_130_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_130_result;
-    return;
-}
-
-inline void GlesState::glGetQueryiv(uint32_t const target, uint32_t const parameter,
-                                    int32_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-inline void GlesState::glGetQueryObjectuiv(uint32_t const query, uint32_t const parameter,
-                                           uint32_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-inline void GlesState::glGenQueriesEXT(int32_t const count, uint32_t* const queries) {
-    Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_131_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_131_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        QueryId l_id = (QueryId)(slice(queries, (uint64_t)(0), (uint64_t)(count))[(uint64_t)(l_i)]);
-        l_ctx->mInstances.mQueries[l_id] = std::shared_ptr<Query>((new Query()));
-        l_q[(uint64_t)(l_i)] = l_id;
-    }
-}
-
-inline void GlesState::glBeginQueryEXT(uint32_t const target, uint32_t const query) {}
-
-inline void GlesState::glEndQueryEXT(uint32_t const target) {}
-
-inline void GlesState::glDeleteQueriesEXT(int32_t const count, uint32_t* const queries) {
-    Slice<QueryId> l_q = slice(queries, (uint64_t)(0), (uint64_t)(count));
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_132_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_132_result;
-    for (int32_t l_i = 0; l_i < count; ++l_i) {
-        l_ctx->mInstances.mQueries[l_q[(uint64_t)(l_i)]] = std::shared_ptr<Query>();
-    }
-}
-
-inline void GlesState::glIsQueryEXT(uint32_t const query, bool const result) {
-    std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
-    std::shared_ptr<Context> l_GetContext_133_result = l_context;
-    std::shared_ptr<Context> l_ctx = l_GetContext_133_result;
-    return;
-}
-
-inline void GlesState::glQueryCounterEXT(uint32_t const query, uint32_t const target) {}
-
-inline void GlesState::glGetQueryivEXT(uint32_t const target, uint32_t const parameter,
-                                       int32_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-inline void GlesState::glGetQueryObjectivEXT(uint32_t const query, uint32_t const parameter,
-                                             int32_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-inline void GlesState::glGetQueryObjectuivEXT(uint32_t const query, uint32_t const parameter,
-                                              uint32_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-inline void GlesState::glGetQueryObjecti64vEXT(uint32_t const query, uint32_t const parameter,
-                                               int64_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-inline void GlesState::glGetQueryObjectui64vEXT(uint32_t const query, uint32_t const parameter,
-                                                uint64_t* const value) {
-    slice(value, 0, 1)[0] = slice(value, 0, 1)[0];
-}
-
-}  // namespace gapii
-
-#endif  // GAPII_GLES_STATE_H
diff --git a/cc/gapii/slice.h b/cc/gapii/slice.h
index 22e1aa1..0c3b6b5 100644
--- a/cc/gapii/slice.h
+++ b/cc/gapii/slice.h
@@ -30,15 +30,22 @@
     inline Slice();
     inline Slice(T* base, uint64_t count, const std::shared_ptr<Pool>& pool);
 
-    inline Slice<T> operator()(uint64_t start, uint64_t end) const;
-    inline T&       operator[](uint64_t index) const;
-
     // Returns the number of elements in the slice.
     inline uint64_t count() const;
 
     // Returns the size of the slice in bytes.
     inline uint64_t size() const;
 
+    // Returns true if this is a slice on the application pool (external memory).
+    inline bool isApplicationPool() const;
+
+    // Returns a new subset slice from this slice.
+    inline Slice<T> operator()(uint64_t start, uint64_t end) const;
+
+    // Returns a reference to a single element in the slice.
+    // Care must be taken to not mutate data in the application pool.
+    inline T& operator[](uint64_t index) const;
+
     // Support for range-based for looping
     inline T* begin() const;
     inline T* end() const;
@@ -57,16 +64,6 @@
     : mBase(base), mCount(0), mPool(pool) {}
 
 template<typename T>
-inline Slice<T> Slice<T>::operator()(uint64_t start, uint64_t end) const {
-    return Slice<T>(mBase+start, end-start, mPool);
-}
-
-template<typename T>
-inline T& Slice<T>::operator[](uint64_t index) const {
-    return mBase[index];
-}
-
-template<typename T>
 inline uint64_t Slice<T>::count() const {
     return mCount;
 }
@@ -77,6 +74,21 @@
 }
 
 template<typename T>
+inline bool Slice<T>::isApplicationPool() const {
+    return mPool.get() == nullptr;
+}
+
+template<typename T>
+inline Slice<T> Slice<T>::operator()(uint64_t start, uint64_t end) const {
+    return Slice<T>(mBase+start, end-start, mPool);
+}
+
+template<typename T>
+inline T& Slice<T>::operator[](uint64_t index) const {
+    return mBase[index];
+}
+
+template<typename T>
 inline T* Slice<T>::begin() const {
     return mBase;
 }
diff --git a/cc/gapii/spy_base.cpp b/cc/gapii/spy_base.cpp
new file mode 100644
index 0000000..bcc7621
--- /dev/null
+++ b/cc/gapii/spy_base.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "spy_base.h"
+
+namespace gapii {
+
+void SpyBase::Observation::encode(gapic::Encoder* e) const {
+    e->Uint64(reinterpret_cast<uint64_t>(mBase));
+    e->Uint64(mSize);
+    e->Id(mId);
+}
+
+// Inline methods
+void SpyBase::init(std::shared_ptr<gapic::Encoder> encoder) {
+    mEncoder = encoder;
+}
+
+void SpyBase::read(void* base, uint64_t size) {
+    mReads.push_back(observe(base, size));
+}
+
+void SpyBase::write(void* base, uint64_t size) {
+    mWrites.push_back(observe(base, size));
+}
+
+void SpyBase::encodeObservations() {
+    mEncoder->Uint32(mReads.size());
+    for (auto r : mReads) {
+        r.encode(mEncoder.get());
+    }
+    mEncoder->Uint32(mWrites.size());
+    for (auto r : mWrites) {
+        r.encode(mEncoder.get());
+    }
+    mReads.clear();
+    mWrites.clear();
+}
+
+SpyBase::Observation SpyBase::observe(void* base, uint64_t size) {
+    gapic::Id id = gapic::Id::Hash(base, size);
+    if (mResources.count(id) == 0) {
+        mEncoder->Uint16(0xfffd);  // Type ID -- TODO: mEncoder->Id(RESOURCE_ID);
+        mEncoder->Id(id);
+        mEncoder->Data(base, size);
+        mResources.emplace(id);
+    }
+    return Observation{ base, size, id };
+}
+
+}  // namespace gapii
+
diff --git a/cc/gapii/spy_base.h b/cc/gapii/spy_base.h
new file mode 100644
index 0000000..8bd52f5
--- /dev/null
+++ b/cc/gapii/spy_base.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef GAPII_SPY_BASE_H
+#define GAPII_SPY_BASE_H
+
+#include "slice.h"
+
+#include <gapic/encoder.h>
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+namespace gapii {
+
+class SpyBase {
+public:
+    void init(std::shared_ptr<gapic::Encoder> encoder);
+
+protected:
+    // Observation is a single read or write memory observation.
+    struct Observation {
+        // encode writes this observation to the encoder e.
+        void encode(gapic::Encoder* e) const;
+
+        const void*     mBase; // Base address of the observation.
+        const uint64_t  mSize; // Number of bytes of the observation.
+        const gapic::Id mId;   // The resource identifier of the observation.
+    };
+
+    typedef std::unordered_set<gapic::Id> IdSet;
+    typedef std::vector<Observation> ObservationList;
+    typedef std::shared_ptr<gapic::Encoder> EncoderSPtr;
+
+    // read is called to make a read memory observation of size bytes, starting at base.
+    void read(void* base, uint64_t size);
+
+    // write is called to make a write memory observation of size bytes, starting at base.
+    void write(void* base, uint64_t size);
+
+    // encodeObservations encodes all read and write observations to the encoder, and clears the
+    // read and write lists.
+    void encodeObservations();
+
+    template <typename T>
+    inline void read(const Slice<T>& slice);
+
+    // Read reads and returns the i'th element from the slice src.
+    template <typename T>
+    inline T read(const Slice<T>& src, uint64_t i);
+
+    template <typename T>
+    inline void write(const Slice<T>& slice);
+
+    // Writes a value to i'th element in the slice dst.
+    template <typename T>
+    inline void write(const Slice<T>& dst, uint64_t i, T value);
+
+    template <typename T>
+    inline void copy(const Slice<T>& dst, const Slice<T>& src);
+
+    template<typename T>
+    inline Slice<T> clone(const Slice<T>& src);
+
+    template<typename T>
+    inline Slice<T> make(uint64_t count) const;
+
+    template<typename T>
+    inline Slice<T> slice(T* src, uint64_t s, uint64_t e) const;
+
+    inline Slice<uint8_t> slice(void* src, uint64_t s, uint64_t e) const;
+
+    inline Slice<char> slice(const std::string& src) const;
+
+    template<typename T>
+    inline Slice<T> slice(const Slice<T>& src, uint64_t s, uint64_t e) const;
+
+    inline std::string string(const Slice<char>& slice) const;
+
+    ObservationList mReads;  // The list of read observations made by the spy.
+    ObservationList mWrites; // The list of write observations made by the spy.
+    IdSet mResources;        // The list of observations that have already been encoded.
+    EncoderSPtr mEncoder;    // The output stream encoder.
+
+private:
+    Observation observe(void* base, uint64_t size);
+};
+
+template <typename T>
+inline void SpyBase::read(const Slice<T>& slice) {
+    if (slice.isApplicationPool()) {
+        return read(slice.begin(), slice.count() * sizeof(T));
+    }
+}
+
+template<typename T>
+inline T SpyBase::read(const Slice<T>& src, uint64_t index) {
+    T& elem = src[index];
+    if (src.isApplicationPool()) {
+        read(&elem, sizeof(T));
+    }
+    return elem;
+}
+
+template <typename T>
+inline void SpyBase::write(const Slice<T>& slice) {
+    if (slice.isApplicationPool()) {
+        return write(slice.begin(), slice.count() * sizeof(T));
+    }
+}
+
+template<typename T>
+inline void SpyBase::write(const Slice<T>& dst, uint64_t index, T value) {
+    if (!dst.isApplicationPool()) { // The spy must not mutate data in the application pool.
+        dst[index] = value;
+    } else {
+        write(&dst[index], sizeof(T));
+    }
+}
+
+template <typename T>
+inline void SpyBase::copy(const Slice<T>& dst, const Slice<T>& src) {
+    read(src);
+    if (!dst.isApplicationPool()) { // The spy must not mutate data in the application pool.
+        uint64_t c = (src.count() < dst.count()) ? src.count() : dst.count();
+        for (uint64_t i = 0; i < c; i++) {
+          dst[i] = src[i];
+        }
+    }
+    write(dst);
+}
+
+template<typename T>
+inline Slice<T> SpyBase::clone(const Slice<T>& src) {
+    Slice<T> dst = make<T>(src.count());
+    copy(dst, src);
+    return dst;
+}
+
+template<typename T>
+inline Slice<T> SpyBase::make(uint64_t count) const {
+    auto pool = Pool::create(count * sizeof(T));
+    return Slice<T>(reinterpret_cast<T*>(pool->base()), count, pool);
+}
+
+template<typename T>
+inline Slice<T> SpyBase::slice(T* src, uint64_t s, uint64_t e) const {
+    // TODO: Find the pool containing src
+    return Slice<T>(src+s, e-s, std::shared_ptr<Pool>());
+}
+
+inline Slice<uint8_t> SpyBase::slice(void* src, uint64_t s, uint64_t e) const {
+    return slice(reinterpret_cast<uint8_t*>(src), s, e);
+}
+
+inline Slice<char> SpyBase::slice(const std::string& src) const {
+    Slice<char> dst = make<char>(src.length());
+    for (uint64_t i = 0; i < src.length(); i++) {
+        dst[i] = src[i];
+    }
+    return dst;
+}
+
+template<typename T>
+inline Slice<T> SpyBase::slice(const Slice<T>& src, uint64_t s, uint64_t e) const {
+    return src(s, e);
+}
+
+inline std::string SpyBase::string(const Slice<char>& slice) const {
+    return std::string(slice.begin(), slice.end());
+}
+
+}  // namespace gapii
+
+#endif // GAPII_SPY_BASE_H
diff --git a/cc/gapii/state_base.h b/cc/gapii/state_base.h
deleted file mode 100644
index 6fe8b98..0000000
--- a/cc/gapii/state_base.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef GAPII_STATE_BASE_H
-#define GAPII_STATE_BASE_H
-
-#include "slice.h"
-
-#include <functional>
-#include <stdint.h>
-
-namespace gapii {
-
-class StateBase {
-public:
-    typedef std::function<void(const void* ptr, uint64_t offset, uint64_t size)> ObserveFunc;
-
-    inline StateBase(ObserveFunc observe);
-
-protected:
-    template <typename T>
-    inline void read(const Slice<T>& slice) const;
-
-    template <typename T>
-    inline void write(const Slice<T>& slice) const;
-
-    template <typename T>
-    inline void copy(const Slice<T>& dst, const Slice<T>& src) const;
-
-    template<typename T>
-    inline Slice<T> make(uint64_t count) const;
-
-    template<typename T>
-    inline Slice<T> clone(const Slice<T>& src) const;
-
-    template<typename T>
-    inline Slice<T> slice(T* src, uint64_t s, uint64_t e) const;
-
-    inline Slice<uint8_t> slice(void* src, uint64_t s, uint64_t e) const;
-
-    inline Slice<char> slice(const std::string& src) const;
-
-    template<typename T>
-    inline Slice<T> slice(const Slice<T>& src, uint64_t s, uint64_t e) const;
-
-    inline std::string string(const Slice<char>& slice) const;
-
-    ObserveFunc mObserve;
-};
-
-inline StateBase::StateBase(ObserveFunc observe)
-    : mObserve(observe) {}
-
-template <typename T>
-inline void StateBase::read(const Slice<T>& slice) const {
-    return mObserve(slice.begin(), 0, slice.count() * sizeof(T));
-}
-
-template <typename T>
-inline void StateBase::write(const Slice<T>& slice) const {
-    return mObserve(slice.begin(), 0, slice.count() * sizeof(T));
-}
-
-template <typename T>
-inline void StateBase::copy(const Slice<T>& dst, const Slice<T>& src) const {
-    read(src);
-    uint64_t c = (src.count() < dst.count()) ? src.count() : dst.count();
-    for (uint64_t i = 0; i < c; i++) {
-      dst[i] = src[i];
-    }
-    write(dst);
-}
-
-template<typename T>
-inline Slice<T> StateBase::make(uint64_t count) const {
-    auto pool = Pool::create(count * sizeof(T));
-    return Slice<T>(reinterpret_cast<T*>(pool->base()), count, pool);
-}
-
-template<typename T>
-inline Slice<T> StateBase::clone(const Slice<T>& src) const {
-    Slice<T> dst = make<T>(src.count());
-    copy(dst, src);
-    return dst;
-}
-
-template<typename T>
-inline Slice<T> StateBase::slice(T* src, uint64_t s, uint64_t e) const {
-    // TODO: Find the pool containing src
-    return Slice<T>(src+s, e-s, std::shared_ptr<Pool>());
-}
-
-inline Slice<uint8_t> StateBase::slice(void* src, uint64_t s, uint64_t e) const {
-    return slice(reinterpret_cast<uint8_t*>(src), s, e);
-}
-
-inline Slice<char> StateBase::slice(const std::string& src) const {
-    Slice<char> dst = make<char>(src.length());
-    for (uint64_t i = 0; i < src.length(); i++) {
-        dst[i] = src[i];
-    }
-    return dst;
-}
-
-template<typename T>
-inline Slice<T> StateBase::slice(const Slice<T>& src, uint64_t s, uint64_t e) const {
-    return src(s, e);
-}
-
-inline std::string StateBase::string(const Slice<char>& slice) const {
-    return std::string(slice.begin(), slice.end());
-}
-
-}  // namespace gapii
-
-#endif // GAPII_STATE_BASE_H
diff --git a/gfxapi/templates/api_classnames.tmpl b/gfxapi/templates/api_classnames.tmpl
index 920620d..18f62d1 100644
--- a/gfxapi/templates/api_classnames.tmpl
+++ b/gfxapi/templates/api_classnames.tmpl
@@ -16,16 +16,6 @@
 
 {{/*
 -------------------------------------------------------------------------------
-  Emits the {api}State classname.
--------------------------------------------------------------------------------
-*/}}
-{{define "ApiClassnames.State"}}
-  {{print (Title (Global "API")) "State"}}
-{{end}}
-
-
-{{/*
--------------------------------------------------------------------------------
   Emits the {api}Imports classname.
 -------------------------------------------------------------------------------
 */}}
diff --git a/gfxapi/templates/api_spy.h.tmpl b/gfxapi/templates/api_spy.h.tmpl
index 1340a41..49144c0 100644
--- a/gfxapi/templates/api_spy.h.tmpl
+++ b/gfxapi/templates/api_spy.h.tmpl
@@ -19,8 +19,8 @@
 {{Include "cpp_common.tmpl"    }}
 
 {{/* ---- Overrides ---- */}}
-{{Global "C++.EnumTypeOverride" "uint32_t"}}
-{{Global "C++.ExternPrefix"     "mState." }}
+{{Global "C++.EnumTypeOverride"   "uint32_t"}}
+{{Global "C++.Statement.Override" "Statement"}}
 
 {{$filename := print (Global "API") "_spy.h" }}
 {{Global "SpyName" (print (Title (Global "API")) "Spy")}}
@@ -36,24 +36,19 @@
   #define {{$guard}}

   #include "{{Global "API"}}_imports.h"
-  #include "{{Global "API"}}_state.h"
   #include "{{Global "API"}}_types.h"

-  #include <gapic/encoder.h>
+  #include "spy_base.h"

   #include <gapic/log.h>

   #include <memory>
   #include <string>
-  #include <unordered_set>

-  #include <stdint.h>

   namespace gapii {«

-  class {{$spyname}} {
+  class {{$spyname}} : public SpyBase {
   «public:»
-    inline {{$spyname}}();

     inline void init(std::shared_ptr<gapic::Encoder> encoder);

     {{range $f := AllCommands $}}
@@ -62,44 +57,21 @@

   «protected:»
     {{Macro "ApiClassnames.Imports"}} mImports;
-    {{Macro "ApiClassnames.State"  }} mState;

-  «private:»
-    enum order {
-      PRE_OBSERVE,
-      POST_OBSERVE,
-    };
+    // Globals
+    {{range $g := $.Globals}}
+      {{Macro "C++.Type" $g}} {{$g.Name}};
+    {{end}}

-    inline void observe(const void* base, uint64_t offset, uint64_t size);

-    std::unordered_set<gapic::Id> mObserved;
-    std::shared_ptr<gapic::Encoder> mEncoder;
+    #include "{{Global "API"}}_state_externs.inl"
   };

-  inline {{$spyname}}::{{$spyname}}()
-    : mState(std::bind(&GlesSpy::observe, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) {}

   // Inline methods
   inline void {{$spyname}}::init(std::shared_ptr<gapic::Encoder> encoder) {
-    mEncoder = encoder;
+    SpyBase::init(encoder);
     mImports.Resolve();
   }

-  inline void {{$spyname}}::observe(const void* base, uint64_t offset, uint64_t size) {
-    const void* ptr = reinterpret_cast<const uint8_t*>(base) + offset;
-    gapic::Id id = gapic::Id::Hash(ptr, size);
-    if (mObserved.count(id) == 0) {
-        mEncoder->Uint16(0xfffd); // Type ID -- TODO: mEncoder->Id(RESOURCE_ID);
-        mEncoder->Id(id);
-        mEncoder->Data(ptr, static_cast<int32_t>(size));
-        mObserved.emplace(id);
-    }
-    mEncoder->Uint16(0xfffe); // Type ID -- TODO: mEncoder->Id(OBSERVATION_ID);
-    mEncoder->Uint64(reinterpret_cast<uint64_t>(ptr));
-    mEncoder->Uint64(size);
-    mEncoder->Id(id);
-  }

   {{range $i, $f := AllCommands $}}
     {{Global "HACK_FUNCTION_INDEX_HACK" $i}}
     {{Macro "MethodImplementation" $f}}¶
@@ -144,33 +116,25 @@
 {{define "MethodImplementation"}}
   {{AssertType $ "Function"}}
 
-  {{$name := Macro "CmdName" $}}
-  {{$synthetic := GetAnnotation $ "synthetic"}}
-  {{$ret       := not (IsVoid $.Return.Type)}}
-  {{$spyname   := Global "SpyName"}}
+  {{$name    := Macro "CmdName" $}}
+  {{$spyname := Global "SpyName"}}
 
   inline {{Macro "C++.ReturnType" $}} {{$spyname}}::{{$name}}({{Macro "C++.CallParameters" $}}) {
     GAPID_INFO("{{$name}}()\n");
-    {{$args := Macro "C++.CallArguments" $}}
-    {{if $ret}}
-      {{if $synthetic}}
-        {{Macro "C++.ReturnType" $}} result = {{Macro "C++.Null" (TypeOf $.Return)}};
-      {{else}}
-        {{Macro "C++.ReturnType" $}} result = mImports.{{$name}}({{Macro "C++.CallArguments" $}});
-      {{end}}
-      mState.{{$name}}({{if $args}}{{$args}}, {{end}}result);
-    {{else}}
-      {{if not $synthetic}}mImports.{{$name}}({{$args}});{{end}}
-      mState.{{$name}}({{$args}});
-    {{end}}
+
+    {{Macro "CallImport" $}} {{/* TODO: Call this between all API reads and writes*/}}

+    do {
+      {{Macro "C++.Block" $.Block}}
+    } while(false);

     mEncoder->Uint16({{Global "HACK_FUNCTION_INDEX_HACK"}}); // Type ID -- TODO: mEncoder->Id({{Macro "ID" $}});
-
+    encodeObservations();
     {{range $p := $.FullParameters}}
       {{Macro "Encode" "Parameter" $p "Type" (TypeOf $p) "Name" $p.Name}}
     {{end}}
 
-    {{if $ret}}¶
+    {{if not (IsVoid $.Return.Type)}}¶
       return result;
     {{end}}
   }
@@ -179,6 +143,30 @@
 
 {{/*
 -------------------------------------------------------------------------------
+  Emits the C++ logic to call the imported (real driver) function.
+-------------------------------------------------------------------------------
+*/}}
+{{define "CallImport"}}
+  {{AssertType $ "Function"}}
+
+  {{$name      := Macro "CmdName" $}}
+  {{$args      := Macro "C++.CallArguments" $}}
+  {{$synthetic := GetAnnotation $ "synthetic"}}
+
+  {{if not (IsVoid $.Return.Type)}}
+    {{if $synthetic}}
+      {{Macro "C++.ReturnType" $}} result = {{Macro "C++.Null" (TypeOf $.Return)}};
+    {{else}}
+      {{Macro "C++.ReturnType" $}} result = mImports.{{$name}}({{$args}});
+    {{end}}
+  {{else}}
+    {{if not $synthetic}}mImports.{{$name}}({{$args}});{{end}}
+  {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
   Emits the C++ encode logic for the specified parameter.
 -------------------------------------------------------------------------------
 */}}
@@ -201,9 +189,11 @@
   {{else if IsS64         $.Type}}mEncoder->Int64({{$.Name}});
   {{else if IsInt         $.Type}}mEncoder->Int64({{$.Name}});
   {{else if IsUint        $.Type}}mEncoder->Uint64({{$.Name}});
-  {{else if IsPointer     $.Type}}mEncoder->Uint64(reinterpret_cast<uint64_t>({{$.Name}}));
   {{else if IsString      $.Type}}mEncoder->String({{$.Name}});
   {{else if IsEnum        $.Type}}mEncoder->Uint32(static_cast<uint32_t>({{$.Name}}));
+  {{else if IsPointer     $.Type}}
+    mEncoder->Uint64(reinterpret_cast<uint64_t>({{$.Name}}));
+    mEncoder->Uint32(0); // PoolID
   {{else if IsStaticArray $.Type}}
     for (int i = 0; i < {{$.Type.Size}}; i++) {
       {{Macro "Encode" "Type" $.Type.ValueType "Name" (print $.Name "[i]") "Parameter" $.Parameter}}
@@ -217,3 +207,17 @@
   {{end}}
 {{end}}
 
+
+{{/*
+-------------------------------------------------------------------------------
+  Emits the logic to execute the given statement without mutating outputs.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Statement"}}
+  {{     if IsAssign    $}}{{Macro "C++.Statement.Default" $}}
+  {{else if IsMapAssign $}}{{Macro "C++.Statement.Default" $}}
+  {{else if IsReturn    $}}break;
+  {{else                 }}{{Macro "C++.Statement.Default" $}}
+  {{end}}
+{{end}}
+
diff --git a/gfxapi/templates/api_state.h.tmpl b/gfxapi/templates/api_state.h.tmpl
deleted file mode 100644
index 818378c..0000000
--- a/gfxapi/templates/api_state.h.tmpl
+++ /dev/null
@@ -1,106 +0,0 @@
-{{/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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.
- */}}
-
-{{/* ---- Includes ---- */}}
-{{Include "api_classnames.tmpl"}}
-{{Include "cpp_common.tmpl"    }}
-
-{{/* ---- Overrides ---- */}}
-{{Global "C++.EnumTypeOverride"   "uint32_t" }}
-{{Global "C++.Statement.Override" "Statement"}}
-
-{{$filename := print (Global "API") "_state.h" }}
-{{$ | Macro "State" | Format (Global "clang-format") | Write $filename}}
-
-{{define "State"}}
-  {{AssertType $ "API"}}
-  {{Macro "C++.AOSP.Copyright"}}
-  {{$classname := Macro "ApiClassnames.State"}}
-  {{$guard := print "GAPII_" (Upper (Global "API")) "_STATE_H"}}

-  #ifndef {{$guard}}
-  #define {{$guard}}

-  #include "state_base.h"
-  #include "{{Global "API"}}_types.h"

-  #include <gapic/encoder.h>

-  #include <stdint.h>

-  namespace gapii {«

-  class {{$classname}} : public StateBase {
-  «public:»
-    inline {{$classname}}(ObserveFunc observe);

-    {{range $c := AllCommands $}}
-      inline void {{Macro "CmdName" $c}}({{Macro "Parameters" $c}});
-    {{end}}

-    {{range $g := $.Globals}}
-      {{Macro "C++.Type" $g}} {{$g.Name}};
-    {{end}}

-    #include "{{Global "API"}}_state_externs.inl"
-  };

-    inline {{$classname}}::{{$classname}}(ObserveFunc observe) : StateBase(observe) {}

-  {{range $c := AllCommands $}}
-    inline void {{$classname}}::{{Macro "CmdName" $c}}({{Macro "Parameters" $c}}) {
-      {{Macro "C++.Block" $c.Block}}
-    }¶
-  {{end}}

-  »} // namespace gapii

-  #endif // {{$guard}}

-{{end}}
-
-
-{{/*
--------------------------------------------------------------------------------
-  Emits the comma-separated list of type-name paired parameters for given
-  function, including the return value. All parameters are marked const.
--------------------------------------------------------------------------------
-*/}}
-{{define "Parameters"}}
-  {{AssertType $ "Function"}}
-
-  {{range $i, $p := $.CallParameters}}
-    {{if $i}}, {{end}}{{Macro "C++.ParameterType" $p}} const {{$p.Name}}§
-  {{end}}
-  {{if not (IsVoid $.Return.Type)}}
-    {{if len $.CallParameters}}, {{end}}{{Macro "C++.Type" $.Return.Type}} const result§
-  {{end}}
-{{end}}
-
-
-{{/*
--------------------------------------------------------------------------------
-  Emits the logic to execute the given statement without mutating outputs.
--------------------------------------------------------------------------------
-*/}}
-{{define "Statement"}}
-  {{     if IsAssign    $}}{{Macro "C++.Statement.Default" $}}
-  {{else if IsMapAssign $}}{{Macro "C++.Statement.Default" $}}
-  {{else if IsReturn    $}}return;
-  {{else                 }}{{Macro "C++.Statement.Default" $}}
-  {{end}}
-{{end}}
-
diff --git a/gfxapi/templates/cpp_common.tmpl b/gfxapi/templates/cpp_common.tmpl
index 578d12f..1c83c2f 100644
--- a/gfxapi/templates/cpp_common.tmpl
+++ b/gfxapi/templates/cpp_common.tmpl
@@ -276,6 +276,7 @@
   {{     if IsDeclareLocal $}}{{Macro "C++.Type" (TypeOf $.Local)}} {{Macro "C++.LocalName" $.Local}} = {{Macro "C++.Read" $.Local.Value}};
   {{else if IsAssign       $}}{{Macro "C++.Assign" $}}
   {{else if IsMapAssign    $}}{{Macro "C++.MapAssign" $}}
+  {{else if IsSliceAssign  $}}{{Macro "C++.SliceAssign" $}}
   {{else if IsReturn       $}}return {{Macro "C++.Read" $.Value}};
   {{else if IsBranch       $}}if ({{Macro "C++.Read" $.Condition}}) {
       {{Macro "C++.Block" $.True}}
@@ -313,7 +314,6 @@
 */}}
 {{define "C++.Assign"}}
   {{AssertType $ "Assign"}}
-
   {{Macro "C++.Read" $.LHS}} {{$.Operator}} {{Macro "C++.Read" $.RHS}};
 {{end}}
 
@@ -325,13 +325,24 @@
 */}}
 {{define "C++.MapAssign"}}
   {{AssertType $ "MapAssign"}}
-
   {{Macro "C++.Read" $.To.Map}}[{{Macro "C++.Read" $.To.Index}}] {{$.Operator}} {{Macro "C++.Read" $.Value}};
 {{end}}
 
 
 {{/*
 -------------------------------------------------------------------------------
+  Emits the C++ logic to perform a slice assign statement.
+-------------------------------------------------------------------------------
+*/}}
+{{define "C++.SliceAssign"}}
+  {{AssertType $ "SliceAssign"}}
+  {{if eq $.Operator "="}}write({{Macro "C++.Read" $.To.Slice}}, {{Macro "C++.Read" $.To.Index}}, {{Macro "C++.Read" $.Value}});
+  {{else}}{{Error "Unsupported MapAssign operator %s" $.Operator}}{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
   Emits the C++ logic to perform an iteration statement.
 -------------------------------------------------------------------------------
 */}}
@@ -380,7 +391,7 @@
   {{else if IsNew              $}}{{$ty := Unpack $.Type}}std::shared_ptr<{{Macro "C++.Type" $ty.To}}>(new {{Macro "C++.Type" $ty.To}}())
   {{else if IsCreate           $}}{{$ty := Unpack $.Type}}std::shared_ptr<{{Macro "C++.Type" $ty.To}}>((new {{Macro "C++.Type" $ty.To}}()){{Macro "C++.InitializeFields" $.Initializer}})
   {{else if IsClassInitializer $}}{{Macro "C++.Type" $}}(){{Macro "C++.InitializeFields" $}}
-  {{else if IsSliceIndex       $}}{{Macro "C++.Read" $.Slice  }}[{{Macro "C++.Read" $.Index}}]
+  {{else if IsSliceIndex       $}}read({{Macro "C++.Read" $.Slice}}, {{Macro "C++.Read" $.Index}})
   {{else if IsSliceRange       $}}slice({{Macro "C++.Read" $.Slice}}, {{Macro "C++.Read" $.Range.LHS}}, {{Macro "C++.Read" $.Range.RHS}})
   {{else if IsPointerRange     $}}slice({{Macro "C++.Read" $.Pointer}}, {{Macro "C++.Read" $.Range.LHS}}, {{Macro "C++.Read" $.Range.RHS}})
   {{else if IsClone            $}}clone({{Macro "C++.Read" $.Slice}})
@@ -479,7 +490,7 @@
 
   {{if $.Target.Object}}{{Macro "C++.MethodCall" $}}
   {{else}}{{/* extern */}}
-    {{Global "C++.ExternPrefix"}}{{$.Target.Function.Name}}({{Macro "C++.ReadList" $.Arguments}})
+    {{$.Target.Function.Name}}({{Macro "C++.ReadList" $.Arguments}})
   {{end}}
 {{end}}
 
@@ -552,11 +563,6 @@
   ////////////////////////////////////////////////////////////////////////////////
 {{end}}
 
-{{/* Defaults */}}
-{{if not (Global "C++.ExternPrefix")}}
-  {{Global "C++.ExternPrefix" ""}}
-{{end}}
-
 {{$clang_style := "{BasedOnStyle: Google, AccessModifierOffset: -4, ColumnLimit: 100, ContinuationIndentWidth: 8, IndentWidth: 4}"}}
 {{Global "clang-format" (Strings "clang-format" "-style" $clang_style)}}
 
diff --git a/gfxapi/templates/go_common.tmpl b/gfxapi/templates/go_common.tmpl
index 6ffeb2c..f2fae84 100644
--- a/gfxapi/templates/go_common.tmpl
+++ b/gfxapi/templates/go_common.tmpl
@@ -292,7 +292,8 @@
   {{     if IsDeclareLocal $}}{{$.Local.Name}} := {{Macro "Go.Read" $.Local.Value}} {{Macro "Go.TypeComment" (TypeOf $.Local)}}
   {{else if IsAssert       $}}
   {{else if IsAssign       $}}{{Macro "Go.Assign" "LHS" $.LHS "Operator" $.Operator "RHS" $.RHS}}
-  {{else if IsMapAssign    $}}{{Macro "Go.MapAssign" "To" $.To "Operator" $.Operator "Value" $.Value}}
+  {{else if IsMapAssign    $}}{{Macro "Go.MapAssign" $}}
+  {{else if IsSliceAssign  $}}{{Macro "Go.SliceAssign" $}}
   {{else if IsCopy         $}}{{Macro "Go.Copy" $}}
   {{else if IsReturn       $}}{{Macro "Go.Assign" "LHS" $.Function.Return "Operator" "=" "RHS" $.Value}}
   {{else if IsIteration    $}}{{Macro "Go.Iteration" $}}
@@ -371,12 +372,7 @@
 -------------------------------------------------------------------------------
 */}}
 {{define "Go.Assign"}}
-  {{if IsSliceIndex $.LHS}}
-    {{if ne $.Operator "="}}{{Error "Compound assignments to pointers are not supported (%s)" $.Operator}}{{end}}
-    {{Macro "Go.Read" $.LHS.Slice}}.Index({{Macro "Go.Read" $.LHS.Index}}, ϟs).Write({{Macro "Go.Read" $.RHS}}, ϟs)
-  {{else}}
-    {{Macro "Go.Read" $.LHS}} {{$.Operator}} {{Macro "Go.Read" $.RHS}}
-  {{end}}
+  {{Macro "Go.Read" $.LHS}} {{$.Operator}} {{Macro "Go.Read" $.RHS}}
 {{end}}
 
 
@@ -397,6 +393,7 @@
 -------------------------------------------------------------------------------
 */}}
 {{define "Go.MapAssign"}}
+  {{AssertType $ "MapAssign"}}
   {{if eq $.Operator "="}}{{Macro "Go.Read" $.To.Map}}[{{Macro "Go.Read" $.To.Index}}] = {{Macro "Go.Read" $.Value}}
   {{else}}{{Error "Unsupported MapAssign operator %s" $.Operator}}{{end}}
 {{end}}
@@ -404,6 +401,18 @@
 
 {{/*
 -------------------------------------------------------------------------------
+  Emits the logic to assign a value to a slice index
+-------------------------------------------------------------------------------
+*/}}
+{{define "Go.SliceAssign"}}
+  {{AssertType $ "SliceAssign"}}
+  {{if eq $.Operator "="}}{{Macro "Go.Read" $.To.Slice}}.Index({{Macro "Go.Read" $.To.Index}}, ϟs).Write({{Macro "Go.Read" $.Value}}, ϟs)
+  {{else}}{{Error "Unsupported SliceAssign operator %s" $.Operator}}{{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
   Emits the Go logic to read the value of the specified expression.
   If the global "Go.Read.Override" is specified then this the macro with the
   specified name is called, otherwise the macro delegates to "Go.Read.Default".
diff --git a/gfxapi/templates/replay_writer.go.tmpl b/gfxapi/templates/replay_writer.go.tmpl
index e12d9e8..2cd8517 100644
--- a/gfxapi/templates/replay_writer.go.tmpl
+++ b/gfxapi/templates/replay_writer.go.tmpl
@@ -288,14 +288,9 @@
     {{Macro "Go.Read" $.Slice}}.onReplayWrite(ϟa, ϟs, ϟd, ϟl, ϟb, ϟp)
   {{else if IsCopy $}}
     {{Macro "Go.Read" $.Dst}}.replayCopy({{Macro "Go.Read" $.Src}}, ϟa, ϟs, ϟd, ϟl, ϟb, ϟp)
-  {{else if IsAssign $}}
-    {{if IsSliceIndex $.LHS}}
-      {{$lhs := $.LHS | Unpack}}
-      {{if ne $.Operator "="}}{{Error "Compound assignments to pointers are not supported (%s)" $.Operator}}{{end}}
-      {{Macro "Go.Read" $lhs.Slice}}.Index({{Macro "Go.Read" $lhs.Index}}, ϟs).replayWrite({{Macro "Go.Read" $.RHS}}, ϟa, ϟs, ϟd, ϟl, ϟb, ϟp)
-    {{else}}
-      {{Macro "Go.Statement.Default" $}}
-    {{end}}
+  {{else if IsSliceAssign $}}
+    {{if ne $.Operator "="}}{{Error "Compound assignments to pointers are not supported (%s)" $.Operator}}{{end}}
+    {{Macro "Go.Read" $.To.Slice}}.Index({{Macro "Go.Read" $.To.Index}}, ϟs).replayWrite({{Macro "Go.Read" $.Value}}, ϟa, ϟs, ϟd, ϟl, ϟb, ϟp)
   {{else}}
     {{Macro "Go.Statement.Default" $}}
   {{end}}
diff --git a/make.go b/make.go
index db327d8..36c209c 100644
--- a/make.go
+++ b/make.go
@@ -91,7 +91,6 @@
 		Apic(gapiipath, glesapi, Path(gpusrc, "gfxapi/templates/api_imports.cpp.tmpl"))
 		Apic(gapiipath, glesapi, Path(gpusrc, "gfxapi/templates/api_imports.h.tmpl"))
 		Apic(gapiipath, glesapi, Path(gpusrc, "gfxapi/templates/api_spy.h.tmpl"))
-		Apic(gapiipath, glesapi, Path(gpusrc, "gfxapi/templates/api_state.h.tmpl"))
 		Apic(gapiipath, glesapi, Path(gpusrc, "gfxapi/templates/api_types.h.tmpl"))
 		Apic(gapiiwinpath, glesapi, Path(gpusrc, "gfxapi/templates/opengl32_exports.def.tmpl"))
 		Apic(gapiiwinpath, glesapi, Path(gpusrc, "gfxapi/templates/opengl32_resolve.cpp.tmpl"))