diff --git a/girepository/ginvoke.c b/girepository/ginvoke.c
index bbf152b..c2eba44 100644
--- a/girepository/ginvoke.c
+++ b/girepository/ginvoke.c
@@ -158,7 +158,8 @@ g_function_info_invoke (GIFunctionInfo *info,
   gpointer func;
   GITypeInfo *tinfo;
   GIArgInfo *ainfo;
-  gint n_args, in_pos, out_pos, i;
+  gboolean is_method;
+  gint n_args, n_invoke_args, in_pos, out_pos, i;
   gpointer *args;
   gboolean success = FALSE;
   
@@ -199,24 +200,49 @@ g_function_info_invoke (GIFunctionInfo *info,
       g_module_close (entire_app);
     }
 
+  is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
+    && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0;
+
   tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
   rtype = get_ffi_type (tinfo);
   g_base_info_unref ((GIBaseInfo *)tinfo);
 
-  n_args = g_callable_info_get_n_args ((GICallableInfo *)info);
-  atypes = g_new (ffi_type*, n_args);
-  args =  g_new (gpointer, n_args);
-  
   in_pos = 0;
   out_pos = 0;
+
+  n_args = g_callable_info_get_n_args ((GICallableInfo *)info);
+  if (is_method)
+    {
+      if (n_in_args == 0)
+	{
+	  g_set_error (error,
+		       G_INVOKE_ERROR,
+		       G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+		       "Too few \"in\" arguments (handling this)");
+	  goto out;
+	}
+      n_invoke_args = n_args+1;
+      in_pos++;
+    }
+  else
+    n_invoke_args = n_args;
+  atypes = g_new (ffi_type*, n_invoke_args);
+  args =  g_new (gpointer, n_invoke_args);
+  
+  if (is_method)
+    {
+      atypes[0] = &ffi_type_pointer;
+      args[0] = (gpointer) &in_args[0];
+    }
   for (i = 0; i < n_args; i++)
     {
+      int offset = (is_method ? 1 : 0);
       ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i);
       switch (g_arg_info_get_direction (ainfo))
 	{
 	case GI_DIRECTION_IN:
 	  tinfo = g_arg_info_get_type (ainfo);
-	  atypes[i] = get_ffi_type (tinfo);
+	  atypes[i+offset] = get_ffi_type (tinfo);
 	  g_base_info_unref ((GIBaseInfo *)tinfo);
 
 	  if (in_pos >= n_in_args)
@@ -224,38 +250,38 @@ g_function_info_invoke (GIFunctionInfo *info,
 	      g_set_error (error,
 			   G_INVOKE_ERROR,
 			   G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-			   "Too few \"in\" arguments");	      
+			   "Too few \"in\" arguments (handling in)");
 	      goto out;
 	    }
 
-	  args[i] = (gpointer)&in_args[in_pos];
+	  args[i+offset] = (gpointer)&in_args[in_pos];
 	  in_pos++;
 	  
 	  break;
 	case GI_DIRECTION_OUT:
-	  atypes[i] = &ffi_type_pointer;
+	  atypes[i+offset] = &ffi_type_pointer;
 
 	  if (out_pos >= n_out_args)
 	    {
 	      g_set_error (error,
 			   G_INVOKE_ERROR,
 			   G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-			   "Too few \"out\" arguments");	      
+			   "Too few \"out\" arguments (handling out)");	      
 	      goto out;
 	    }
 
-	  args[i] = (gpointer)&out_args[out_pos];
+	  args[i+offset] = (gpointer)&out_args[out_pos+offset];
 	  out_pos++;	  
 	  break;
 	case GI_DIRECTION_INOUT:
-	  atypes[i] = &ffi_type_pointer;
+	  atypes[i+offset] = &ffi_type_pointer;
 
 	  if (in_pos >= n_in_args)
 	    {
 	      g_set_error (error,
 			   G_INVOKE_ERROR,
 			   G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-			   "Too few \"in\" arguments");	      
+			   "Too few \"in\" arguments (handling inout)");
 	      goto out;
 	    }
 
@@ -264,11 +290,11 @@ g_function_info_invoke (GIFunctionInfo *info,
 	      g_set_error (error,
 			   G_INVOKE_ERROR,
 			   G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-			   "Too few \"in\" arguments");	      
+			   "Too few \"out\" arguments (handling inout)");	      
 	      goto out;
 	    }
 	  
-	  args[i] = (gpointer)&in_args[in_pos];
+	  args[i+offset] = (gpointer)&in_args[in_pos];
 	  in_pos++;	  
 	  out_pos++;	  
 	  break;
@@ -282,7 +308,7 @@ g_function_info_invoke (GIFunctionInfo *info,
       g_set_error (error,
 		   G_INVOKE_ERROR,
 		   G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-		   "Too many \"in\" arguments");	      
+		   "Too many \"in\" arguments (at end)");
       goto out;
     }
   if (out_pos < n_out_args)
@@ -290,11 +316,11 @@ g_function_info_invoke (GIFunctionInfo *info,
       g_set_error (error,
 		   G_INVOKE_ERROR,
 		   G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-		   "Too many \"out\" arguments");	      
+		   "Too many \"out\" arguments (at end)");	      
       goto out;
     }
 
-  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK)
+  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK)
     goto out;
 
   ffi_call (&cif, func, return_value, args);
diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c
index 3b7107e..983c695 100644
--- a/girepository/gtypelib.c
+++ b/girepository/gtypelib.c
@@ -821,53 +821,6 @@ validate_function_blob (ValidateContext *ctx,
 	  return FALSE;
 	}
     }
-  else if (is_method)
-    {
-      guint32 this_offset;
-      guint32 this_type_offset;
-      ArgBlob *this;
-      SimpleTypeBlob *thistype;
-      InterfaceTypeBlob *thistype_iface;
-
-      if (sigblob->n_arguments == 0)
-	{
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID,
-		       "Invalid 0-argument method");
-	}
-      
-      this_offset = blob->signature + sizeof (SignatureBlob);
-      this = (ArgBlob*) &typelib->data[this_offset];
-      this_type_offset = this_offset + G_STRUCT_OFFSET (ArgBlob, arg_type);
-      thistype = (SimpleTypeBlob *)&typelib->data[this_type_offset];
-      
-      if (thistype->reserved == 0 && 
-	  thistype->reserved2 == 0)
-	{
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID_BLOB,
-		       "Non-reference type tag %d found for \"this\" argument",
-		       thistype->tag);
-	  return FALSE;
-	}
-      
-      thistype_iface = (InterfaceTypeBlob*)&typelib->data[thistype->offset];
-
-      switch (thistype_iface->tag) 
-	{
-	case GI_TYPE_TAG_INTERFACE:
-	  break;
-	default:
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID_BLOB,
-		       "Invalid type tag %d found for \"this\" argument",
-		       thistype_iface->tag);
-	  return FALSE;
-	}
-    }
 
   pop_context (ctx);
 
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index f007e33..3760379 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -383,6 +383,8 @@ class GLibTransformer(object):
         # Strip namespace and object prefix: gtk_window_new -> new
         func.name = func.symbol[len(prefix)+1:]
         if is_method:
+            # We don't need the "this" parameter
+            del func.parameters[0]
             klass.methods.append(func)
         else:
             klass.constructors.append(func)
diff --git a/tests/scanner/drawable-expected.gir b/tests/scanner/drawable-expected.gir
index f96ab65..37ff723 100644
--- a/tests/scanner/drawable-expected.gir
+++ b/tests/scanner/drawable-expected.gir
@@ -17,9 +17,6 @@
           <type name="none" c:type="void"/>
         </return-value>
         <parameters>
-          <parameter name="drawable">
-            <type name="TestDrawable" c:type="TestDrawable*"/>
-          </parameter>
           <parameter name="x">
             <type name="int" c:type="int"/>
           </parameter>
diff --git a/tests/scanner/foo-expected.gir b/tests/scanner/foo-expected.gir
index cb771e7..55f9333 100644
--- a/tests/scanner/foo-expected.gir
+++ b/tests/scanner/foo-expected.gir
@@ -55,20 +55,12 @@
         <return-value>
           <type name="utility.Object" c:type="UtilityObject*"/>
         </return-value>
-        <parameters>
-          <parameter name="object">
-            <type name="Object" c:type="FooObject*"/>
-          </parameter>
-        </parameters>
       </method>
       <method name="various" c:identifier="foo_object_various">
         <return-value>
           <type name="none" c:type="void"/>
         </return-value>
         <parameters>
-          <parameter name="object">
-            <type name="Object" c:type="FooObject*"/>
-          </parameter>
           <parameter name="data">
             <type name="any" c:type="void*"/>
           </parameter>
@@ -82,9 +74,6 @@
           <type name="none" c:type="void"/>
         </return-value>
         <parameters>
-          <parameter name="object">
-            <type name="Object" c:type="FooObject*"/>
-          </parameter>
           <parameter name="blah">
             <type name="List" c:type="FooList*"/>
           </parameter>
@@ -95,9 +84,6 @@
           <type name="ObjectCookie" c:type="FooObjectCookie"/>
         </return-value>
         <parameters>
-          <parameter name="object">
-            <type name="Object" c:type="FooObject*"/>
-          </parameter>
           <parameter name="target">
             <type name="utf8" c:type="char*"/>
           </parameter>
@@ -108,9 +94,6 @@
           <type name="none" c:type="void"/>
         </return-value>
         <parameters>
-          <parameter name="object">
-            <type name="Object" c:type="FooObject*"/>
-          </parameter>
           <parameter name="time">
             <type name="time_t" c:type="time_t"/>
           </parameter>
@@ -253,11 +236,6 @@
         <return-value>
           <type name="none" c:type="void"/>
         </return-value>
-        <parameters>
-          <parameter name="boxed">
-            <type name="Boxed" c:type="FooBoxed*"/>
-          </parameter>
-        </parameters>
       </method>
     </record>
     <function name="boxed_new" c:identifier="foo_boxed_new">
@@ -273,11 +251,6 @@
         <return-value>
           <type name="none" c:type="void"/>
         </return-value>
-        <parameters>
-          <parameter name="dbusdata">
-            <type name="DBusData" c:type="FooDBusData*"/>
-          </parameter>
-        </parameters>
       </method>
     </record>
     <callback name="Callback" c:type="FooCallback">
