context: using System;
  using System.Net;
  using System.Collections;
  using System.Runtime.InteropServices;
  using Gtk;
  using Mono.Unix;
  using Mono.Unix.Native;
  
  namespace Avahi.UI
  {
      public class ServiceDialog : Dialog
      {
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_new (string title, IntPtr parent, IntPtr dummy);
  
          [DllImport ("avahi-ui")]
          private static extern void aui_service_dialog_set_browse_service_typesv (IntPtr dialog, IntPtr[] types);
  
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_get_browse_service_types (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_get_domain (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern void aui_service_dialog_set_domain (IntPtr dialog, IntPtr domain);
  
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_get_service_type (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern void aui_service_dialog_set_service_type (IntPtr dialog, IntPtr type);
  
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_get_service_name (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern void aui_service_dialog_set_service_name (IntPtr dialog, IntPtr type);
  
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_get_address (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern UInt16 aui_service_dialog_get_port (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_get_host_name (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern IntPtr aui_service_dialog_get_txt_data (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern bool aui_service_dialog_get_resolve_service (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern void aui_service_dialog_set_resolve_service (IntPtr dialog, bool val);
  
          [DllImport ("avahi-ui")]
          private static extern bool aui_service_dialog_get_resolve_host_name (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern void aui_service_dialog_set_resolve_host_name (IntPtr dialog, bool val);
  
          [DllImport ("avahi-ui")]
          private static extern Protocol aui_service_dialog_get_address_family (IntPtr dialog);
  
          [DllImport ("avahi-ui")]
          private static extern void aui_service_dialog_set_address_family (IntPtr dialog, Protocol proto);
  
          [DllImport ("avahi-common")]
          private static extern IntPtr avahi_address_snprint (IntPtr buf, int size, IntPtr address);
  
          [DllImport ("avahi-common")]
          private static extern IntPtr avahi_string_list_get_next (IntPtr list);
  
          [DllImport ("avahi-common")]
          private static extern IntPtr avahi_string_list_get_text (IntPtr list);
  
          [DllImport ("avahi-common")]
          private static extern int avahi_string_list_get_size (IntPtr list);
  
          public string[] BrowseServiceTypes {
              get {
                  IntPtr arr = aui_service_dialog_get_browse_service_types (Raw);
  
                  ArrayList values = new ArrayList ();
  
                  for (int i = 0;;i++) {
                      IntPtr ptr = Marshal.ReadIntPtr (arr, i * Marshal.SizeOf (typeof (IntPtr)));
  
                      if (ptr == IntPtr.Zero)
                          break;
  
                      values.Add (GLib.Marshaller.Utf8PtrToString (ptr));
                  }
  
                  return (string[]) values.ToArray (typeof (string));
              } set {
                  IntPtr[] types;
                  if (value == null) {
                      types = new IntPtr[] { IntPtr.Zero };
                  } else {
                      types = new IntPtr[value.Length + 1];
  
                      for (int i = 0; i < value.Length; i++) {
                          types[i] = GLib.Marshaller.StringToPtrGStrdup (value[i]);
                      }
  
                      types[value.Length] = IntPtr.Zero;
                  }
  
                  aui_service_dialog_set_browse_service_typesv (Raw, types);
  
                  for (int i = 0;;i++) {
                      if (types[i] != IntPtr.Zero)
                          break;
  
                      GLib.Marshaller.Free (types[i]);
                  }
              }
          }
  
          public string ServiceType {
              get {
                  return GLib.Marshaller.Utf8PtrToString (aui_service_dialog_get_service_type (Raw));
              } set {
                  IntPtr type = GLib.Marshaller.StringToPtrGStrdup (value);
                  aui_service_dialog_set_service_type (Raw, type);
                  GLib.Marshaller.Free (type);
              }
          }
  
          public string ServiceName {
              get {
                  return GLib.Marshaller.Utf8PtrToString (aui_service_dialog_get_service_name (Raw));
              } set {
                  IntPtr name = GLib.Marshaller.StringToPtrGStrdup (value);
                  aui_service_dialog_set_service_name (Raw, name);
                  GLib.Marshaller.Free (name);
              }
          }
  
          public IPAddress Address {
              get {
                  return PtrToAddress (aui_service_dialog_get_address (Raw));
              }
          }
  
          public UInt16 Port {
              get {
                  return aui_service_dialog_get_port (Raw);
              }
          }
  
          public string HostName {
              get {
                  return GLib.Marshaller.Utf8PtrToString (aui_service_dialog_get_host_name (Raw));
              }
          }
  
          public string Domain {
              get {
                  return GLib.Marshaller.Utf8PtrToString (aui_service_dialog_get_domain (Raw));
              } set {
                  IntPtr domain = GLib.Marshaller.StringToPtrGStrdup (value);
                  aui_service_dialog_set_domain (Raw, domain);
                  GLib.Marshaller.Free (domain);
              }
          }
  
          public byte[][] TxtData {
              get {
                  ArrayList txtlist = new ArrayList ();
                  IntPtr txt = aui_service_dialog_get_txt_data (Raw);
  
                  for (IntPtr l = txt; l != IntPtr.Zero; l = avahi_string_list_get_next (l)) {
                      IntPtr buf = avahi_string_list_get_text (l);
                      int len = avahi_string_list_get_size (l);
  
                      byte[] txtbuf = new byte[len];
                      Marshal.Copy (buf, txtbuf, 0, len);
                      txtlist.Add (txtbuf);
                  }
  
                  return (byte[][]) txtlist.ToArray (typeof (byte[]));
              }
          }
  
          public bool ResolveServiceEnabled {
              get {
                  return aui_service_dialog_get_resolve_service (Raw);
              } set {
                  aui_service_dialog_set_resolve_service (Raw, value);
              }
          }
  
          public bool ResolveHostNameEnabled {
              get {
                  return aui_service_dialog_get_resolve_host_name (Raw);
              } set {
                  aui_service_dialog_set_resolve_host_name (Raw, value);
              }
          }
  
          public Protocol AddressFamily {
              get {
                  return aui_service_dialog_get_address_family (Raw);
              } set {
                  aui_service_dialog_set_address_family (Raw, value);
              }
          }
  
          public ServiceDialog (string title, Window parent, params object[] buttonData)
          {
              Raw = aui_service_dialog_new (title, parent == null ? IntPtr.Zero : parent.Handle,
                                            IntPtr.Zero);
  
              for (int i = 0; i < buttonData.Length - 1; i += 2) {
                  AddButton ((string) buttonData[i], (int) buttonData[i + 1]);
              }
          }
  
          private static IPAddress PtrToAddress (IntPtr ptr)
          {
              IPAddress address = null;
  
  
gt:             if (ptr != IntPtr.Zero) {