+#define SPI_ATK_PATH_PREFIX_LENGTH 27
+#define SPI_ATK_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/"
+#define SPI_ATK_OBJECT_PATH_ROOT "root"
+
+#define SPI_ATK_OBJECT_REFERENCE_TEMPLATE SPI_ATK_OBJECT_PATH_PREFIX "%d"
+
+#define SPI_DBUS_ID "spi-dbus-id"
+
+SpiRegister *spi_global_register = NULL;
+
+static const gchar * spi_register_root_path = SPI_ATK_OBJECT_PATH_PREFIX SPI_ATK_OBJECT_PATH_ROOT;
+
+enum
+{
+ OBJECT_REGISTERED,
+ OBJECT_DEREGISTERED,
+ LAST_SIGNAL
+};
+static guint register_signals[LAST_SIGNAL] = { 0 };
+
+/*---------------------------------------------------------------------------*/
+
+static void
+spi_register_finalize (GObject * object);
+
+/*---------------------------------------------------------------------------*/
+
+G_DEFINE_TYPE (SpiRegister, spi_register, G_TYPE_OBJECT)
+
+static void spi_register_class_init (SpiRegisterClass * klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ spi_register_parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+ object_class->finalize = spi_register_finalize;
+
+ register_signals [OBJECT_REGISTERED] =
+ g_signal_new ("object-registered",
+ SPI_REGISTER_TYPE,
+ G_SIGNAL_ACTION,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_OBJECT);
+
+ register_signals [OBJECT_DEREGISTERED] =
+ g_signal_new ("object-deregistered",
+ SPI_REGISTER_TYPE,
+ G_SIGNAL_ACTION,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_OBJECT);
+}
+
+static void
+spi_register_init (SpiRegister * reg)
+{
+ reg->ref2ptr = g_hash_table_new (g_direct_hash, g_direct_equal);
+ reg->reference_counter = 0;
+}
+
+static void
+deregister_object (gpointer data, GObject * gobj)
+{
+ SpiRegister *reg = SPI_REGISTER (data);
+
+ spi_register_deregister_object (reg, gobj, FALSE);
+}
+
+static void
+spi_register_remove_weak_ref (gpointer key, gpointer val, gpointer reg)
+{
+ g_object_weak_unref (val, deregister_object, reg);
+}
+
+static void
+spi_register_finalize (GObject * object)
+{
+ SpiRegister *reg = SPI_REGISTER (object);
+
+ g_hash_table_foreach (reg->ref2ptr, spi_register_remove_weak_ref, reg);
+ g_hash_table_unref (reg->ref2ptr);