diff --git a/src/func.c b/src/func.c
index f2ede94..3c202f8 100644
--- a/src/func.c
+++ b/src/func.c
@@ -870,6 +870,21 @@ gnm_func_group_add_func (GnmFuncGroup *fn_group, GnmFunc *fn_def)
 	fn_group->functions = g_slist_prepend (fn_group->functions, fn_def);
 }
 
+static void
+gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *fn_def)
+{
+	g_return_if_fail (fn_group != NULL);
+	g_return_if_fail (fn_def != NULL);
+
+	fn_group->functions = g_slist_remove (fn_group->functions, fn_def);
+	if (fn_group->functions == NULL) {
+		categories = g_list_remove (categories, fn_group);
+		gnm_func_group_free (fn_group);
+		if (unknown_cat == fn_group)
+			unknown_cat = NULL;
+	}
+}
+
 /******************************************************************************/
 
 static void
@@ -970,15 +985,8 @@ gnm_func_free (GnmFunc *func)
 	g_return_if_fail (func->usage_count == 0);
 
 	group = func->fn_group;
-	if (group != NULL) {
-		group->functions = g_slist_remove (group->functions, func);
-		if (group->functions == NULL) {
-			categories = g_list_remove (categories, group);
-			gnm_func_group_free (group);
-			if (unknown_cat == group)
-				unknown_cat = NULL;
-		}
-	}
+	if (group != NULL)
+		gnm_func_group_remove_func (group, func);
 
 	if (!(func->flags & GNM_FUNC_IS_WORKBOOK_LOCAL)) {
 		g_hash_table_remove (functions_by_name, func->name);
@@ -1180,39 +1188,37 @@ unknownFunctionHandler (GnmFuncEvalInfo *ei,
 }
 
 /**
- * gnm_func_add_stub:
+ * gnm_func_upgrade_placeholder:
+ * @fd:
  * @fn_group:
- * @name:
  * @textdomain:
  * @load_desc: (scope async):
  * @opt_usage_notify: (scope async):
  **/
-GnmFunc *
-gnm_func_add_stub (GnmFuncGroup *fn_group,
-		   const char *name,
-		   const char *textdomain,
-		   GnmFuncLoadDesc   load_desc,
-		   GnmFuncUsageNotify opt_usage_notify)
+void
+gnm_func_upgrade_placeholder (GnmFunc *fd,
+			      GnmFuncGroup *fn_group,
+			      const char *textdomain,
+			      GnmFuncLoadDesc load_desc,
+			      GnmFuncUsageNotify opt_usage_notify)
 {
-	GnmFunc *func = g_new0 (GnmFunc, 1);
+	gnm_func_group_remove_func (fd->fn_group, fd);
 
 	if (!textdomain)
 		textdomain = GETTEXT_PACKAGE;
 
-	func->name		= name;
-	func->usage_notify	= opt_usage_notify;
-	func->fn_type		= GNM_FUNC_TYPE_STUB;
-	func->fn.load_desc	= load_desc;
-	func->textdomain        = go_string_new (textdomain);
+	fd->fn_type = GNM_FUNC_TYPE_STUB;
+	fd->fn.load_desc = load_desc;
+	fd->usage_notify = opt_usage_notify;
 
-	func->fn_group = fn_group;
-	if (fn_group != NULL)
-		gnm_func_group_add_func (fn_group, func);
+	go_string_unref (fd->textdomain);
+	fd->textdomain = go_string_new (textdomain);
 
-	g_hash_table_insert (functions_by_name,
-			     (gpointer)(func->name), func);
+	fd->flags              &= ~GNM_FUNC_IS_PLACEHOLDER;
 
-	return func;
+	fd->fn_group = fn_group;
+	if (fn_group != NULL)
+		gnm_func_group_add_func (fn_group, fd);
 }
 
 /*
@@ -1252,9 +1258,12 @@ gnm_func_add_placeholder (Workbook *scope,
 
 	if (scope != NULL)
 		desc.flags |= GNM_FUNC_IS_WORKBOOK_LOCAL;
-	else
+	else {
+#if 0
 		/* WISHLIST : it would be nice to have a log if these. */
 		g_warning ("Unknown %sfunction : %s", type, name);
+#endif
+	}
 
 	func = gnm_func_add (unknown_cat, &desc, NULL);
 
diff --git a/src/func.h b/src/func.h
index abf1ad5..13bd567 100644
--- a/src/func.h
+++ b/src/func.h
@@ -231,25 +231,26 @@ char const *gnm_func_get_name	     (GnmFunc const *fn_def,
 				      gboolean localized);
 gpointer    gnm_func_get_user_data   (GnmFunc const *func);
 void        gnm_func_set_user_data   (GnmFunc *func, gpointer user_data);
-GnmFunc	   *gnm_func_lookup	     (char const *name, Workbook *scope);	/* change scope one day */
+GnmFunc	   *gnm_func_lookup	     (char const *name, Workbook *scope);
 GnmFunc    *gnm_func_lookup_localized (char const *name, Workbook *scope);
 GSList	   *gnm_func_lookup_prefix   (char const *prefix, Workbook *scope,
 				      gboolean trans);
 GnmFunc    *gnm_func_add	     (GnmFuncGroup *group,
 				      GnmFuncDescriptor const *descriptor,
 				      const char *textdomain);
-GnmFunc    *gnm_func_add_stub	     (GnmFuncGroup *group,
-				      const char *name,
-				      const char *textdomain,
-				      GnmFuncLoadDesc load_desc,
-				      GnmFuncUsageNotify opt_usage_notify);
-GnmFunc    *gnm_func_add_placeholder (Workbook *optional_scope,			/* change scope one day */
+GnmFunc    *gnm_func_add_placeholder (Workbook *optional_scope,
 				      char const *name,
 				      char const *type,
 				      gboolean copy_name);
 GnmFunc	   *gnm_func_lookup_or_add_placeholder
-                                      (char const *name, Workbook *scope,	/* change scope one day */
+                                      (char const *name, Workbook *scope,
 				       gboolean copy_name);
+void        gnm_func_upgrade_placeholder
+				      (GnmFunc *fd,
+				       GnmFuncGroup *fn_group,
+				       const char *textdomain,
+				       GnmFuncLoadDesc load_desc,
+				       GnmFuncUsageNotify opt_usage_notify);
 
 /* TODO */
 char const *gnm_func_get_description (GnmFunc const *fn_def);
diff --git a/src/gnm-plugin.c b/src/gnm-plugin.c
index fe70716..1e6a1bc 100644
--- a/src/gnm-plugin.c
+++ b/src/gnm-plugin.c
@@ -172,7 +172,7 @@ plugin_service_function_group_func_desc_load (GnmFunc const *fn_def,
 }
 
 static void
-plugin_service_function_group_func_ref_notify  (GnmFunc *fn_def, int refcount)
+plugin_service_function_group_func_ref_notify (GnmFunc *fn_def, int refcount)
 {
 	GOPluginService *service;
 
@@ -186,6 +186,17 @@ plugin_service_function_group_func_ref_notify  (GnmFunc *fn_def, int refcount)
 }
 
 static void
+delayed_ref_notify (GOPlugin *plugin, GnmFunc *fd)
+{
+	g_signal_handlers_disconnect_by_func (plugin,
+					      G_CALLBACK (delayed_ref_notify),
+					      fd);
+
+	/* We cannot do this until after the plugin has been activated.  */
+	plugin_service_function_group_func_ref_notify (fd, 1);
+}
+
+static void
 plugin_service_function_group_activate (GOPluginService *service, GOErrorInfo **ret_error)
 {
 	PluginServiceFunctionGroup *sfg =
@@ -194,14 +205,36 @@ plugin_service_function_group_activate (GOPluginService *service, GOErrorInfo **
 	GO_INIT_RET_ERROR_INFO (ret_error);
 	sfg->func_group = gnm_func_group_fetch (sfg->category_name,
 						sfg->translated_category_name);
-	GO_SLIST_FOREACH (sfg->function_name_list, char, fname,
-		GnmFunc *fn_def;
-
-		fn_def = gnm_func_add_stub (
-			sfg->func_group, fname, sfg->textdomain,
-			plugin_service_function_group_func_desc_load,
-			plugin_service_function_group_func_ref_notify);
-		gnm_func_set_user_data (fn_def, service);
+	if (gnm_debug_flag ("plugin-func"))
+		g_printerr ("Activating group %s\n", sfg->category_name);
+	GO_SLIST_FOREACH
+		(sfg->function_name_list, char, fname,
+		 GnmFunc *fd;
+
+		 fd = gnm_func_lookup (fname, NULL);
+		 if (fd) {
+#if 0
+			 g_printerr ("Reusing placeholder for %s\n", fname);
+#endif
+		 } else {
+			 fd = gnm_func_add_placeholder
+				 (NULL, fname, "?", TRUE);
+		 }
+		 if (fd->flags & GNM_FUNC_IS_PLACEHOLDER) {
+			 gnm_func_set_user_data (fd, service);
+			 gnm_func_upgrade_placeholder
+				 (fd, sfg->func_group,
+				  sfg->textdomain,
+				  plugin_service_function_group_func_desc_load,
+				  plugin_service_function_group_func_ref_notify);
+			 if (fd->usage_count > 0)
+				 g_signal_connect (go_plugin_service_get_plugin (service),
+						   "state_changed",
+						   G_CALLBACK (delayed_ref_notify),
+						   fd);
+		 } else {
+			 g_warning ("Multiple definitions of function %s -- this cannot be good!", fname);
+		 }
 	);
 	service->is_active = TRUE;
 }
@@ -211,6 +244,9 @@ plugin_service_function_group_deactivate (GOPluginService *service, GOErrorInfo
 {
 	PluginServiceFunctionGroup *sfg = GNM_PLUGIN_SERVICE_FUNCTION_GROUP (service);
 
+	if (gnm_debug_flag ("plugin-func"))
+		g_printerr ("Deactivating group %s\n", sfg->category_name);
+
 	GO_INIT_RET_ERROR_INFO (ret_error);
 	GO_SLIST_FOREACH (sfg->function_name_list, char, fname,
 		gnm_func_free (gnm_func_lookup (fname, NULL));
diff --git a/src/parse-util.c b/src/parse-util.c
index f79ab67..73d46fb 100644
--- a/src/parse-util.c
+++ b/src/parse-util.c
@@ -1396,6 +1396,7 @@ std_func_map (GnmConventions const *convs, Workbook *scope,
 	if (!f) {
 		/* Ok, great.  What do we do if we are supposed to be using
 		   localized function names?  */
+		scope = NULL;
 		f = gnm_func_add_placeholder (scope, name, "", TRUE);
 	}
 
