diff --git a/gobject/genums.c b/gobject/genums.c
index f5d2115..8562ed9 100644
--- a/gobject/genums.c
+++ b/gobject/genums.c
@@ -431,5 +431,184 @@ g_value_get_flags (const GValue *value)
   return value->data[0].v_ulong;
 }
 
+/**
+ * g_type_enum_val_from_string:
+ * @enum_type: enum type to parse, derived from %G_TYPE_ENUM.
+ * @string: string to parse containing a numeric or a literal name, or
+ * a nick.
+ * @enum_val: integer to store the result in.
+ *
+ * Parses an @enum_type and stored the result in @enum_val.
+ *
+ * If @string is not an integer within the range of possible enum
+ * values, and if it does not match the name or the nick name of any
+ * of the possible values for the enum, %FALSE is returned.
+ *
+ * Return value: %TRUE if @string was successfully parsed and stored
+ * in @enum_val.
+ *
+ * Since: 2.16 FIXME
+ **/
+gboolean
+g_type_enum_val_from_string (GType        enum_type,
+			     const gchar *string,
+			     gint        *enum_val)
+{
+  GEnumClass *eclass;
+  GEnumValue *ev;
+  gchar *endptr;
+  gint value;
+  gboolean result = TRUE;
+
+  g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), FALSE);
+  g_return_val_if_fail (string != NULL, FALSE);
+  g_return_val_if_fail (enum_val != NULL, FALSE);
+
+  eclass = g_type_class_ref (enum_type);
+
+  value = g_ascii_strtoll (string, &endptr, 0);
+  if (endptr != string) /* parsed a number */
+    {
+      if (value < eclass->minimum || value > eclass->maximum)
+	result = FALSE;
+      else
+	*enum_val = value;
+    }
+  else
+    {
+      ev = g_enum_get_value_by_name (eclass, string);
+      if (!ev)
+	ev = g_enum_get_value_by_nick (eclass, string);
+
+      if (ev)
+	*enum_val = ev->value;
+      else
+	result = FALSE;
+    }
+
+  g_type_class_unref (eclass);
+
+  return result;
+}
+
+/**
+ * g_type_flags_val_from_string:
+ * @flags_type: enum type to parse, derived from %G_TYPE_FLAGS.
+ * @string: string to parse containing a numeric or `|' separated list
+ * of literal names, and nicks.
+ * @flags_val: unsigned integer to store the result in.
+ *
+ * Parses an @flags_type and stored the result in @flags_val.
+ *
+ * If @string is not an unsigned that match the flags mask, and one of
+ * the `|' separated string does not match the nick name or the name
+ * of any of the possible values for the flags, %FALSE is returned.
+ *
+ * Return value: %TRUE if @string was successfully parsed and stored
+ * in @flags_val.
+ *
+ * Since: 2.16 FIXME
+ **/
+gboolean
+g_type_flags_val_from_string (GType         flags_type,
+			      const gchar  *string,
+			      guint        *flags_val)
+{
+  GFlagsClass *fclass;
+  gchar *endptr, *prevptr;
+  guint i, j, ret, value;
+  gchar *flagstr;
+  GFlagsValue *fv;
+  const gchar *flag;
+  gunichar ch;
+  gboolean eos;
+
+  g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), FALSE);
+  g_return_val_if_fail (string != NULL, FALSE);
+  g_return_val_if_fail (flags_val != NULL, FALSE);
+
+  ret = TRUE;
+
+  fclass = g_type_class_ref (flags_type);
+
+  value = g_ascii_strtoull (string, &endptr, 0);
+  if (endptr != string) /* parsed a number */
+    {
+      if (value & ~fclass->mask)
+	ret = FALSE;
+      else
+	*flags_val = value;
+    }
+  else
+    {
+
+      flagstr = g_strdup (string);
+      for (value = i = j = 0; ; i++)
+	{
+
+	  eos = flagstr[i] == '\0';
+
+	  if (!eos && flagstr[i] != '|')
+	    continue;
+
+	  flag = &flagstr[j];
+	  endptr = &flagstr[i];
+
+	  if (!eos)
+	    {
+	      flagstr[i++] = '\0';
+	      j = i;
+	    }
+
+	  /* trim spaces */
+	  for (;;)
+	    {
+	      ch = g_utf8_get_char (flag);
+	      if (!g_unichar_isspace (ch))
+		break;
+	      flag = g_utf8_next_char (flag);
+	    }
+
+	  while (endptr > flag)
+	    {
+	      prevptr = g_utf8_prev_char (endptr);
+	      ch = g_utf8_get_char (prevptr);
+	      if (!g_unichar_isspace (ch))
+		break;
+	      endptr = prevptr;
+	    }
+
+	  if (endptr > flag)
+	    {
+	      *endptr = '\0';
+	      fv = g_flags_get_value_by_name (fclass, flag);
+
+	      if (!fv)
+		fv = g_flags_get_value_by_nick (fclass, flag);
+
+	      if (fv)
+		value |= fv->value;
+	      else
+		{
+		  ret = FALSE;
+		  break;
+		}
+	    }
+
+	  if (eos)
+	    {
+	      *flags_val = value;
+	      break;
+	    }
+	}
+
+      g_free (flagstr);
+    }
+
+  g_type_class_unref (fclass);
+
+  return ret;
+}
+
 #define __G_ENUMS_C__
 #include "gobjectaliasdef.c"
diff --git a/gobject/genums.h b/gobject/genums.h
index 5d16c53..3738c78 100644
--- a/gobject/genums.h
+++ b/gobject/genums.h
@@ -99,7 +99,12 @@ gint            g_value_get_enum        	(const GValue   *value);
 void            g_value_set_flags       	(GValue         *value,
 						 guint           v_flags);
 guint           g_value_get_flags       	(const GValue   *value);
-
+gboolean        g_type_enum_val_from_string     (GType           enum_type,
+						 const gchar    *string,
+						 gint           *enum_val);
+gboolean	g_type_flags_val_from_string    (GType           flags_type,
+						 const gchar    *string,
+						 guint          *flags_value);
 
 
 /* --- registration functions --- */
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index 8597af3..70bc938 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -339,6 +339,8 @@ g_type_default_interface_peek
 g_type_default_interface_ref
 g_type_default_interface_unref
 g_type_depth
+g_type_enum_val_from_string
+g_type_flags_val_from_string
 g_type_free_instance
 g_type_from_name
 g_type_fundamental
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 5fa9860..9bc79f6 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -204,6 +204,7 @@ void		      g_type_query		     (GType	       type,
 						      GTypeQuery      *query);
 
 
+
 /* --- type registration --- */
 typedef void   (*GBaseInitFunc)              (gpointer         g_class);
 typedef void   (*GBaseFinalizeFunc)          (gpointer         g_class);
