diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index e67957d..0748144 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -1279,30 +1279,6 @@ _mesa_PopAttrib(void)
 
 
 /**
- * Helper for incrementing/decrementing vertex buffer object reference
- * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group.
- */
-static void
-adjust_buffer_object_ref_counts(struct gl_array_object *arrayObj, GLint step)
-{
-   GLuint i;
-
-   arrayObj->Vertex.BufferObj->RefCount += step;
-   arrayObj->Weight.BufferObj->RefCount += step;
-   arrayObj->Normal.BufferObj->RefCount += step;
-   arrayObj->Color.BufferObj->RefCount += step;
-   arrayObj->SecondaryColor.BufferObj->RefCount += step;
-   arrayObj->FogCoord.BufferObj->RefCount += step;
-   arrayObj->Index.BufferObj->RefCount += step;
-   arrayObj->EdgeFlag.BufferObj->RefCount += step;
-   for (i = 0; i < Elements(arrayObj->TexCoord); i++)
-      arrayObj->TexCoord[i].BufferObj->RefCount += step;
-   for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
-      arrayObj->VertexAttrib[i].BufferObj->RefCount += step;
-}
-
-
-/**
  * Copy gl_pixelstore_attrib from src to dst, updating buffer
  * object refcounts.
  */
@@ -1328,6 +1304,73 @@ copy_pixelstore(struct gl_context *ctx,
 #define GL_CLIENT_UNPACK_BIT (1<<21)
 
 
+/**
+ * Copy gl_array_object from src to dest.
+ * 'dest' must be in an initialized state.
+ */
+static void
+copy_array_object(struct gl_context *ctx,
+                  struct gl_array_object *dest,
+                  struct gl_array_object *src)
+{
+   dest->Name = src->Name;
+   /* skip RefCount, Mutex */
+   dest->VBOonly = src->VBOonly;
+   dest->_Enabled = src->_Enabled;
+   dest->_MaxElement = src->_MaxElement;
+
+   _mesa_copy_client_array(ctx, &dest->Vertex, &src->Vertex);
+   _mesa_copy_client_array(ctx, &dest->Weight, &src->Weight);
+   _mesa_copy_client_array(ctx, &dest->Normal, &src->Normal);
+   _mesa_copy_client_array(ctx, &dest->Color, &src->Color);
+   _mesa_copy_client_array(ctx, &dest->SecondaryColor, &src->SecondaryColor);
+   /* XXX copy more arrays here */
+
+}
+
+
+/**
+ * Copy gl_array_attrib from src to dest.
+ * 'dest' must be in an initialized state.
+ */
+static void
+copy_array_attrib(struct gl_context *ctx,
+                  struct gl_array_attrib *dest,
+                  struct gl_array_attrib *src)
+{
+   _mesa_reference_array_object(ctx, &dest->ArrayObj, src->ArrayObj);
+
+   /* skip DefaultArrayObj, Objects */
+
+   dest->ActiveTexture = src->ActiveTexture;
+   dest->LockFirst = src->LockFirst;
+   dest->LockCount = src->LockCount;
+   dest->PrimitiveRestart = src->PrimitiveRestart;
+   dest->RestartIndex = src->RestartIndex;
+   /* skip dest->NewState */
+   dest->RebindArrays = src->RebindArrays;
+
+   _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
+                                 src->ArrayBufferObj);
+   _mesa_reference_buffer_object(ctx, &dest->ElementArrayBufferObj,
+                                 src->ElementArrayBufferObj);
+}
+
+
+/**
+ * Free/unreference the fields of 'dest' but don't delete it (that's
+ * done later in the calling code).
+ */
+static void
+free_array_attrib_data(struct gl_context *ctx,
+                       struct gl_array_attrib *attrib)
+{
+   _mesa_reference_array_object(ctx, &attrib->ArrayObj, NULL);
+   _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL);
+   _mesa_reference_buffer_object(ctx, &attrib->ElementArrayBufferObj, NULL);
+}
+
+
 void GLAPIENTRY
 _mesa_PushClientAttrib(GLbitfield mask)
 {
@@ -1362,24 +1405,15 @@ _mesa_PushClientAttrib(GLbitfield mask)
       struct gl_array_attrib *attr;
       struct gl_array_object *obj;
 
-      attr = MALLOC_STRUCT( gl_array_attrib );
-      obj = MALLOC_STRUCT( gl_array_object );
-
-#if FEATURE_ARB_vertex_buffer_object
-      /* increment ref counts since we're copying pointers to these objects */
-      ctx->Array.ArrayBufferObj->RefCount++;
-      ctx->Array.ElementArrayBufferObj->RefCount++;
-#endif
+      attr = CALLOC_STRUCT( gl_array_attrib );
+      obj = CALLOC_STRUCT( gl_array_object );
 
-      memcpy( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
-      memcpy( obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object) );
+      copy_array_object(ctx, obj, ctx->Array.ArrayObj);
+      copy_array_attrib(ctx, attr, &ctx->Array);
 
-      attr->ArrayObj = obj;
+      _mesa_reference_array_object(ctx, &attr->ArrayObj, obj);
 
       save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr);
-
-      /* bump reference counts on buffer objects */
-      adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1);
    }
 
    ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
@@ -1426,30 +1460,14 @@ _mesa_PopClientAttrib(void)
 	    ctx->NewState |= _NEW_PACKUNPACK;
             break;
          case GL_CLIENT_VERTEX_ARRAY_BIT: {
-	    struct gl_array_attrib * data =
+	    struct gl_array_attrib * attr =
 	      (struct gl_array_attrib *) node->data;
 
-            adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, -1);
-	 
-            ctx->Array.ActiveTexture = data->ActiveTexture;
-	    if (data->LockCount != 0)
-	       _mesa_LockArraysEXT(data->LockFirst, data->LockCount);
-	    else if (ctx->Array.LockCount)
-	       _mesa_UnlockArraysEXT();
-
-	    _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name );
-	    
-#if FEATURE_ARB_vertex_buffer_object
-            _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
-                                data->ArrayBufferObj->Name);
-            _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
-                                data->ElementArrayBufferObj->Name);
-#endif
-
-	    memcpy( ctx->Array.ArrayObj, data->ArrayObj,
-		    sizeof( struct gl_array_object ) );
+            copy_array_object(ctx, ctx->Array.ArrayObj, attr->ArrayObj);
+            copy_array_attrib(ctx, &ctx->Array, attr);
 
-	    FREE( data->ArrayObj );
+            ctx->Driver.DeleteArrayObject(ctx, attr->ArrayObj);
+            free_array_attrib_data(ctx, attr);
 	    
 	    /* FIXME: Should some bits in ctx->Array->NewState also be set
 	     * FIXME: here?  It seems like it should be set to inclusive-or
