context: using GLib;
  using Gst;
  using System;
  using System.Runtime.InteropServices;
  
  namespace Gst {
  
    public struct EnumValue {
      internal int value;
      public int Value {
        get {
          return value;
        }
      }
  
      internal string value_name;
      public string Name {
        get {
          return value_name;
        }
      }
  
      internal string value_nick;
      public string Nick {
        get {
          return value_nick;
        }
      }
    }
  
    public struct FlagsValue {
      internal uint value;
      public uint Value {
        get {
          return value;
        }
      }
  
      internal string value_name;
      public string Name {
        get {
          return value_name;
        }
      }
  
      internal string value_nick;
      public string Nick {
        get {
          return value_nick;
        }
      }
    }
  
    public struct EnumInfo {
      [StructLayout (LayoutKind.Sequential) ]
      struct GTypeClass {
        IntPtr gtype;
      }
  
      [StructLayout (LayoutKind.Sequential) ]
      struct GEnumClass {
        GTypeClass gclass;
        public int minimum;
        public int maximum;
        public uint n_values;
        public IntPtr values;
      }
  
      [StructLayout (LayoutKind.Sequential) ]
      struct GEnumValue {
        public int value;
        public IntPtr value_name;
        public IntPtr value_nick;
      }
  
      [DllImport ("libgobject-2.0-0.dll") ]
      static extern IntPtr g_type_class_ref (IntPtr gtype);
      [DllImport ("libgobject-2.0-0.dll") ]
      static extern void g_type_class_unref (IntPtr gclass);
      [DllImport ("libgobject-2.0-0.dll") ]
      static extern bool g_type_is_a (IntPtr type, IntPtr is_a_type);
  
      int min;
      public int Min {
        get {
          return min;
        }
      }
  
      int max;
      public int Max {
        get {
          return max;
        }
      }
  
      EnumValue[] values;
      public EnumValue[] Values {
        get {
          return values;
        }
      }
  
      public EnumValue this[int val] {
        get {
          foreach (EnumValue v in Values) {
            if (v.value == val)
              return v;
          }
  
          throw new Exception ();
        }
      }
  
      public static bool IsEnumType (GLib.GType gtype) {
        return (g_type_is_a (gtype.Val, GType.Enum.Val));
      }
  
      public EnumInfo (GLib.GType gtype) {
        if (!IsEnumType (gtype))
          throw new ArgumentException ();
  
        IntPtr class_ptr = g_type_class_ref (gtype.Val);
        if (class_ptr == IntPtr.Zero)
          throw new Exception ();
  
        GEnumClass klass = (GEnumClass) Marshal.PtrToStructure (class_ptr, typeof (GEnumClass));
        this.min = klass.minimum;
        this.max = klass.maximum;
  
        values = new EnumValue[klass.n_values];
        int unmanaged_struct_size = Marshal.SizeOf (typeof (GEnumValue));
        for (int i = 0; i < klass.n_values; i++) {
          GEnumValue gv = (GEnumValue) Marshal.PtrToStructure (new IntPtr (klass.values.ToInt64() + i * unmanaged_struct_size), typeof (GEnumValue));
          values[i].value = gv.value;
          values[i].value_name = GLib.Marshaller.Utf8PtrToString (gv.value_name);
          values[i].value_nick = GLib.Marshaller.Utf8PtrToString (gv.value_nick);
        }
  
        g_type_class_unref (class_ptr);
      }
    }
  
    public struct FlagsInfo {
      [StructLayout (LayoutKind.Sequential) ]
      struct GTypeClass {
        IntPtr gtype;
      }
  
      [StructLayout (LayoutKind.Sequential) ]
      struct GFlagsClass {
        GTypeClass gclass;
        public uint mask;
        public uint n_values;
        public IntPtr values;
      }
  
      [StructLayout (LayoutKind.Sequential) ]
      struct GFlagsValue {
        public uint value;
        public IntPtr value_name;
        public IntPtr value_nick;
      }
  
      [DllImport ("libgobject-2.0-0.dll") ]
      static extern IntPtr g_type_class_ref (IntPtr gtype);
      [DllImport ("libgobject-2.0-0.dll") ]
      static extern void g_type_class_unref (IntPtr gclass);
      [DllImport ("libgobject-2.0-0.dll") ]
      static extern bool g_type_is_a (IntPtr type, IntPtr is_a_type);
  
      uint mask;
      public uint Mask {
        get {
          return mask;
        }
      }
  
      FlagsValue[] values;
      public FlagsValue[] Values {
        get {
          return values;
        }
      }
  
      public static bool IsFlagsType (GLib.GType gtype) {
        return (g_type_is_a (gtype.Val, GType.Flags.Val));
      }
  
      public FlagsValue[] this[uint flags] {
        get {
          System.Collections.ArrayList ret = new System.Collections.ArrayList ();
  
          foreach (FlagsValue v in Values) {
            if (flags == 0 && v.value == 0)
              ret.Add (v);
            else if ( (v.value & flags) != 0)
              ret.Add (v);
          }
  
          return (FlagsValue[]) ret.ToArray (typeof (FlagsValue));
        }
      }
  
      public FlagsInfo (GLib.GType gtype) {
        if (!IsFlagsType (gtype))
          throw new ArgumentException ();
  
        IntPtr class_ptr = g_type_class_ref (gtype.Val);
        if (class_ptr == IntPtr.Zero)
          throw new Exception ();
  
        GFlagsClass klass = (GFlagsClass) Marshal.PtrToStructure (class_ptr, typeof (GFlagsClass));
        this.mask = klass.mask;
  
        values = new FlagsValue[klass.n_values];
        int unmanaged_struct_size = Marshal.SizeOf (typeof (GFlagsValue));
  
gt:       for (int i = 0; i < klass.n_values; i++) {