diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c
index be8f765..22d397c 100644
--- a/gst/gstelementfactory.c
+++ b/gst/gstelementfactory.c
@@ -249,6 +249,8 @@ gboolean
 gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
     GType type)
 {
+  GstPluginFeature *existing_feature;
+  GstRegistry *registry;
   GstElementFactory *factory;
   GType *interfaces;
   guint n_interfaces, i;
@@ -257,6 +259,23 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
 
   g_return_val_if_fail (name != NULL, FALSE);
   g_return_val_if_fail (g_type_is_a (type, GST_TYPE_ELEMENT), FALSE);
+  
+  registry = gst_registry_get_default ();
+  
+  /* check if feature already exists, if it exists ther eis no need to update it
+   * when the registry is getting updated, outdated plugins and all there
+   * feature are removed and readded.
+   */
+  existing_feature = gst_registry_lookup_feature (registry, name);
+  if (existing_feature) {
+    GST_DEBUG_OBJECT (registry, "update existing feature %p (%s)",
+        existing_feature, name);
+    factory = GST_ELEMENT_FACTORY_CAST (existing_feature);
+    factory->type = type;
+    GST_PLUGIN_FEATURE_CAST (factory)->loaded = TRUE;
+    gst_object_unref (existing_feature);
+    return TRUE;
+  }
 
   factory =
       GST_ELEMENT_FACTORY_CAST (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
@@ -322,8 +341,7 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
   gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE_CAST (factory), rank);
   GST_PLUGIN_FEATURE_CAST (factory)->loaded = TRUE;
 
-  gst_registry_add_feature (gst_registry_get_default (),
-      GST_PLUGIN_FEATURE_CAST (factory));
+  gst_registry_add_feature (registry, GST_PLUGIN_FEATURE_CAST (factory));
 
   return TRUE;
 
@@ -389,12 +407,12 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
 
   /* fill in the pointer to the factory in the element class. The
    * class will not be unreffed currently. 
-   * FIXME: This isn't safe and may leak a refcount on the factory if 2 threads
-   * create the first instance of an element at the same moment */
+   * Be thread safe as there might be 2 threads creating the first instance of
+   * an element at the same moment
+   */
   oclass = GST_ELEMENT_GET_CLASS (element);
-  if (G_UNLIKELY (oclass->elementfactory == NULL))
-    oclass->elementfactory = factory;
-  else
+  if (!g_atomic_pointer_compare_and_exchange (
+      (gpointer *)&oclass->elementfactory, NULL, factory))
     gst_object_unref (factory);
 
   if (name)
@@ -407,7 +425,8 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
   /* ERRORS */
 load_failed:
   {
-    GST_WARNING_OBJECT (factory, "loading plugin returned NULL!");
+    GST_WARNING_OBJECT (factory, 
+      "loading plugin containing feature %s returned NULL!", name);
     return NULL;
   }
 no_type:
diff --git a/gst/gstplugin.c b/gst/gstplugin.c
index f80ddac..a27ef69 100644
--- a/gst/gstplugin.c
+++ b/gst/gstplugin.c
@@ -535,6 +535,7 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
   gpointer ptr;
   struct stat file_status;
   GstRegistry *registry;
+  gboolean new_plugin = TRUE;
 
   g_return_val_if_fail (filename != NULL, NULL);
 
@@ -544,11 +545,12 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
   plugin = gst_registry_lookup (registry, filename);
   if (plugin) {
     if (plugin->module) {
+      /* already loaded */
       g_static_mutex_unlock (&gst_plugin_loading_mutex);
       return plugin;
     } else {
-      gst_object_unref (plugin);
-      plugin = NULL;
+      /* load plugin and update fields */
+      new_plugin = FALSE;
     }
   }
 
@@ -586,13 +588,14 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
     goto return_error;
   }
 
-  plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
-
+  if (new_plugin) {
+    plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
+    plugin->file_mtime = file_status.st_mtime;
+    plugin->file_size = file_status.st_size;
+  }
   plugin->module = module;
   plugin->filename = g_strdup (filename);
   plugin->basename = g_path_get_basename (filename);
-  plugin->file_mtime = file_status.st_mtime;
-  plugin->file_size = file_status.st_size;
 
   ret = g_module_symbol (module, "gst_plugin_desc", &ptr);
   if (!ret) {
@@ -606,15 +609,17 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
   }
   plugin->orig_desc = (GstPluginDesc *) ptr;
 
-  /* check plugin description: complain about bad values but accept them, to
-   * maintain backwards compatibility (FIXME: 0.11) */
-  CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, name, filename);
-  CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, description, filename);
-  CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, version, filename);
-  CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, license, filename);
-  CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, source, filename);
-  CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, package, filename);
-  CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, origin, filename);
+  if (new_plugin) {
+    /* check plugin description: complain about bad values but accept them, to
+     * maintain backwards compatibility (FIXME: 0.11) */
+    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, name, filename);
+    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, description, filename);
+    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, version, filename);
+    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, license, filename);
+    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, source, filename);
+    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, package, filename);
+    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, origin, filename);
+  }
 
   GST_LOG ("Plugin %p for file \"%s\" prepared, calling entry function...",
       plugin, filename);
@@ -645,8 +650,10 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
   _gst_plugin_fault_handler_filename = NULL;
   GST_INFO ("plugin \"%s\" loaded", plugin->filename);
 
-  gst_object_ref (plugin);
-  gst_default_registry_add_plugin (plugin);
+  if (new_plugin) {
+    gst_object_ref (plugin);
+    gst_default_registry_add_plugin (plugin);
+  }
 
   g_static_mutex_unlock (&gst_plugin_loading_mutex);
   return plugin;
