func (manager *MonitorManager) Watch(fileURI string) (string, dbus.ObjectPath, string, error) {
	watcherID := atomic.AddUint32(&_WatcherCounter, 1)
	watcher, err := NewWatcher(watcherID, fileURI)
	if err != nil {
		return "", dbus.ObjectPath("/"), "", err
	}

	if err := dbus.InstallOnSession(watcher); err != nil {
		watcher.finalize()
		return "", dbus.ObjectPath("/"), "", err
	}

	manager.watchers[WatcherID(watcherID)] = watcher
	dbusInfo := watcher.GetDBusInfo()
	return dbusInfo.Dest, dbus.ObjectPath(dbusInfo.ObjectPath), dbusInfo.Interface, nil
}
func (manager *MonitorManager) Monitor(fileURI string, flags uint32) (string, dbus.ObjectPath, string, error) {
	monitorID := atomic.AddUint32(&_MonitorCounter, 1)
	monitor, err := NewMonitor(monitorID, fileURI, gio.FileMonitorFlags(flags))
	if monitor == nil {
		return "", dbus.ObjectPath("/"), "", err
	}

	if err := dbus.InstallOnSession(monitor); err != nil {
		Log.Error("Install Monitor to Session Bus failed:", err)
		monitor.finalize()
		return "", dbus.ObjectPath("/"), "", err
	}

	manager.monitors[MonitorID(monitorID)] = monitor
	dbusInfo := monitor.GetDBusInfo()
	return dbusInfo.Dest, dbus.ObjectPath(dbusInfo.ObjectPath), dbusInfo.Interface, nil
}
// Because empty object path is invalid, so JobObjectPath is used as default value.
// So empty interface means install failed.
func installJob(job dbus.DBusObject) (string, dbus.ObjectPath, string, error) {
	dest := ""
	objPath := dbus.ObjectPath(d.JobObjectPath)
	iface := ""
	if job == nil {
		Log.Warning("cannot install a nil object on dbus.")
		return dest, objPath, iface, errors.New("cannot install a nil object on dbus.")
	}

	err := dbus.InstallOnSession(job)
	if err != nil {
		Log.Warning("install dbus on session bus failed:", err)
		return dest, objPath, iface, err
	}

	dbusInfo := job.GetDBusInfo()
	return dbusInfo.Dest, dbus.ObjectPath(dbusInfo.ObjectPath), dbusInfo.Interface, nil
}