+/** \mainpage
+ *
+ * \section choose_api Choosing an API
+ *
+ * Avahi provides three programming APIs for integration of
+ * mDNS/DNS-SD features into your progams:
+ *
+ * \li avahi-core: an API for embedding a complete mDNS/DNS-SD stack
+ * into your software. This is intended for developers of embedded
+ * ampliances only. We dissuade from using this API in normal desktop
+ * applications since it is not a good idea to run multiple mDNS
+ * stacks simultaneously on the same host.
+ * \li The DBUS API: an extensive DBUS interface for browsing and
+ * registering mDNS/DNS-SD services using avahi-daemon. We recommend
+ * to use this API for software written in any language but
+ * C. (i.e. python)
+ * \li avahi-client: a simplifying C wrapper around the DBUS API. We
+ * recommend to use this API in C or C++ progams. The DBUS internals
+ * are hidden completely.
+ *
+ * All three APIs are very similar, however avahi-core is the most powerful.
+ *
+ * In addition to the three APIs described above Avahi supports two
+ * compatibility libraries:
+ *
+ * \li avahi-compat-libdns_sd: the original Bonjour API as documented
+ * in the header file "dns_sd.h" by Apple Computer, Inc.
+ *
+ * \li avahi-compat-howl: the HOWL API as released with HOWL 0.9.8 by
+ * Porchdog Software.
+ *
+ * Please note that these compatibility layers are incomplete and
+ * generally a waste of resources. We strongly encourage everyone to
+ * use our native APIs for newly written programs and to port older
+ * programs to one of them!
+ *
+ * \section error_reporting Error Reporting
+ *
+ * Some notes on the Avahi error handling:
+ *
+ * - Error codes are negative integers and defined as AVAHI_ERR_xx
+ * - If a function returns some kind of non-negative integer value
+ * on success, a failure is indicated by returning the error code
+ * directly.
+ * - If a function returns a pointer of some kind on success, a
+ * failure is indicated by returning NULL
+ * - The last error number may be retrieved by calling
+ * avahi_server_errno() (for the server API) or avahi_client_errno()
+ * (for the client API)
+ * - Just like the libc errno variable the Avahi errno is NOT reset
+ * to AVAHI_OK if a function call succeeds.
+ * - You may convert a numeric error code into a human readable
+ * string using avahi_strerror()
+ * - The constructor functions avahi_server_new() and
+ * avahi_client_new() return the error code in a call-by-reference
+ * argument
+ *
+ * \section event_loop Event Loop Abstraction
+ *
+ * Avahi uses for both avahi-client and avahi-core a simple event loop
+ * abstraction layer.A table AvahiPoll which contains function
+ * pointers for user defined timeout and I/O condition event source
+ * implementations, needs to be passed to avahi_server_new() and
+ * avahi_client_new(). An adapter for this abstraction layer is
+ * available for the GLib main loop in the object AvahiGLibPoll. A
+ * simple stand-alone implementation is available under the name
+ * AvahiSimplePoll.
+ *
+ * \section good_publish How to Register Services
+ *
+ * - Subscribe to server state changes. Pass a callback function
+ * pointer to avahi_client_new()/avahi_server_new(). It will be called
+ * whenever the server state changes.
+ * - Only register your services when the server is in state
+ * AVAHI_SERVER_RUNNING. If you register your services in other server
+ * states they might not be accessible since the local host name is
+ * not established.
+ * - Remove your services when the server enters
+ * AVAHI_SERVER_COLLISION state. Your services may no be reachable
+ * anymore since the local host name is no longer established.
+ * - When registering services, use the following algorithm:
+ * - Create a new entry group (i.e. avahi_entry_group_new())
+ * - Add your service(s)/additional host names (i.e. avahi_entry_group_add_service())
+ * - Commit the entry group (i.e. avahi_entry_group_commit())
+ * - Subscribe to entry group state changes.
+ * - If the entry group enters AVAHI_ENTRY_GROUP_COLLISION state the
+ * services of the entry group are automatically removed from the
+ * server. You may immediately add your services back to the entry
+ * group (but with new names, perhaps using
+ * avahi_alternative_service_name()) and commit again. Please do not
+ * free the entry group and create a new one. This would inhibit some
+ * traffic limiting algorithms in mDNS.
+ * - When you need to modify your services, use the AVAHI_PUBLISH_UPDATE flag. Please do not
+ * free the entry group and create a new one. This would inhibit some
+ * traffic limiting algorithms in mDNS.
+ *
+ * The linked functions belong to avahi-client. They all have counterparts in the DBUS API and avahi-core.
+ *
+ * \section good_browse How to Browse for Services
+ *
+ * - For normal applications you need to call avahi_service_browser_new()
+ * for the service type you want to browse for. Use
+ * avahi_client_resolve_service() to acquire service data for a a service
+ * name.
+ * - You can use avahi_domain_browser_new() to get a list of announced
+ * browsing domains. Please note that not all domains whith services
+ * on the LAN are mandatorily announced.
+ * - Network monitor software may use avahi_service_type_browser_new()
+ * to browse for the list of available service types on the LAN. This
+ * API should NOT be used in normal software since it increases
+ * traffic heavily.
+ * - There is no need to subscribe to server state changes.
+ *
+ * The linked functions belong to avahi-client. They all have
+ * counterparts in the DBUS API and avahi-core.
+ *
+ * \section daemon_dies How to Write a Client That Can Deal with Daemon Restarts
+ *
+ * With Avahi it is possible to write client applications that can
+ * deal with Avahi daemon restarts. To accomplish that make sure to
+ * pass AVAHI_CLIENT_NO_FAIL to avahi_client_new()'s flags
+ * parameter. That way avahi_client_new() will succeed even when the
+ * daemon is not running. In that case the object will enter
+ * AVAHI_CLIENT_CONNECTING state. As soon as the daemon becomes
+ * available the object will enter one of the AVAHI_CLIENT_S_xxx
+ * states. Make sure to not create browsers or entry groups before the
+ * client object has entered one of those states. As usual you will be
+ * informed about state changes with the callback function supplied to
+ * avahi_client_new(). If the client is forced to disconnect from the
+ * server it will enter AVAHI_CLIENT_FAILURE state with
+ * avahi_client_errno() == AVAHI_ERR_DISCONNECTED. Free the
+ * AvahiClient object in that case and reconnect to the server anew -
+ * again with passing AVAHI_CLIENT_NO_FAIL to avahi_client_new().
+ *
+ * We encourage to implement this in all software where service
+ * discovery is not an integral part of application. e.g. use it in
+ * all kinds of background daemons, but not in software like iChat
+ * compatible IM software.
+ *
+ * For now AVAHI_CLIENT_NO_FAIL cannot deal with DBUS daemon restarts.
+ *
+ * \section domains How to Deal Properly with Browsing Domains
+ *
+ * Due to the introduction of wide-area DNS-SD the correct handling of
+ * domains becomes more important for Avahi enabled applications. All
+ * applications that offer the user a list of services discovered with
+ * Avahi should offer some kind of editable drop down box where the
+ * user can either enter his own domain or select one of those offered
+ * by AvahiDomainBrowser. The default domain to browse should be the
+ * one returned by avahi_client_get_domain_name(). The list of domains
+ * returned by AvahiDomainBrowser is assembled by the browsing domains
+ * configured in the daemon's configuration file, the domains
+ * announced inside the default domain, the domains set with the
+ * environment variable $AVAHI_BROWSE_DOMAINS (colon-seperated) on the
+ * client side and the domains set in the XDG configuration file
+ * ~/.config/avahi/browse-domains on the client side (seperated by
+ * newlines). File managers offering some kind of "Network
+ * Neighborhood" folder should show the entries of the default domain
+ * right inside that and offer subfolders for the browsing domains
+ * returned by AvahiDomainBrowser.
+ */
+