"glDrawRangeElements",
         "glDrawRangeElementsBaseVertex",
         "glDrawRangeElementsEXT",
-        #"glMultiDrawElements",
-        #"glMultiDrawElementsBaseVertex",
-        #"glMultiDrawElementsEXT",
-        #"glMultiModeDrawElementsIBM",
+        "glMultiDrawElements",
+        "glMultiDrawElementsBaseVertex",
+        "glMultiDrawElementsEXT",
+        "glMultiModeDrawElementsIBM",
     ])
 
     misc_draw_function_names = set([
             return
 
         if function.name in self.draw_elements_function_names and arg.name == 'indices':
-            print '    %s = %s.toPointer();' % (lvalue, rvalue)
+            self.extract_opaque_arg(function, arg, arg_type, lvalue, rvalue)
             return
 
         if arg.type is glapi.GLlocation \
 
 
 static inline GLuint
 __glMultiDrawArrays_maxindex(const GLint *first, const GLsizei *count, GLsizei primcount) {
-    OS::DebugMessage("warning: %s: unsupported\n", __FUNCTION__);
-    return 0;
+    GLuint maxindex = 0;
+    for (GLsizei prim = 0; prim < primcount; ++prim) {
+        GLuint maxindex_prim = __glDrawArrays_maxindex(first[prim], count[prim]);
+        maxindex = std::max(maxindex, maxindex_prim);
+    }
+    return maxindex;
 }
 
 static inline GLuint
 __glMultiDrawElements_maxindex(const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
-    OS::DebugMessage("warning: %s: unsupported\n", __FUNCTION__);
-    return 0;
+    GLuint maxindex = 0;
+    for (GLsizei prim = 0; prim < primcount; ++prim) {
+        GLuint maxindex_prim = __glDrawElements_maxindex(count[prim], type, indices[prim]);
+        maxindex = std::max(maxindex, maxindex_prim);
+    }
+    return maxindex;
 }
 
 static inline GLuint
 __glMultiDrawElementsBaseVertex_maxindex(const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint * basevertex) {
-    OS::DebugMessage("warning: %s: unsupported\n", __FUNCTION__);
-    return 0;
+    GLuint maxindex = 0;
+    for (GLsizei prim = 0; prim < primcount; ++prim) {
+        GLuint maxindex_prim = __glDrawElementsBaseVertex_maxindex(count[prim], type, indices[prim], basevertex[prim]);
+        maxindex = std::max(maxindex, maxindex_prim);
+    }
+    return maxindex;
 }
 
 #define __glMultiDrawArraysEXT_maxindex __glMultiDrawArrays_maxindex
 
             print '    __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
             print '    if (!__element_array_buffer) {'
             if isinstance(arg.type, stdapi.Array):
-                Tracer.dump_arg_instance(self, function, arg)
                 print '        __writer.beginArray(%s);' % arg.type.length
                 print '        for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
                 print '            __writer.beginElement();'
-                print '            __writer.writeBlob((const void *)%s, count[i]*__gl_type_size(type));' % (arg.name)
+                print '            __writer.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
                 print '            __writer.endElement();'
                 print '        }'
                 print '        __writer.endArray();'
             else:
-                print '        __writer.writeBlob((const void *)%s, count*__gl_type_size(type));' % (arg.name)
+                print '        __writer.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
             print '    } else {'
             Tracer.dump_arg_instance(self, function, arg)
             print '    }'
 
 
     def extract_arg(self, function, arg, arg_type, lvalue, rvalue):
         ValueExtractor().visit(arg_type, lvalue, rvalue)
+    
+    def extract_opaque_arg(self, function, arg, arg_type, lvalue, rvalue):
+        OpaqueValueExtractor().visit(arg_type, lvalue, rvalue)
 
     def call_function(self, function):
         arg_names = ", ".join([arg.name for arg in function.args])
 
         print '    __traceStruct%s(%s);' % (struct.id, instance)
 
     def visit_array(self, array, instance):
-        print '    if (%s) {' % instance
+        length = '__c' + array.type.id
         index = '__i' + array.type.id
-        print '        __writer.beginArray(%s);' % (array.length,)
-        print '        for (int %s = 0; %s < %s; ++%s) {' % (index, index, array.length, index)
+        print '    if (%s) {' % instance
+        print '        size_t %s = %s;' % (length, array.length)
+        print '        __writer.beginArray(%s);' % length
+        print '        for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
         print '            __writer.beginElement();'
         self.visit(array.type, '(%s)[%s]' % (instance, index))
         print '            __writer.endElement();'
         print '        }'
         print '        __writer.endArray();'
-        print '    }'
-        print '    else'
+        print '    } else {'
         print '        __writer.writeNull();'
+        print '    }'
 
     def visit_blob(self, blob, instance):
         print '    __writer.writeBlob(%s, %s);' % (instance, blob.size)
         dump_instance(pointer.type, "*" + instance)
         print '        __writer.endElement();'
         print '        __writer.endArray();'
-        print '    }'
-        print '    else'
+        print '    } else {'
         print '        __writer.writeNull();'
+        print '    }'
 
     def visit_handle(self, handle, instance):
         self.visit(handle.type, instance)