summary refs log tree commit diff
path: root/shared
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-01-20 16:26:51 +0100
committerMichael Biebl <biebl@debian.org>2016-01-20 16:26:51 +0100
commit494f296a3baab08522617b24b1f126d8f9a17502 (patch)
treec8ef32fb0dd1c4ff35a0b38e787abb58692de0cd /shared
parent54f6333410ffd570e62717d9e77c5c987175e397 (diff)
Imported Upstream version 1.1.90 upstream/1.1.90
Diffstat (limited to 'shared')
-rw-r--r--shared/Makefile.am10
-rw-r--r--shared/Makefile.in605
-rw-r--r--shared/gsystem-local-alloc.h208
-rw-r--r--shared/nm-dbus-compat.h74
-rw-r--r--shared/nm-default.h121
-rw-r--r--shared/nm-glib.h356
-rw-r--r--shared/nm-macros-internal.h357
-rw-r--r--shared/nm-test-libnm-utils.h101
-rw-r--r--shared/nm-test-utils-impl.c466
-rw-r--r--shared/nm-test-utils.h1743
-rw-r--r--shared/nm-version-macros.h75
-rw-r--r--shared/nm-version-macros.h.in75
12 files changed, 4191 insertions, 0 deletions
diff --git a/shared/Makefile.am b/shared/Makefile.am
new file mode 100644
index 00000000..f0a1dba9
--- /dev/null
+++ b/shared/Makefile.am
@@ -0,0 +1,10 @@
+EXTRA_DIST = \
+     gsystem-local-alloc.h \
+     nm-dbus-compat.h \
+     nm-default.h \
+     nm-glib.h \
+     nm-test-utils.h \
+     nm-macros-internal.h \
+     nm-version-macros.h.in
+
+CLEANFILES=nm-version.h
diff --git a/shared/Makefile.in b/shared/Makefile.in
new file mode 100644
index 00000000..ffa641d8
--- /dev/null
+++ b/shared/Makefile.in
@@ -0,0 +1,605 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = shared
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \
+	$(top_srcdir)/m4/compiler_warnings.m4 \
+	$(top_srcdir)/m4/gettext.m4 \
+	$(top_srcdir)/m4/gnome-code-coverage.m4 \
+	$(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \
+	$(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \
+	$(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \
+	$(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+	$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+	$(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = nm-version-macros.h
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+	$(srcdir)/nm-version-macros.h.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AM_TESTS_FD_REDIRECT = @AM_TESTS_FD_REDIRECT@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@
+BLUEZ5_LIBS = @BLUEZ5_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
+CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
+CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@
+DLLTOOL = @DLLTOOL@
+DNSMASQ_PATH = @DNSMASQ_PATH@
+DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GENHTML = @GENHTML@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@
+LIBAUDIT_LIBS = @LIBAUDIT_LIBS@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNDP_CFLAGS = @LIBNDP_CFLAGS@
+LIBNDP_LIBS = @LIBNDP_LIBS@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
+LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@
+LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOG_DRIVER = @LOG_DRIVER@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@
+MM_GLIB_LIBS = @MM_GLIB_LIBS@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NEWT_CFLAGS = @NEWT_CFLAGS@
+NEWT_LIBS = @NEWT_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
+NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PATH = @PPPD_PATH@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@
+SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@
+SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@
+SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@
+SYSTEMD_JOURNAL_CFLAGS = @SYSTEMD_JOURNAL_CFLAGS@
+SYSTEMD_JOURNAL_LIBS = @SYSTEMD_JOURNAL_LIBS@
+SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@
+SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_DIR = @UDEV_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VALGRIND_RULES = @VALGRIND_RULES@
+VAPIGEN = @VAPIGEN@
+VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@
+VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nmbinary = @nmbinary@
+nmconfdir = @nmconfdir@
+nmdatadir = @nmdatadir@
+nmlibdir = @nmlibdir@
+nmrundir = @nmrundir@
+nmstatedir = @nmstatedir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+with_dhclient = @with_dhclient@
+with_dhcpcd = @with_dhcpcd@
+with_netconfig = @with_netconfig@
+with_resolvconf = @with_resolvconf@
+with_valgrind = @with_valgrind@
+EXTRA_DIST = \
+     gsystem-local-alloc.h \
+     nm-dbus-compat.h \
+     nm-default.h \
+     nm-glib.h \
+     nm-test-utils.h \
+     nm-macros-internal.h \
+     nm-version-macros.h.in
+
+CLEANFILES = nm-version.h
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu shared/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu shared/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+nm-version-macros.h: $(top_builddir)/config.status $(srcdir)/nm-version-macros.h.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/shared/gsystem-local-alloc.h b/shared/gsystem-local-alloc.h
new file mode 100644
index 00000000..51b62519
--- /dev/null
+++ b/shared/gsystem-local-alloc.h
@@ -0,0 +1,208 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Colin Walters <walters@verbum.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GSYSTEM_LOCAL_ALLOC_H__
+#define __GSYSTEM_LOCAL_ALLOC_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GS_DEFINE_CLEANUP_FUNCTION(Type, name, func) \
+  static inline void name (void *v) \
+  { \
+    func (*(Type*)v); \
+  }
+
+#define GS_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \
+  static inline void name (void *v) \
+  { \
+    if (*(Type*)v) \
+      func (*(Type*)v); \
+  }
+
+/* These functions shouldn't be invoked directly;
+ * they are stubs that:
+ * 1) Take a pointer to the location (typically itself a pointer).
+ * 2) Provide %NULL-safety where it doesn't exist already (e.g. g_object_unref)
+ */
+
+/**
+ * gs_free:
+ *
+ * Call g_free() on a variable location when it goes out of scope.
+ */
+#define gs_free __attribute__ ((cleanup(gs_local_free)))
+GS_DEFINE_CLEANUP_FUNCTION(void*, gs_local_free, g_free)
+
+/**
+ * gs_unref_object:
+ *
+ * Call g_object_unref() on a variable location when it goes out of
+ * scope.  Note that unlike g_object_unref(), the variable may be
+ * %NULL.
+ */
+#define gs_unref_object __attribute__ ((cleanup(gs_local_obj_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GObject*, gs_local_obj_unref, g_object_unref)
+
+/**
+ * gs_unref_variant:
+ *
+ * Call g_variant_unref() on a variable location when it goes out of
+ * scope.  Note that unlike g_variant_unref(), the variable may be
+ * %NULL.
+ */
+#define gs_unref_variant __attribute__ ((cleanup(gs_local_variant_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GVariant*, gs_local_variant_unref, g_variant_unref)
+
+/**
+ * gs_free_variant_iter:
+ *
+ * Call g_variant_iter_free() on a variable location when it goes out of
+ * scope.
+ */
+#define gs_free_variant_iter __attribute__ ((cleanup(gs_local_variant_iter_free)))
+GS_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, gs_local_variant_iter_free, g_variant_iter_free)
+
+/**
+ * gs_free_variant_builder:
+ *
+ * Call g_variant_builder_unref() on a variable location when it goes out of
+ * scope.
+ */
+#define gs_unref_variant_builder __attribute__ ((cleanup(gs_local_variant_builder_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, gs_local_variant_builder_unref, g_variant_builder_unref)
+
+/**
+ * gs_unref_array:
+ *
+ * Call g_array_unref() on a variable location when it goes out of
+ * scope.  Note that unlike g_array_unref(), the variable may be
+ * %NULL.
+
+ */
+#define gs_unref_array __attribute__ ((cleanup(gs_local_array_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref)
+
+/**
+ * gs_unref_ptrarray:
+ *
+ * Call g_ptr_array_unref() on a variable location when it goes out of
+ * scope.  Note that unlike g_ptr_array_unref(), the variable may be
+ * %NULL.
+
+ */
+#define gs_unref_ptrarray __attribute__ ((cleanup(gs_local_ptrarray_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, gs_local_ptrarray_unref, g_ptr_array_unref)
+
+/**
+ * gs_unref_hashtable:
+ *
+ * Call g_hash_table_unref() on a variable location when it goes out
+ * of scope.  Note that unlike g_hash_table_unref(), the variable may
+ * be %NULL.
+ */
+#define gs_unref_hashtable __attribute__ ((cleanup(gs_local_hashtable_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref)
+
+/**
+ * gs_free_list:
+ *
+ * Call g_list_free() on a variable location when it goes out
+ * of scope.
+ */
+#define gs_free_list __attribute__ ((cleanup(gs_local_free_list)))
+GS_DEFINE_CLEANUP_FUNCTION(GList*, gs_local_free_list, g_list_free)
+
+/**
+ * gs_free_slist:
+ *
+ * Call g_slist_free() on a variable location when it goes out
+ * of scope.
+ */
+#define gs_free_slist __attribute__ ((cleanup(gs_local_free_slist)))
+GS_DEFINE_CLEANUP_FUNCTION(GSList*, gs_local_free_slist, g_slist_free)
+
+/**
+ * gs_free_checksum:
+ *
+ * Call g_checksum_free() on a variable location when it goes out
+ * of scope.  Note that unlike g_checksum_free(), the variable may
+ * be %NULL.
+ */
+#define gs_free_checksum __attribute__ ((cleanup(gs_local_checksum_free)))
+GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free)
+
+/**
+ * gs_unref_bytes:
+ *
+ * Call g_bytes_unref() on a variable location when it goes out
+ * of scope.  Note that unlike g_bytes_unref(), the variable may
+ * be %NULL.
+ */
+#define gs_unref_bytes __attribute__ ((cleanup(gs_local_bytes_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref)
+
+/**
+ * gs_strfreev:
+ *
+ * Call g_strfreev() on a variable location when it goes out of scope.
+ */
+#define gs_strfreev __attribute__ ((cleanup(gs_local_strfreev)))
+GS_DEFINE_CLEANUP_FUNCTION(char**, gs_local_strfreev, g_strfreev)
+
+/**
+ * gs_free_error:
+ *
+ * Call g_error_free() on a variable location when it goes out of scope.
+ */
+#define gs_free_error __attribute__ ((cleanup(gs_local_free_error)))
+GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free)
+
+/**
+ * gs_unref_keyfile:
+ *
+ * Call g_key_file_unref() on a variable location when it goes out of scope.
+ */
+#define gs_unref_keyfile __attribute__ ((cleanup(gs_local_keyfile_unref)))
+GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_keyfile_unref, g_key_file_unref)
+
+static inline void
+gs_cleanup_close_fdp (int *fdp)
+{
+  int fd;
+
+  g_assert (fdp);
+  
+  fd = *fdp;
+  if (fd != -1)
+    (void) close (fd);
+}
+
+/**
+ * gs_fd_close:
+ *
+ * Call close() on a variable location when it goes out of scope.
+ */
+#define gs_fd_close __attribute__((cleanup(gs_cleanup_close_fdp)))
+
+G_END_DECLS
+
+#endif
diff --git a/shared/nm-dbus-compat.h b/shared/nm-dbus-compat.h
new file mode 100644
index 00000000..dd97b5fd
--- /dev/null
+++ b/shared/nm-dbus-compat.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2015 Red Hat, Inc.
+ */
+
+#ifndef __NM_DBUS_COMPAT_H__
+#define __NM_DBUS_COMPAT_H__
+
+/* Copied from <dbus/dbus-shared.h> */
+
+/* Bus names */
+
+/** The bus name used to talk to the bus itself. */
+#define DBUS_SERVICE_DBUS      "org.freedesktop.DBus"
+
+/* Paths */
+/** The object path used to talk to the bus itself. */
+#define DBUS_PATH_DBUS  "/org/freedesktop/DBus"
+/** The object path used in local/in-process-generated messages. */
+#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
+
+/* Interfaces, these #define don't do much other than
+ * catch typos at compile time
+ */
+/** The interface exported by the object with #DBUS_SERVICE_DBUS and #DBUS_PATH_DBUS */
+#define DBUS_INTERFACE_DBUS           "org.freedesktop.DBus"
+/** The interface supported by introspectable objects */
+#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
+/** The interface supported by objects with properties */
+#define DBUS_INTERFACE_PROPERTIES     "org.freedesktop.DBus.Properties"
+/** The interface supported by most dbus peers */
+#define DBUS_INTERFACE_PEER           "org.freedesktop.DBus.Peer"
+
+/** This is a special interface whose methods can only be invoked
+ * by the local implementation (messages from remote apps aren't
+ * allowed to specify this interface).
+ */
+#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
+
+/* Owner flags */
+#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
+#define DBUS_NAME_FLAG_REPLACE_EXISTING  0x2 /**< Request to replace the current primary owner */
+#define DBUS_NAME_FLAG_DO_NOT_QUEUE      0x4 /**< If we can not become the primary owner do not place us in the queue */
+
+/* Replies to request for a name */
+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER  1 /**< Service has become the primary owner of the requested name */
+#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE       2 /**< Service could not become the primary owner and has been placed in the queue */
+#define DBUS_REQUEST_NAME_REPLY_EXISTS         3 /**< Service is already in the queue */
+#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER  4 /**< Service is already the primary owner */
+
+/* Replies to releasing a name */
+#define DBUS_RELEASE_NAME_REPLY_RELEASED        1 /**< Service was released from the given name */
+#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT    2 /**< The given name does not exist on the bus */
+#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER       3 /**< Service is not an owner of the given name */
+
+/* Replies to service starts */
+#define DBUS_START_REPLY_SUCCESS         1 /**< Service was auto started */
+#define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */
+
+#endif  /* __NM_DBUS_COMPAT_H__ */
diff --git a/shared/nm-default.h b/shared/nm-default.h
new file mode 100644
index 00000000..045ad8db
--- /dev/null
+++ b/shared/nm-default.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2015 Red Hat, Inc.
+ */
+
+#ifndef __NM_DEFAULT_H__
+#define __NM_DEFAULT_H__
+
+/* makefiles define NETWORKMANAGER_COMPILATION for compiling NetworkManager.
+ * Depending on which parts are compiled, different values are set. */
+#define NM_NETWORKMANAGER_COMPILATION_DEFAULT             0x0001
+#define NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON       0x0002
+#define NM_NETWORKMANAGER_COMPILATION_LIB                 0x0004
+#define NM_NETWORKMANAGER_COMPILATION_SYSTEMD             0x0008
+#define NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY          0x0010
+
+#ifndef NETWORKMANAGER_COMPILATION
+/* For convenience, we don't require our Makefile.am to define
+ * -DNETWORKMANAGER_COMPILATION. As we now include this internal header,
+ *  we know we do a NETWORKMANAGER_COMPILATION. */
+#define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_DEFAULT
+#endif
+
+/*****************************************************************************/
+
+/* always include these headers for our internal source files. */
+
+#include "nm-glib.h"
+#include "nm-version.h"
+#include "gsystem-local-alloc.h"
+
+/*****************************************************************************/
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB) || ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+
+#include <glib/gi18n-lib.h>
+
+#else
+
+#include <glib/gi18n.h>
+
+#endif /* NM_NETWORKMANAGER_COMPILATION_LIB || NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY */
+
+/*****************************************************************************/
+
+#if (NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON || (NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_SYSTEMD
+
+/* the header is used inside src/, where additional
+ * headers are available. */
+
+#include "nm-types.h"
+#include "nm-logging.h"
+
+#endif /* NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON */
+
+/*****************************************************************************/
+
+/**
+ * The boolean type _Bool is C99 while we mostly stick to C89. However, _Bool is too
+ * convinient to miss and is effectively available in gcc and clang. So, just use it.
+ *
+ * Usually, one would include "stdbool.h" to get the "bool" define which aliases
+ * _Bool. We provide this define here, because we want to make use of it anywhere.
+ * (also, stdbool.h is again C99).
+ *
+ * Using _Bool has advantages over gboolean:
+ *
+ * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean
+ *   is a typedef for gint). Especially when having boolean fields in a struct, we can
+ *   thereby easily save some space.
+ *
+ * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing
+ *   will not work:
+ *        gboolean v1 = 1;
+ *        gboolean v2 = 2;
+ *        g_assert_cmpint (v1, ==, v2); // will fail
+ *   For that, we often to use !! to coerce gboolean values to 0 or 1:
+ *        g_assert_cmpint (!!v2, ==, TRUE);
+ *   With _Bool type, this will be handled properly by the compiler.
+ *
+ * - For structs, we might want to safe even more space and use bitfields:
+ *       struct s1 {
+ *           gboolean v1:1;
+ *       };
+ *   But the problem here is that gboolean is signed, so that
+ *   v1 will be either 0 or -1 (not 1, TRUE). Thus, the following
+ *   fails:
+ *      struct s1 s = { .v1 = TRUE, };
+ *      g_assert_cmpint (s1.v1, ==, TRUE);
+ *   It will however work just fine with bool/_Bool while retaining the
+ *   notion of having a boolean value.
+ *
+ * Also, add the defines for "true" and "false". Those are nicely highlighted by the editor
+ * as special types, contrary to glib's "TRUE"/"FALSE".
+ */
+
+#ifndef bool
+#define bool _Bool
+#define true    1
+#define false   0
+#endif
+
+/*****************************************************************************/
+
+#endif /* __NM_DEFAULT_H__ */
diff --git a/shared/nm-glib.h b/shared/nm-glib.h
new file mode 100644
index 00000000..c75e91ba
--- /dev/null
+++ b/shared/nm-glib.h
@@ -0,0 +1,356 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2008 - 2011 Red Hat, Inc.
+ */
+
+#ifndef __NM_GLIB_H__
+#define __NM_GLIB_H__
+
+
+#include <gio/gio.h>
+#include <string.h>
+
+#ifdef __clang__
+
+#undef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+#undef G_GNUC_END_IGNORE_DEPRECATIONS
+
+#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+    _Pragma("clang diagnostic push") \
+    _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
+
+#define G_GNUC_END_IGNORE_DEPRECATIONS \
+    _Pragma("clang diagnostic pop")
+
+#endif
+
+static inline void
+__g_type_ensure (GType type)
+{
+#if !GLIB_CHECK_VERSION(2,34,0)
+	if (G_UNLIKELY (type == (GType)-1))
+		g_error ("can't happen");
+#else
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+	g_type_ensure (type);
+	G_GNUC_END_IGNORE_DEPRECATIONS;
+#endif
+}
+#define g_type_ensure __g_type_ensure
+
+#if !GLIB_CHECK_VERSION(2,34,0)
+
+#define g_clear_pointer(pp, destroy) \
+    G_STMT_START {                                                                 \
+        G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer));                       \
+        /* Only one access, please */                                              \
+        gpointer *_pp = (gpointer *) (pp);                                         \
+        gpointer _p;                                                               \
+        /* This assignment is needed to avoid a gcc warning */                     \
+        GDestroyNotify _destroy = (GDestroyNotify) (destroy);                      \
+                                                                                   \
+        _p = *_pp;                                                                 \
+        if (_p)                                                                    \
+        {                                                                          \
+            *_pp = NULL;                                                           \
+            _destroy (_p);                                                         \
+        }                                                                          \
+    } G_STMT_END
+
+/* These are used to clean up the output of test programs; we can just let
+ * them no-op in older glib.
+ */
+#define g_test_expect_message(log_domain, log_level, pattern)
+#define g_test_assert_expected_messages()
+
+#else
+
+/* We build with -DGLIB_MAX_ALLOWED_VERSION set to 2.32 to make sure we don't
+ * accidentally use new API that we shouldn't. But we don't want warnings for
+ * the APIs that we emulate above.
+ */
+
+#define g_test_expect_message(domain, level, format...) \
+	G_STMT_START { \
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+		g_test_expect_message (domain, level, format); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+	} G_STMT_END
+
+#define g_test_assert_expected_messages_internal(domain, file, line, func) \
+	G_STMT_START { \
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+		g_test_assert_expected_messages_internal (domain, file, line, func); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+	} G_STMT_END
+
+#endif
+
+
+#if GLIB_CHECK_VERSION (2, 35, 0)
+/* For glib >= 2.36, g_type_init() is deprecated.
+ * But since 2.35.1 (7c42ab23b55c43ab96d0ac2124b550bf1f49c1ec) this function
+ * does nothing. Replace the call with empty statement. */
+#define nm_g_type_init()     G_STMT_START { (void) 0; } G_STMT_END
+#else
+#define nm_g_type_init()     G_STMT_START { g_type_init (); } G_STMT_END
+#endif
+
+
+/* g_test_initialized() is only available since glib 2.36. */
+#if !GLIB_CHECK_VERSION (2, 36, 0)
+#define g_test_initialized() (g_test_config_vars->test_initialized)
+#endif
+
+/* Rumtime check for glib version. First do a compile time check which
+ * (if satisfied) shortcuts the runtime check. */
+#define nm_glib_check_version(major, minor, micro) \
+    (   GLIB_CHECK_VERSION ((major), (minor), (micro)) \
+     || (   (   glib_major_version > (major)) \
+         || (   glib_major_version == (major) \
+             && glib_minor_version > (minor)) \
+         || (   glib_major_version == (major) \
+             && glib_minor_version == (minor) \
+             && glib_micro_version >= (micro))))
+
+/* g_test_skip() is only available since glib 2.38. Add a compatibility wrapper. */
+inline static void
+__nmtst_g_test_skip (const gchar *msg)
+{
+#if GLIB_CHECK_VERSION (2, 38, 0)
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+	g_test_skip (msg);
+	G_GNUC_END_IGNORE_DEPRECATIONS
+#else
+	g_debug ("%s", msg);
+#endif
+}
+#define g_test_skip __nmtst_g_test_skip
+
+
+/* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */
+inline static void
+__g_test_add_data_func_full (const char     *testpath,
+                             gpointer        test_data,
+                             GTestDataFunc   test_func,
+                             GDestroyNotify  data_free_func)
+{
+#if GLIB_CHECK_VERSION (2, 34, 0)
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+	g_test_add_data_func_full (testpath, test_data, test_func, data_free_func);
+	G_GNUC_END_IGNORE_DEPRECATIONS
+#else
+	g_return_if_fail (testpath != NULL);
+	g_return_if_fail (testpath[0] == '/');
+	g_return_if_fail (test_func != NULL);
+
+	g_test_add_vtable (testpath, 0, test_data, NULL,
+	                   (GTestFixtureFunc) test_func,
+	                   (GTestFixtureFunc) data_free_func);
+#endif
+}
+#define g_test_add_data_func_full __g_test_add_data_func_full
+
+
+#if !GLIB_CHECK_VERSION (2, 34, 0)
+#define G_DEFINE_QUARK(QN, q_n)               \
+GQuark                                        \
+q_n##_quark (void)                            \
+{                                             \
+	static GQuark q;                          \
+                                              \
+	if G_UNLIKELY (q == 0)                    \
+		q = g_quark_from_static_string (#QN); \
+                                              \
+	return q;                                 \
+}
+#endif
+
+
+static inline gboolean
+nm_g_hash_table_replace (GHashTable *hash, gpointer key, gpointer value)
+{
+	/* glib 2.40 added a return value indicating whether the key already existed
+	 * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */
+#if GLIB_CHECK_VERSION(2, 40, 0)
+	return g_hash_table_replace (hash, key, value);
+#else
+	gboolean contained = g_hash_table_contains (hash, key);
+
+	g_hash_table_replace (hash, key, value);
+	return !contained;
+#endif
+}
+
+static inline gboolean
+nm_g_hash_table_insert (GHashTable *hash, gpointer key, gpointer value)
+{
+	/* glib 2.40 added a return value indicating whether the key already existed
+	 * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */
+#if GLIB_CHECK_VERSION(2, 40, 0)
+	return g_hash_table_insert (hash, key, value);
+#else
+	gboolean contained = g_hash_table_contains (hash, key);
+
+	g_hash_table_insert (hash, key, value);
+	return !contained;
+#endif
+}
+
+static inline gboolean
+nm_g_hash_table_add (GHashTable *hash, gpointer key)
+{
+	/* glib 2.40 added a return value indicating whether the key already existed
+	 * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */
+#if GLIB_CHECK_VERSION(2, 40, 0)
+	return g_hash_table_add (hash, key);
+#else
+	gboolean contained = g_hash_table_contains (hash, key);
+
+	g_hash_table_add (hash, key);
+	return !contained;
+#endif
+}
+
+#if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST)
+static inline void
+_nm_g_ptr_array_insert (GPtrArray *array,
+                        gint       index_,
+                        gpointer   data)
+{
+	g_return_if_fail (array);
+	g_return_if_fail (index_ >= -1);
+	g_return_if_fail (index_ <= (gint) array->len);
+
+	g_ptr_array_add (array, data);
+
+	if (index_ != -1 && index_ != (gint) (array->len - 1)) {
+		memmove (&(array->pdata[index_ + 1]),
+		         &(array->pdata[index_]),
+		         (array->len - index_ - 1) * sizeof (gpointer));
+		array->pdata[index_] = data;
+	}
+}
+#endif
+#if !GLIB_CHECK_VERSION(2, 40, 0)
+#define g_ptr_array_insert(array, index, data) G_STMT_START { _nm_g_ptr_array_insert (array, index, data); } G_STMT_END
+#else
+#define g_ptr_array_insert(array, index, data) \
+	G_STMT_START { \
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+		g_ptr_array_insert (array, index, data); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+	} G_STMT_END
+#endif
+
+
+#if !GLIB_CHECK_VERSION (2, 40, 0)
+inline static gboolean
+_g_key_file_save_to_file (GKeyFile     *key_file,
+                          const gchar  *filename,
+                          GError      **error)
+{
+	gchar *contents;
+	gboolean success;
+	gsize length;
+
+	g_return_val_if_fail (key_file != NULL, FALSE);
+	g_return_val_if_fail (filename != NULL, FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	contents = g_key_file_to_data (key_file, &length, NULL);
+	g_assert (contents != NULL);
+
+	success = g_file_set_contents (filename, contents, length, error);
+	g_free (contents);
+
+	return success;
+}
+#define g_key_file_save_to_file(key_file, filename, error) \
+	_g_key_file_save_to_file (key_file, filename, error)
+#else
+#define g_key_file_save_to_file(key_file, filename, error) \
+	({ \
+		gboolean _success; \
+		\
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+		_success = g_key_file_save_to_file (key_file, filename, error); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+		_success; \
+	})
+#endif
+
+
+#if GLIB_CHECK_VERSION (2, 36, 0)
+#define g_credentials_get_unix_pid(creds, error) \
+	G_GNUC_EXTENSION ({ \
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+			(g_credentials_get_unix_pid) ((creds), (error)); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+	})
+#else
+#define g_credentials_get_unix_pid(creds, error) \
+	G_GNUC_EXTENSION ({ \
+		struct ucred *native_creds; \
+		 \
+		native_creds = g_credentials_get_native ((creds), G_CREDENTIALS_TYPE_LINUX_UCRED); \
+		g_assert (native_creds); \
+		native_creds->pid; \
+	})
+#endif
+
+
+#if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST)
+static inline gpointer *
+_nm_g_hash_table_get_keys_as_array (GHashTable *hash_table,
+                                    guint      *length)
+{
+	GHashTableIter iter;
+	gpointer key, *ret;
+	guint i = 0;
+
+	g_return_val_if_fail (hash_table, NULL);
+
+	ret = g_new0 (gpointer, g_hash_table_size (hash_table) + 1);
+	g_hash_table_iter_init (&iter, hash_table);
+
+	while (g_hash_table_iter_next (&iter, &key, NULL))
+		ret[i++] = key;
+
+	ret[i] = NULL;
+
+	if (length)
+		*length = i;
+
+	return ret;
+}
+#endif
+#if !GLIB_CHECK_VERSION(2, 40, 0)
+#define g_hash_table_get_keys_as_array(hash_table, length) \
+	G_GNUC_EXTENSION ({ \
+		_nm_g_hash_table_get_keys_as_array (hash_table, length); \
+	})
+#else
+#define g_hash_table_get_keys_as_array(hash_table, length) \
+	G_GNUC_EXTENSION ({ \
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+			(g_hash_table_get_keys_as_array) ((hash_table), (length)); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+	})
+#endif
+
+#endif  /* __NM_GLIB_H__ */
diff --git a/shared/nm-macros-internal.h b/shared/nm-macros-internal.h
new file mode 100644
index 00000000..7bddb4bd
--- /dev/null
+++ b/shared/nm-macros-internal.h
@@ -0,0 +1,357 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2014 Red Hat, Inc.
+ */
+
+#ifndef __NM_MACROS_INTERNAL_H__
+#define __NM_MACROS_INTERNAL_H__
+
+#include "nm-default.h"
+
+/********************************************************/
+
+/* http://stackoverflow.com/a/11172679 */
+#define  _NM_UTILS_MACRO_FIRST(...)                           __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway)
+#define __NM_UTILS_MACRO_FIRST_HELPER(first, ...)             first
+
+#define  _NM_UTILS_MACRO_REST(...)                            __NM_UTILS_MACRO_REST_HELPER(__NM_UTILS_MACRO_REST_NUM(__VA_ARGS__), __VA_ARGS__)
+#define __NM_UTILS_MACRO_REST_HELPER(qty, ...)                __NM_UTILS_MACRO_REST_HELPER2(qty, __VA_ARGS__)
+#define __NM_UTILS_MACRO_REST_HELPER2(qty, ...)               __NM_UTILS_MACRO_REST_HELPER_##qty(__VA_ARGS__)
+#define __NM_UTILS_MACRO_REST_HELPER_ONE(first)
+#define __NM_UTILS_MACRO_REST_HELPER_TWOORMORE(first, ...)    , __VA_ARGS__
+#define __NM_UTILS_MACRO_REST_NUM(...) \
+    __NM_UTILS_MACRO_REST_SELECT_20TH(__VA_ARGS__, \
+                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
+                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
+                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
+                TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
+#define __NM_UTILS_MACRO_REST_SELECT_20TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, ...) a20
+
+/********************************************************/
+
+/* http://stackoverflow.com/a/2124385/354393 */
+
+#define NM_NARG(...) \
+         _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N())
+#define _NM_NARG(...) \
+         _NM_NARG_ARG_N(__VA_ARGS__)
+#define _NM_NARG_ARG_N( \
+          _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
+         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
+         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
+         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
+         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
+         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
+         _61,_62,_63,N,...) N
+#define _NM_NARG_RSEQ_N() \
+         63,62,61,60,                   \
+         59,58,57,56,55,54,53,52,51,50, \
+         49,48,47,46,45,44,43,42,41,40, \
+         39,38,37,36,35,34,33,32,31,30, \
+         29,28,27,26,25,24,23,22,21,20, \
+         19,18,17,16,15,14,13,12,11,10, \
+         9,8,7,6,5,4,3,2,1,0
+
+/********************************************************/
+
+#if defined (__GNUC__)
+#define _NM_PRAGMA_WARNING_DO(warning)       G_STRINGIFY(GCC diagnostic ignored warning)
+#elif defined (__clang__)
+#define _NM_PRAGMA_WARNING_DO(warning)       G_STRINGIFY(clang diagnostic ignored warning)
+#endif
+
+/* you can only suppress a specific warning that the compiler
+ * understands. Otherwise you will get another compiler warning
+ * about invalid pragma option.
+ * It's not that bad however, because gcc and clang often have the
+ * same name for the same warning. */
+
+#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+#define NM_PRAGMA_WARNING_DISABLE(warning) \
+        _Pragma("GCC diagnostic push") \
+        _Pragma(_NM_PRAGMA_WARNING_DO(warning))
+#elif defined (__clang__)
+#define NM_PRAGMA_WARNING_DISABLE(warning) \
+        _Pragma("clang diagnostic push") \
+        _Pragma(_NM_PRAGMA_WARNING_DO(warning))
+#else
+#define NM_PRAGMA_WARNING_DISABLE(warning)
+#endif
+
+#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+#define NM_PRAGMA_WARNING_REENABLE \
+    _Pragma("GCC diagnostic pop")
+#elif defined (__clang__)
+#define NM_PRAGMA_WARNING_REENABLE \
+    _Pragma("clang diagnostic pop")
+#else
+#define NM_PRAGMA_WARNING_REENABLE
+#endif
+
+/********************************************************/
+
+/* macro to return strlen() of a compile time string. */
+#define STRLEN(str)     ( sizeof ("" str) - 1 )
+
+#define NM_SET_OUT(out_val, value) \
+	G_STMT_START { \
+		typeof(*(out_val)) *_out_val = (out_val); \
+		\
+		if (_out_val) { \
+			*_out_val = (value); \
+		} \
+	} G_STMT_END
+
+/********************************************************/
+
+#define _NM_IN_SET_EVAL_1(op, x, y1)                              \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_2(op, x, y1, y2)                          \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_3(op, x, y1, y2, y3)                      \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+         op (_x == (y3))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_4(op, x, y1, y2, y3, y4)                  \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+         op (_x == (y3))                                          \
+         op (_x == (y4))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_5(op, x, y1, y2, y3, y4, y5)              \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+         op (_x == (y3))                                          \
+         op (_x == (y4))                                          \
+         op (_x == (y5))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_N2(op, x, n, ...)        _NM_IN_SET_EVAL_##n(op, x, __VA_ARGS__)
+#define _NM_IN_SET_EVAL_N(op, x, n, ...)         _NM_IN_SET_EVAL_N2(op, x, n, __VA_ARGS__)
+
+/* Beware that this does short-circuit evaluation (use "||" instead of "|")
+ * which has a possibly unexpected non-function-like behavior.
+ * Use NM_IN_SET_SE if you need all arguments to be evaluted. */
+#define NM_IN_SET(x, ...)               _NM_IN_SET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+
+/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do
+ * short-circuit evaluation, which can make a difference if the arguments have
+ * side-effects. */
+#define NM_IN_SET_SE(x, ...)            _NM_IN_SET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+
+/*****************************************************************************/
+
+#define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \
+	(cond) ? (prefix) : "", \
+	(cond) ? (str) : (str_else), \
+	(cond) ? (suffix) : ""
+#define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)")
+
+/*****************************************************************************/
+
+#if NM_MORE_ASSERTS
+#define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END
+#else
+#define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END
+#endif
+
+/*****************************************************************************/
+
+static inline gboolean
+nm_clear_g_source (guint *id)
+{
+	if (id && *id) {
+		g_source_remove (*id);
+		*id = 0;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static inline gboolean
+nm_clear_g_signal_handler (gpointer self, gulong *id)
+{
+	if (id && *id) {
+		g_signal_handler_disconnect (self, *id);
+		*id = 0;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static inline gboolean
+nm_clear_g_variant (GVariant **variant)
+{
+	if (variant && *variant) {
+		g_variant_unref (*variant);
+		*variant = NULL;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static inline gboolean
+nm_clear_g_cancellable (GCancellable **cancellable)
+{
+	if (cancellable && *cancellable) {
+		g_cancellable_cancel (*cancellable);
+		g_object_unref (*cancellable);
+		*cancellable = NULL;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*****************************************************************************/
+
+/* Determine whether @x is a power of two (@x being an integer type).
+ * For the special cases @x equals zero or one, it also returns true.
+ * For negative @x, always returns FALSE. That only applies, if the data
+ * type of @x is signed. */
+#define nm_utils_is_power_of_two(x) ({ \
+		typeof(x) __x = (x); \
+		\
+		/* Check if the value is negative. In that case, return FALSE.
+		 * The first expression is a compile time constant, depending on whether
+		 * the type is signed. The second expression is a clumsy way for (__x >= 0),
+		 * which causes a compiler warning for unsigned types. */ \
+		    ( ( ((typeof(__x)) -1) > ((typeof(__x)) 0) ) || (__x > 0) || (__x == 0) ) \
+		 && ((__x & (__x - 1)) == 0); \
+	})
+
+/*****************************************************************************/
+
+/* check if @flags has exactly one flag (@check) set. You should call this
+ * only with @check being a compile time constant and a power of two. */
+#define NM_FLAGS_HAS(flags, check)  \
+    ( (G_STATIC_ASSERT_EXPR ( ((check) != 0) && ((check) & ((check)-1)) == 0 )), (NM_FLAGS_ANY ((flags), (check))) )
+
+#define NM_FLAGS_ANY(flags, check)  ( ( ((flags) & (check)) != 0       ) ? TRUE : FALSE )
+#define NM_FLAGS_ALL(flags, check)  ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE )
+
+#define NM_FLAGS_SET(flags, val)  ({ \
+		const typeof(flags) _flags = (flags); \
+		const typeof(flags) _val = (val); \
+		\
+		_flags | _val; \
+	})
+
+#define NM_FLAGS_UNSET(flags, val)  ({ \
+		const typeof(flags) _flags = (flags); \
+		const typeof(flags) _val = (val); \
+		\
+		_flags & (~_val); \
+	})
+
+#define NM_FLAGS_ASSIGN(flags, val, assign)  ({ \
+		const typeof(flags) _flags = (flags); \
+		const typeof(flags) _val = (val); \
+		\
+		(assign) \
+			? _flags | (_val) \
+			: _flags & (~_val); \
+	})
+
+/*****************************************************************************/
+
+#define _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, ORIG_FUNC, VERSIONED_FUNC, ARGS_TYPED, ARGS) \
+RETURN_TYPE VERSIONED_FUNC ARGS_TYPED; \
+RETURN_TYPE VERSIONED_FUNC ARGS_TYPED \
+{ \
+    return ORIG_FUNC ARGS; \
+} \
+RETURN_TYPE ORIG_FUNC ARGS_TYPED; \
+__asm__(".symver "G_STRINGIFY(VERSIONED_FUNC)", "G_STRINGIFY(ORIG_FUNC)"@"G_STRINGIFY(VERSION))
+
+#define NM_BACKPORT_SYMBOL(VERSION, RETURN_TYPE, FUNC, ARGS_TYPED, ARGS) \
+_NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, FUNC, _##FUNC##_##VERSION, ARGS_TYPED, ARGS)
+
+/*****************************************************************************/
+
+static inline char *
+nm_strstrip (char *str)
+{
+	/* g_strstrip doesn't like NULL. */
+	return str ? g_strstrip (str) : NULL;
+}
+
+/*****************************************************************************/
+
+static inline guint
+nm_encode_version (guint major, guint minor, guint micro) {
+	/* analog to the preprocessor macro NM_ENCODE_VERSION(). */
+	return (major << 16) | (minor << 8) | micro;
+}
+
+static inline void
+nm_decode_version (guint version, guint *major, guint *minor, guint *micro) {
+	*major = (version & 0xFFFF0000u) >> 16;
+	*minor = (version & 0x0000FF00u) >>  8;
+	*micro = (version & 0x000000FFu);
+}
+/*****************************************************************************/
+
+#define nm_sprintf_buf(buf, format, ...) ({ \
+		char * _buf = (buf); \
+		\
+		/* some static assert trying to ensure that the buffer is statically allocated.
+		 * It disallows a buffer size of sizeof(gpointer) to catch that. */ \
+		G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *)); \
+		g_snprintf (_buf, sizeof (buf), \
+		            ""format"", __VA_ARGS__); \
+		_buf; \
+	})
+
+#define nm_sprintf_bufa(n_elements, format, ...) \
+	({ \
+		char *_buf; \
+		\
+		G_STATIC_ASSERT (sizeof (char[MAX ((n_elements), 1)]) == (n_elements)); \
+		_buf = g_alloca (n_elements); \
+		g_snprintf (_buf, n_elements, \
+		            ""format"", __VA_ARGS__); \
+		_buf; \
+	})
+
+/*****************************************************************************/
+
+#endif /* __NM_MACROS_INTERNAL_H__ */
diff --git a/shared/nm-test-libnm-utils.h b/shared/nm-test-libnm-utils.h
new file mode 100644
index 00000000..8d111003
--- /dev/null
+++ b/shared/nm-test-libnm-utils.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2014 - 2015 Red Hat, Inc.
+ */
+
+#include "NetworkManager.h"
+
+#include "nm-test-utils.h"
+
+/*****************************************************************************/
+
+typedef struct {
+	GDBusConnection *bus;
+	GDBusProxy *proxy;
+	GPid pid;
+	int keepalive_fd;
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+	struct {
+		DBusGConnection *bus;
+	} libdbus;
+#endif
+} NMTstcServiceInfo;
+
+NMTstcServiceInfo *nmtstc_service_init (void);
+void nmtstc_service_cleanup (NMTstcServiceInfo *info);
+
+static inline void _nmtstc_auto_service_cleanup (NMTstcServiceInfo **info)
+{
+	if (info && *info) {
+		nmtstc_service_cleanup (*info);
+		*info = NULL;
+	}
+}
+
+#define NMTSTC_SERVICE_INFO_SETUP(sinfo) \
+	NM_PRAGMA_WARNING_DISABLE ("-Wunused-variable") \
+	__attribute__ ((cleanup(_nmtstc_auto_service_cleanup))) NMTstcServiceInfo *sinfo = nmtstc_service_init (); \
+	NM_PRAGMA_WARNING_REENABLE
+
+/*****************************************************************************/
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB)
+
+NMDevice *nmtstc_service_add_device (NMTstcServiceInfo *info,
+                                     NMClient *client,
+                                     const char *method,
+                                     const char *ifname);
+
+NMDevice * nmtstc_service_add_wired_device (NMTstcServiceInfo *sinfo,
+                                            NMClient *client,
+                                            const char *ifname,
+                                            const char *hwaddr,
+                                            const char **subchannels);
+
+#endif /* NM_NETWORKMANAGER_COMPILATION_LIB */
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+
+#include "nm-client.h"
+#include "nm-remote-settings.h"
+
+NMClient *nmtstc_nm_client_new (void);
+NMRemoteSettings *nmtstc_nm_remote_settings_new (void);
+
+#endif /* NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY */
+
+void nmtstc_service_add_connection (NMTstcServiceInfo *sinfo,
+                                    NMConnection *connection,
+                                    gboolean verify_connection,
+                                    char **out_path);
+
+void nmtstc_service_add_connection_variant (NMTstcServiceInfo *sinfo,
+                                            GVariant *connection,
+                                            gboolean verify_connection,
+                                            char **out_path);
+
+void nmtstc_service_update_connection (NMTstcServiceInfo *sinfo,
+                                       const char *path,
+                                       NMConnection *connection,
+                                       gboolean verify_connection);
+
+void nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo,
+                                               const char *path,
+                                               GVariant *connection,
+                                               gboolean verify_connection);
+
diff --git a/shared/nm-test-utils-impl.c b/shared/nm-test-utils-impl.c
new file mode 100644
index 00000000..5cdfda3d
--- /dev/null
+++ b/shared/nm-test-utils-impl.c
@@ -0,0 +1,466 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2010 - 2015 Red Hat, Inc.
+ *
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "nm-default.h"
+#include "NetworkManager.h"
+#include "nm-dbus-compat.h"
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+#include "nm-dbus-glib-types.h"
+#endif
+
+#include "nm-test-libnm-utils.h"
+
+/*****************************************************************************/
+
+static gboolean
+name_exists (GDBusConnection *c, const char *name)
+{
+	GVariant *reply;
+	gboolean exists = FALSE;
+
+	reply = g_dbus_connection_call_sync (c,
+	                                     DBUS_SERVICE_DBUS,
+	                                     DBUS_PATH_DBUS,
+	                                     DBUS_INTERFACE_DBUS,
+	                                     "GetNameOwner",
+	                                     g_variant_new ("(s)", name),
+	                                     NULL,
+	                                     G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                                     -1,
+	                                     NULL,
+	                                     NULL);
+	if (reply != NULL) {
+		exists = TRUE;
+		g_variant_unref (reply);
+	}
+
+	return exists;
+}
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+
+static DBusGProxy *
+_libdbus_create_proxy_test (DBusGConnection *bus)
+{
+	DBusGProxy *proxy;
+
+	proxy = dbus_g_proxy_new_for_name (bus,
+	                                   NM_DBUS_SERVICE,
+	                                   NM_DBUS_PATH,
+	                                   "org.freedesktop.NetworkManager.LibnmGlibTest");
+	g_assert (proxy);
+
+	dbus_g_proxy_set_default_timeout (proxy, G_MAXINT);
+
+	return proxy;
+}
+
+#endif
+
+NMTstcServiceInfo *
+nmtstc_service_init (void)
+{
+	NMTstcServiceInfo *info;
+	const char *args[2] = { TEST_NM_SERVICE, NULL };
+	GError *error = NULL;
+	int i;
+
+	info = g_malloc0 (sizeof (*info));
+
+	info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL,  &error);
+	g_assert_no_error (error);
+
+	/* Spawn the test service. info->keepalive_fd will be a pipe to the service's
+	 * stdin; if it closes, the service will exit immediately. We use this to
+	 * make sure the service exits if the test program crashes.
+	 */
+	g_spawn_async_with_pipes (NULL, (char **) args, NULL, 0, NULL, NULL,
+	                          &info->pid, &info->keepalive_fd, NULL, NULL, &error);
+	g_assert_no_error (error);
+
+	/* Wait until the service is registered on the bus */
+	for (i = 1000; i > 0; i--) {
+		if (name_exists (info->bus, "org.freedesktop.NetworkManager"))
+			break;
+		g_usleep (G_USEC_PER_SEC / 50);
+	}
+	g_assert (i > 0);
+
+	/* Grab a proxy to our fake NM service to trigger tests */
+	info->proxy = g_dbus_proxy_new_sync (info->bus,
+	                                     G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+	                                     G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
+	                                     G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+	                                     NULL,
+	                                     NM_DBUS_SERVICE,
+	                                     NM_DBUS_PATH,
+	                                     "org.freedesktop.NetworkManager.LibnmGlibTest",
+	                                     NULL, &error);
+	g_assert_no_error (error);
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+	info->libdbus.bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	g_assert_no_error (error);
+	g_assert (info->libdbus.bus);
+#endif
+	return info;
+}
+
+void
+nmtstc_service_cleanup (NMTstcServiceInfo *info)
+{
+	int i;
+
+	g_object_unref (info->proxy);
+	kill (info->pid, SIGTERM);
+
+	/* Wait until the bus notices the service is gone */
+	for (i = 100; i > 0; i--) {
+		if (!name_exists (info->bus, "org.freedesktop.NetworkManager"))
+			break;
+		g_usleep (G_USEC_PER_SEC / 50);
+	}
+	g_assert (i > 0);
+
+	g_object_unref (info->bus);
+	close (info->keepalive_fd);
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+	g_clear_pointer (&info->libdbus.bus, dbus_g_connection_unref);
+#endif
+
+	memset (info, 0, sizeof (*info));
+	g_free (info);
+}
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB)
+
+typedef struct {
+	GMainLoop *loop;
+	const char *ifname;
+	char *path;
+	NMDevice *device;
+} AddDeviceInfo;
+
+static void
+device_added_cb (NMClient *client,
+                 NMDevice *device,
+                 gpointer user_data)
+{
+	AddDeviceInfo *info = user_data;
+
+	g_assert (device);
+	g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, info->path);
+	g_assert_cmpstr (nm_device_get_iface (device), ==, info->ifname);
+
+	info->device = device;
+	g_main_loop_quit (info->loop);
+}
+
+static gboolean
+timeout (gpointer user_data)
+{
+	g_assert_not_reached ();
+	return G_SOURCE_REMOVE;
+}
+
+static GVariant *
+call_add_wired_device (GDBusProxy *proxy, const char *ifname, const char *hwaddr,
+                       const char **subchannels, GError **error)
+{
+	const char *empty[] = { NULL };
+
+	if (!hwaddr)
+		hwaddr = "/";
+	if (!subchannels)
+		subchannels = empty;
+
+	return g_dbus_proxy_call_sync (proxy,
+	                               "AddWiredDevice",
+	                               g_variant_new ("(ss^as)", ifname, hwaddr, subchannels),
+	                               G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                               3000,
+	                               NULL,
+	                               error);
+}
+
+static GVariant *
+call_add_device (GDBusProxy *proxy, const char *method, const char *ifname, GError **error)
+{
+	return g_dbus_proxy_call_sync (proxy,
+	                               method,
+	                               g_variant_new ("(s)", ifname),
+	                               G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                               3000,
+	                               NULL,
+	                               error);
+}
+
+static NMDevice *
+add_device_common (NMTstcServiceInfo *sinfo, NMClient *client,
+                   const char *method, const char *ifname,
+                   const char *hwaddr, const char **subchannels)
+{
+	AddDeviceInfo info;
+	GError *error = NULL;
+	GVariant *ret;
+	guint timeout_id;
+
+	if (g_strcmp0 (method, "AddWiredDevice") == 0)
+		ret = call_add_wired_device (sinfo->proxy, ifname, hwaddr, subchannels, &error);
+	else
+		ret = call_add_device (sinfo->proxy, method, ifname, &error);
+
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
+	g_variant_get (ret, "(o)", &info.path);
+	g_variant_unref (ret);
+
+	/* Wait for libnm to find the device */
+	info.ifname = ifname;
+	info.loop = g_main_loop_new (NULL, FALSE);
+	g_signal_connect (client, "device-added",
+	                  G_CALLBACK (device_added_cb), &info);
+	timeout_id = g_timeout_add_seconds (5, timeout, NULL);
+	g_main_loop_run (info.loop);
+
+	g_source_remove (timeout_id);
+	g_signal_handlers_disconnect_by_func (client, device_added_cb, &info);
+	g_free (info.path);
+	g_main_loop_unref (info.loop);
+
+	return info.device;
+}
+
+NMDevice *
+nmtstc_service_add_device (NMTstcServiceInfo *sinfo, NMClient *client,
+                           const char *method, const char *ifname)
+{
+	return add_device_common (sinfo, client, method, ifname, NULL, NULL);
+}
+
+NMDevice *
+nmtstc_service_add_wired_device (NMTstcServiceInfo *sinfo, NMClient *client,
+                                 const char *ifname, const char *hwaddr,
+                                 const char **subchannels)
+{
+	return add_device_common (sinfo, client, "AddWiredDevice", ifname, hwaddr, subchannels);
+}
+
+#endif /* NM_NETWORKMANAGER_COMPILATION_LIB */
+
+void
+nmtstc_service_add_connection (NMTstcServiceInfo *sinfo,
+                               NMConnection *connection,
+                               gboolean verify_connection,
+                               char **out_path)
+{
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+	gs_unref_hashtable GHashTable *new_settings = NULL;
+	gboolean success;
+	gs_free_error GError *error = NULL;
+	gs_free char *path = NULL;
+	gs_unref_object DBusGProxy *proxy = NULL;
+
+	g_assert (sinfo);
+	g_assert (NM_IS_CONNECTION (connection));
+
+	new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+
+	proxy = _libdbus_create_proxy_test (sinfo->libdbus.bus);
+
+	success = dbus_g_proxy_call (proxy,
+	                             "AddConnection",
+	                             &error,
+	                             DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings,
+	                             G_TYPE_BOOLEAN, verify_connection,
+	                             G_TYPE_INVALID,
+	                             DBUS_TYPE_G_OBJECT_PATH, &path,
+	                             G_TYPE_INVALID);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	g_assert (path && *path);
+
+	if (out_path)
+		*out_path = g_strdup (path);
+#else
+	nmtstc_service_add_connection_variant (sinfo,
+	                                       nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL),
+	                                       verify_connection,
+	                                       out_path);
+#endif
+}
+
+void
+nmtstc_service_add_connection_variant (NMTstcServiceInfo *sinfo,
+                                       GVariant *connection,
+                                       gboolean verify_connection,
+                                       char **out_path)
+{
+	GVariant *result;
+	GError *error = NULL;
+
+	g_assert (sinfo);
+	g_assert (G_IS_DBUS_PROXY (sinfo->proxy));
+	g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}")));
+
+	result = g_dbus_proxy_call_sync (sinfo->proxy,
+	                                 "AddConnection",
+	                                 g_variant_new ("(vb)", connection, verify_connection),
+	                                 G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                                 3000,
+	                                 NULL,
+	                                 &error);
+	g_assert_no_error (error);
+	g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)")));
+	if (out_path)
+		g_variant_get (result, "(o)", out_path);
+	g_variant_unref (result);
+}
+
+void
+nmtstc_service_update_connection (NMTstcServiceInfo *sinfo,
+                                  const char *path,
+                                  NMConnection *connection,
+                                  gboolean verify_connection)
+{
+	if (!path)
+		path = nm_connection_get_path (connection);
+	g_assert (path);
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+	{
+		gs_unref_hashtable GHashTable *new_settings = NULL;
+		gboolean success;
+		gs_free_error GError *error = NULL;
+		gs_unref_object DBusGProxy *proxy = NULL;
+
+		g_assert (sinfo);
+		g_assert (NM_IS_CONNECTION (connection));
+
+		new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+
+		proxy = _libdbus_create_proxy_test (sinfo->libdbus.bus);
+
+		success = dbus_g_proxy_call (proxy,
+		                             "UpdateConnection",
+		                             &error,
+		                             DBUS_TYPE_G_OBJECT_PATH, path,
+		                             DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings,
+		                             G_TYPE_BOOLEAN, verify_connection,
+		                             G_TYPE_INVALID,
+		                             G_TYPE_INVALID);
+		g_assert_no_error (error);
+		g_assert (success);
+	}
+#else
+	nmtstc_service_update_connection_variant (sinfo,
+	                                          path,
+	                                          nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL),
+	                                          verify_connection);
+#endif
+}
+
+void
+nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo,
+                                          const char *path,
+                                          GVariant *connection,
+                                          gboolean verify_connection)
+{
+	GVariant *result;
+	GError *error = NULL;
+
+	g_assert (sinfo);
+	g_assert (G_IS_DBUS_PROXY (sinfo->proxy));
+	g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}")));
+	g_assert (path && path[0] == '/');
+
+	result = g_dbus_proxy_call_sync (sinfo->proxy,
+	                                 "UpdateConnection",
+	                                 g_variant_new ("(ovb)", path, connection, verify_connection),
+	                                 G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                                 3000,
+	                                 NULL,
+	                                 &error);
+	g_assert_no_error (error);
+	g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("()")));
+	g_variant_unref (result);
+}
+
+/*****************************************************************************/
+
+#if ((NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY)
+
+NMClient *
+nmtstc_nm_client_new (void)
+{
+	NMClient *client;
+	DBusGConnection *bus;
+	GError *error = NULL;
+	gboolean success;
+
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	g_assert_no_error (error);
+	g_assert (bus);
+
+	client = g_object_new (NM_TYPE_CLIENT,
+	                       NM_OBJECT_DBUS_CONNECTION, bus,
+	                       NM_OBJECT_DBUS_PATH, NM_DBUS_PATH,
+	                       NULL);
+	g_assert (client != NULL);
+
+	dbus_g_connection_unref (bus);
+
+	success = g_initable_init (G_INITABLE (client), NULL, &error);
+	g_assert_no_error (error);
+	g_assert (success == TRUE);
+
+	return client;
+}
+
+NMRemoteSettings *
+nmtstc_nm_remote_settings_new (void)
+{
+	NMRemoteSettings *settings;
+	DBusGConnection *bus;
+	GError *error = NULL;
+
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	g_assert_no_error (error);
+	g_assert (bus);
+
+	settings = nm_remote_settings_new (bus);
+	g_assert (settings);
+
+	dbus_g_connection_unref (bus);
+
+	return settings;
+}
+
+#endif /* NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY */
+
+/*****************************************************************************/
diff --git a/shared/nm-test-utils.h b/shared/nm-test-utils.h
new file mode 100644
index 00000000..0402201c
--- /dev/null
+++ b/shared/nm-test-utils.h
@@ -0,0 +1,1743 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2014 Red Hat, Inc.
+ */
+
+#ifndef __NM_TEST_UTILS_H__
+#define __NM_TEST_UTILS_H__
+
+/*******************************************************************************
+ * HOWTO run tests.
+ *
+ * Our tests (make check) include this header-only file nm-test-utils.h.
+ *
+ * Logging:
+ *   In tests, nm-logging redirects to glib logging. By default, glib suppresses all debug
+ *   messages unless you set G_MESSAGES_DEBUG. To enable debug logging, you can explicitly set
+ *   G_MESSAGES_DEBUG. Otherwise, nm-test will set G_MESSAGES_DEBUG=all in debug mode (see below).
+ *   For nm-logging, you can configure the log-level and domains via NMTST_DEBUG environment
+ *   variable.
+ *
+ * Assert-logging:
+ *   Some tests assert against logged messages (g_test_expect_message()).
+ *   By specifying no-expect-message in NMTST_DEBUG, you can disable assert logging
+ *   and g_test_assert_expected_messages() will not fail.
+ *
+ * NMTST_SEED_RAND environment variable:
+ *   Tests that use random numbers from nmtst_get_rand() get seeded randomly at each start.
+ *   You can specify the seed by setting NMTST_SEED_RAND. Also, tests will print the seed
+ *   to stdout, so that you know the choosen seed.
+ *
+ *
+ * NMTST_DEBUG environment variable:
+ *
+ * "debug", "no-debug": when at test is run in debug mode, it might behave differently,
+ *   depending on the test. See nmtst_is_debug().
+ *   Known differences:
+ *    - a test might leave the logging level unspecified. In this case, running in
+ *      debug mode, will turn on DEBUG logging, otherwise WARN logging only.
+ *    - if G_MESSAGES_DEBUG is unset, nm-test will set G_MESSAGES_DEBUG=all
+ *      for tests that don't do assert-logging.
+ *   Debug mode is determined as follows (highest priority first):
+ *    - command line option --debug/--no-debug
+ *    - NMTST_DEBUG=debug/no-debug
+ *    - setting NMTST_DEBUG implies debugging turned on
+ *    - g_test_verbose()
+ *
+ * "no-expect-message": for tests that would assert against log messages, disable
+ *   those asserts.
+ *
+ * "log-level=LEVEL", "log-domains=DOMAIN": reset the log level and domain for tests.
+ *    It only has an effect for nm-logging messages.
+ *    This has no effect if the test asserts against logging (unless no-expect-message),
+ *    otherwise, changing the logging would break tests.
+ *    If you set the level to DEBUG or TRACE, it also sets G_MESSAGES_DEBUG=all (unless
+ *    in assert-logging mode and unless G_MESSAGES_DEBUG is already defined).
+ *
+ * "TRACE", this is shorthand for "log-level=TRACE".
+ *
+ * "sudo-cmd=PATH": when running root tests as normal user, the test will execute
+ *   itself by invoking sudo at PATH.
+ *   For example
+ *     NMTST_DEBUG="sudo-cmd=$PWD/tools/test-sudo-wrapper.sh" make -C src/platform/tests/ check
+ *
+ * "slow|quick|thorough": enable/disable long-running tests. This sets nmtst_test_quick().
+ *   Whether long-running tests are enabled is determined as follows (highest priority first):
+ *     - specifying the value in NMTST_DEBUG has highest priority
+ *     - respect g_test_quick(), if the command line contains '-mslow', '-mquick', '-mthorough'.
+ *     - use compile time default
+ *
+ * "p=PATH"|"s=PATH": passes the path to g_test_init() as "-p" and "-s", respectively.
+ *   Unfortunately, these options conflict with "--tap" which our makefile passes to the
+ *   tests, thus it's only useful outside of `make check`.
+ *
+ *******************************************************************************/
+
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "nm-default.h"
+#include "nm-utils.h"
+#include "nm-macros-internal.h"
+
+#ifdef __NETWORKMANAGER_LOGGING_H__
+/* We are running tests under src/. Let's include some files by default.
+ * They are useful, and affect how nm-test-utils.h itself behaves. */
+#include "NetworkManagerUtils.h"
+#include "nm-keyfile-internal.h"
+#endif
+
+/*******************************************************************************/
+
+/* general purpose functions that have no dependency on other nmtst functions */
+
+inline static void
+nmtst_assert_error (GError *error,
+                    GQuark expect_error_domain,
+                    gint expect_error_code,
+                    const char *expect_error_pattern)
+{
+	if (expect_error_domain)
+		g_assert_error (error, expect_error_domain, expect_error_code);
+	else
+		g_assert (error);
+	g_assert (error->message);
+	if (   expect_error_pattern
+	    && !g_pattern_match_simple (expect_error_pattern, error->message)) {
+		g_error ("error message does not have expected pattern '%s'. Instead it is '%s' (%s, %d)",
+		         expect_error_pattern, error->message, g_quark_to_string (error->domain), error->code);
+	}
+}
+
+#define NMTST_WAIT(max_wait_ms, wait) \
+	({ \
+		gboolean _not_expired = TRUE; \
+		gint64 _nmtst_end, _nmtst_max_wait_us = (max_wait_ms) * 1000L; \
+		\
+		_nmtst_end = g_get_monotonic_time () + _nmtst_max_wait_us; \
+		while (TRUE) { \
+			{ wait }; \
+			if (g_get_monotonic_time () > _nmtst_end) { \
+				_not_expired = FALSE; \
+				break; \
+			} \
+		} \
+		_not_expired; \
+	})
+
+#define NMTST_WAIT_ASSERT(max_wait_ms, wait) \
+	G_STMT_START { \
+		if (!(NMTST_WAIT (max_wait_ms, wait))) \
+			g_assert_not_reached (); \
+	} G_STMT_END
+
+inline static void
+_nmtst_assert_success (gboolean success, GError *error, const char *file, int line)
+{
+	if (!success || error)
+		g_error ("(%s:%d) FAILURE success=%d, error=%s", file, line, success, error && error->message ? error->message : "(no error)");
+}
+#define nmtst_assert_success(success, error) _nmtst_assert_success ((success), (error), __FILE__, __LINE__)
+
+/*******************************************************************************/
+
+struct __nmtst_internal
+{
+	GRand *rand0;
+	guint32 rand_seed;
+	GRand *rand;
+	gboolean is_debug;
+	gboolean assert_logging;
+	gboolean no_expect_message;
+	gboolean test_quick;
+	gboolean test_tap_log;
+	char *sudo_cmd;
+	char **orig_argv;
+};
+
+extern struct __nmtst_internal __nmtst_internal;
+
+#define NMTST_DEFINE() \
+struct __nmtst_internal __nmtst_internal = { 0 }; \
+\
+__attribute__ ((destructor)) static void \
+_nmtst_exit (void) \
+{ \
+	__nmtst_internal.assert_logging = FALSE; \
+	g_test_assert_expected_messages (); \
+	nmtst_free (); \
+}
+
+
+inline static gboolean
+nmtst_initialized (void)
+{
+	return !!__nmtst_internal.rand0;
+}
+
+#define __NMTST_LOG(cmd, ...) \
+	G_STMT_START { \
+		g_assert (nmtst_initialized ()); \
+		if (!__nmtst_internal.assert_logging || __nmtst_internal.no_expect_message) { \
+			cmd (__VA_ARGS__); \
+		} else { \
+			printf (_NM_UTILS_MACRO_FIRST (__VA_ARGS__) "\n" _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
+		} \
+	} G_STMT_END
+
+/* split the string inplace at specific delimiters, allowing escaping with '\\'.
+ * Returns a zero terminated array of pointers into @str.
+ *
+ * The caller must g_free() the returned argv array.
+ **/
+inline static char **
+nmtst_str_split (char *str, const char *delimiters)
+{
+	const char *d;
+	GArray *result = g_array_sized_new (TRUE, FALSE, sizeof (char *), 3);
+
+	g_assert (str);
+	g_assert (delimiters && !strchr (delimiters, '\\'));
+
+	while (*str) {
+		gsize i = 0, j = 0;
+
+		while (TRUE) {
+			char c = str[i];
+
+			if (c == '\0') {
+				str[j++] = 0;
+				break;
+			} else if (c == '\\') {
+				str[j++] = str[++i];
+				if (!str[i])
+					break;
+			} else {
+				for (d = delimiters; *d; d++) {
+					if (c == *d) {
+						str[j++] = 0;
+						i++;
+						goto BREAK_INNER_LOOPS;
+					}
+				}
+				str[j++] = c;
+			}
+			i++;
+		}
+
+BREAK_INNER_LOOPS:
+		g_array_append_val (result, str);
+		str = &str[i];
+	}
+
+	return (char **) g_array_free (result, FALSE);
+}
+
+
+/* free instances allocated by nmtst (especially nmtst_init()) on shutdown
+ * to release memory. After nmtst_free(), the test is uninitialized again. */
+inline static void
+nmtst_free (void)
+{
+	if (!nmtst_initialized ())
+		return;
+
+	g_rand_free (__nmtst_internal.rand0);
+	if (__nmtst_internal.rand)
+		g_rand_free (__nmtst_internal.rand);
+	g_free (__nmtst_internal.sudo_cmd);
+	g_strfreev (__nmtst_internal.orig_argv);
+
+	memset (&__nmtst_internal, 0, sizeof (__nmtst_internal));
+}
+
+inline static void
+__nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_level, const char *log_domains, gboolean *out_set_logging)
+{
+	const char *nmtst_debug;
+	gboolean is_debug = FALSE;
+	char *c_log_level = NULL, *c_log_domains = NULL;
+	char *sudo_cmd = NULL;
+	GArray *debug_messages = g_array_new (TRUE, FALSE, sizeof (char *));
+	int i;
+	gboolean no_expect_message = FALSE;
+	gboolean _out_set_logging;
+	gboolean test_quick = FALSE;
+	gboolean test_quick_set = FALSE;
+	gboolean test_quick_argv = FALSE;
+	gs_unref_ptrarray GPtrArray *p_tests = NULL;
+	gs_unref_ptrarray GPtrArray *s_tests = NULL;
+
+	if (!out_set_logging)
+		out_set_logging = &_out_set_logging;
+	*out_set_logging = FALSE;
+
+	g_assert (!nmtst_initialized ());
+
+	g_assert (!((!!argc) ^ (!!argv)));
+	g_assert (!argc || (g_strv_length (*argv) == *argc));
+	g_assert (!assert_logging || (!log_level && !log_domains));
+
+#ifdef __NETWORKMANAGER_UTILS_H__
+	if (!nm_utils_get_testing_initialized ())
+		_nm_utils_set_testing (_NM_UTILS_TEST_GENERAL);
+#endif
+
+	if (argc)
+		__nmtst_internal.orig_argv = g_strdupv (*argv);
+
+	__nmtst_internal.assert_logging = !!assert_logging;
+
+	nm_g_type_init ();
+
+	is_debug = g_test_verbose ();
+
+	nmtst_debug = g_getenv ("NMTST_DEBUG");
+	if (nmtst_debug) {
+		char **d_argv, **i_argv, *nmtst_debug_copy;
+
+		/* By setting then NMTST_DEBUG variable, @is_debug is set automatically.
+		 * This can be reverted with no-debug (on command line or environment variable). */
+		is_debug = TRUE;
+
+		nmtst_debug_copy = g_strdup (nmtst_debug);
+		d_argv = nmtst_str_split (nmtst_debug_copy, ",; \t\r\n");
+
+		for (i_argv = d_argv; *i_argv; i_argv++) {
+			const char *debug = *i_argv;
+
+			if (!g_ascii_strcasecmp (debug, "debug"))
+				is_debug = TRUE;
+			else if (!g_ascii_strcasecmp (debug, "no-debug")) {
+				/* when specifying the NMTST_DEBUG variable, we set is_debug to true. Use this flag to disable this
+				 * (e.g. for only setting the log-level, but not is_debug). */
+				is_debug = FALSE;
+			} else if (!g_ascii_strncasecmp (debug, "log-level=", strlen ("log-level="))) {
+				g_free (c_log_level);
+				log_level = c_log_level = g_strdup (&debug[strlen ("log-level=")]);
+			} else if (!g_ascii_strcasecmp (debug, "TRACE")) {
+				g_free (c_log_level);
+				log_level = c_log_level = g_strdup (debug);
+			} else if (!g_ascii_strncasecmp (debug, "log-domains=", strlen ("log-domains="))) {
+				g_free (c_log_domains);
+				log_domains = c_log_domains = g_strdup (&debug[strlen ("log-domains=")]);
+			} else if (!g_ascii_strncasecmp (debug, "sudo-cmd=", strlen ("sudo-cmd="))) {
+				g_free (sudo_cmd);
+				sudo_cmd = g_strdup (&debug[strlen ("sudo-cmd=")]);
+			} else if (!g_ascii_strcasecmp (debug, "no-expect-message")) {
+				no_expect_message = TRUE;
+			} else if (!g_ascii_strncasecmp (debug, "p=", strlen ("p="))) {
+				if (!p_tests)
+					p_tests = g_ptr_array_new_with_free_func (g_free);
+				g_ptr_array_add (p_tests, g_strdup (&debug[strlen ("p=")]));
+			} else if (!g_ascii_strncasecmp (debug, "s=", strlen ("s="))) {
+				if (!s_tests)
+					s_tests = g_ptr_array_new_with_free_func (g_free);
+				g_ptr_array_add (s_tests, g_strdup (&debug[strlen ("s=")]));
+			} else if (!g_ascii_strcasecmp (debug, "slow") || !g_ascii_strcasecmp (debug, "thorough")) {
+				test_quick = FALSE;
+				test_quick_set = TRUE;
+			} else if (!g_ascii_strcasecmp (debug, "quick")) {
+				test_quick = TRUE;
+				test_quick_set = TRUE;
+			} else {
+				char *msg = g_strdup_printf (">>> nmtst: ignore unrecognized NMTST_DEBUG option \"%s\"", debug);
+
+				g_array_append_val (debug_messages, msg);
+			}
+		}
+
+		g_free (d_argv);
+		g_free (nmtst_debug_copy);
+	}
+
+	if (__nmtst_internal.orig_argv) {
+		char **a = __nmtst_internal.orig_argv;
+
+		for (; *a; a++) {
+			if (!g_ascii_strcasecmp (*a, "--debug"))
+				is_debug = TRUE;
+			else if (!g_ascii_strcasecmp (*a, "--no-debug"))
+				is_debug = FALSE;
+			else if (   !strcmp (*a, "-m=slow")
+			         || !strcmp (*a, "-m=thorough")
+			         || !strcmp (*a, "-m=quick")
+			         || (!strcmp (*a, "-m") && *(a+1)
+			                                && (   !strcmp (*(a+1), "quick")
+			                                    || !strcmp (*(a+1), "slow")
+			                                    || !strcmp (*(a+1), "thorough"))))
+				test_quick_argv = TRUE;
+			else if (strcmp (*a, "--tap") == 0)
+				__nmtst_internal.test_tap_log = TRUE;
+		}
+	}
+
+	if (!argc || g_test_initialized ()) {
+		if (p_tests || s_tests) {
+			char *msg = g_strdup_printf (">>> nmtst: ignore -p and -s options for test which calls g_test_init() itself");
+
+			g_array_append_val (debug_messages, msg);
+		}
+	} else {
+		/* g_test_init() is a variadic function, so we cannot pass it
+		 * (variadic) arguments. If you need to pass additional parameters,
+		 * call nmtst_init() with argc==NULL and call g_test_init() yourself. */
+
+		/* g_test_init() sets g_log_set_always_fatal() for G_LOG_LEVEL_WARNING
+		 * and G_LOG_LEVEL_CRITICAL. So, beware that the test will fail if you
+		 * have any WARN or ERR log messages -- unless you g_test_expect_message(). */
+		GPtrArray *arg_array = g_ptr_array_new ();
+		gs_free char **arg_array_c = NULL;
+		int arg_array_n, j;
+		static char **s_tests_x, **p_tests_x;
+
+		if (*argc) {
+			for (i = 0; i < *argc; i++)
+				g_ptr_array_add (arg_array, (*argv)[i]);
+		} else
+			g_ptr_array_add (arg_array, "./test");
+
+		if (test_quick_set && !test_quick_argv)
+			g_ptr_array_add (arg_array, "-m=quick");
+
+		if (!__nmtst_internal.test_tap_log) {
+			for (i = 0; p_tests && i < p_tests->len; i++) {
+				g_ptr_array_add (arg_array, "-p");
+				g_ptr_array_add (arg_array, p_tests->pdata[i]);
+			}
+			for (i = 0; s_tests && i < s_tests->len; i++) {
+				g_ptr_array_add (arg_array, "-s");
+				g_ptr_array_add (arg_array, s_tests->pdata[i]);
+			}
+		} else if (p_tests || s_tests) {
+			char *msg = g_strdup_printf (">>> nmtst: ignore -p and -s options for tap-tests");
+
+			g_array_append_val (debug_messages, msg);
+		}
+
+		g_ptr_array_add (arg_array, NULL);
+
+		arg_array_n = arg_array->len - 1;
+		arg_array_c = (char **) g_ptr_array_free (arg_array, FALSE);
+
+		g_test_init (&arg_array_n, &arg_array_c, NULL);
+
+		if (*argc > 1) {
+			/* collaps argc/argv by removing the arguments detected
+			 * by g_test_init(). */
+			for (i = 1, j = 1; i < *argc; i++) {
+				if ((*argv)[i] == arg_array_c[j])
+					j++;
+				else
+					(*argv)[i] = NULL;
+			}
+			for (i = 1, j = 1; i < *argc; i++) {
+				if ((*argv)[i]) {
+					(*argv)[j++] = (*argv)[i];
+					if (i >= j)
+						(*argv)[i] = NULL;
+				}
+			}
+			*argc = j;
+		}
+
+		/* we must "leak" the test paths because they are not cloned by g_test_init(). */
+		if (!__nmtst_internal.test_tap_log) {
+			if (p_tests) {
+				p_tests_x = (char **) g_ptr_array_free (p_tests, FALSE);
+				p_tests = NULL;
+			}
+			if (s_tests) {
+				s_tests_x = (char **) g_ptr_array_free (s_tests, FALSE);
+				s_tests = NULL;
+			}
+		}
+	}
+
+	if (test_quick_set)
+		__nmtst_internal.test_quick = test_quick;
+	else if (test_quick_argv)
+		__nmtst_internal.test_quick = g_test_quick ();
+	else {
+#ifdef NMTST_TEST_QUICK
+		__nmtst_internal.test_quick = NMTST_TEST_QUICK;
+#else
+		__nmtst_internal.test_quick = FALSE;
+#endif
+	}
+
+	__nmtst_internal.is_debug = is_debug;
+	__nmtst_internal.rand0 = g_rand_new_with_seed (0);
+	__nmtst_internal.sudo_cmd = sudo_cmd;
+	__nmtst_internal.no_expect_message = no_expect_message;
+
+	if (!log_level && log_domains) {
+		/* if the log level is not specified (but the domain is), we assume
+		 * the caller wants to set it depending on is_debug */
+		log_level = is_debug ? "DEBUG" : "WARN";
+	}
+
+	if (!__nmtst_internal.assert_logging) {
+		gboolean success = TRUE;
+#ifdef __NETWORKMANAGER_LOGGING_H__
+		success = nm_logging_setup (log_level, log_domains, NULL, NULL);
+		*out_set_logging = TRUE;
+#endif
+		g_assert (success);
+#if GLIB_CHECK_VERSION(2,34,0)
+		if (__nmtst_internal.no_expect_message)
+			g_log_set_always_fatal (G_LOG_FATAL_MASK);
+#else
+		/* g_test_expect_message() is a NOP, so allow any messages */
+		g_log_set_always_fatal (G_LOG_FATAL_MASK);
+#endif
+	} else if (__nmtst_internal.no_expect_message) {
+		/* We have a test that would be assert_logging, but the user specified no_expect_message.
+		 * This transforms g_test_expect_message() into a NOP, but we also have to relax
+		 * g_log_set_always_fatal(), which was set by g_test_init(). */
+		g_log_set_always_fatal (G_LOG_FATAL_MASK);
+#ifdef __NETWORKMANAGER_LOGGING_H__
+		if (c_log_domains || c_log_level) {
+			/* Normally, tests with assert_logging do not overwrite the logging level/domains because
+			 * the logging statements are part of the assertions. But if the test is run with
+			 * no-expect-message *and* the logging is set explicitly via environment variables,
+			 * we still reset the logging. */
+			gboolean success;
+
+			success = nm_logging_setup (log_level, log_domains, NULL, NULL);
+			*out_set_logging = TRUE;
+			g_assert (success);
+		}
+#endif
+	} else {
+#if GLIB_CHECK_VERSION(2,34,0)
+		/* We were called not to set logging levels. This means, that the user
+		 * expects to assert against (all) messages. Any uncought message is fatal. */
+		g_log_set_always_fatal (G_LOG_LEVEL_MASK);
+#else
+		/* g_test_expect_message() is a NOP, so allow any messages */
+		g_log_set_always_fatal (G_LOG_FATAL_MASK);
+#endif
+	}
+
+	if ((!__nmtst_internal.assert_logging || (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message)) &&
+	    (is_debug || (c_log_level && (!g_ascii_strcasecmp (c_log_level, "DEBUG") || !g_ascii_strcasecmp (c_log_level, "TRACE")))) &&
+	    !g_getenv ("G_MESSAGES_DEBUG"))
+	{
+		/* if we are @is_debug or @log_level=="DEBUG" and
+		 * G_MESSAGES_DEBUG is unset, we set G_MESSAGES_DEBUG=all.
+		 * To disable this default behaviour, set G_MESSAGES_DEBUG='' */
+
+		/* Note that g_setenv is not thread safe, but you should anyway call
+		 * nmtst_init() at the very start. */
+		g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+	}
+
+	/* Delay messages until we setup logging. */
+	for (i = 0; i < debug_messages->len; i++)
+		__NMTST_LOG (g_message, "%s", g_array_index (debug_messages, const char *, i));
+
+	g_strfreev ((char **) g_array_free (debug_messages, FALSE));
+	g_free (c_log_level);
+	g_free (c_log_domains);
+
+#ifdef __NETWORKMANAGER_UTILS_H__
+	/* ensure that monotonic timestamp is called (because it initially logs a line) */
+	nm_utils_get_monotonic_timestamp_s ();
+#endif
+
+#ifdef NM_UTILS_H
+	{
+		gs_free_error GError *error = NULL;
+
+		if (!nm_utils_init (&error))
+			g_assert_not_reached ();
+		g_assert_no_error (error);
+	}
+#endif
+}
+
+#ifdef __NETWORKMANAGER_LOGGING_H__
+inline static void
+nmtst_init_with_logging (int *argc, char ***argv, const char *log_level, const char *log_domains)
+{
+	__nmtst_init (argc, argv, FALSE, log_level, log_domains, NULL);
+}
+inline static void
+nmtst_init_assert_logging (int *argc, char ***argv, const char *log_level, const char *log_domains)
+{
+	gboolean set_logging;
+
+	__nmtst_init (argc, argv, TRUE, NULL, NULL, &set_logging);
+
+	if (!set_logging) {
+		gboolean success;
+
+		success = nm_logging_setup (log_level, log_domains, NULL, NULL);
+		g_assert (success);
+	}
+}
+#else
+inline static void
+nmtst_init (int *argc, char ***argv, gboolean assert_logging)
+{
+	__nmtst_init (argc, argv, assert_logging, NULL, NULL, NULL);
+}
+#endif
+
+inline static gboolean
+nmtst_is_debug (void)
+{
+	g_assert (nmtst_initialized ());
+	return __nmtst_internal.is_debug;
+}
+
+inline static gboolean
+nmtst_test_quick (void)
+{
+	g_assert (nmtst_initialized ());
+	return __nmtst_internal.test_quick;
+}
+
+#if GLIB_CHECK_VERSION(2,34,0)
+#undef g_test_expect_message
+#define g_test_expect_message(...) \
+	G_STMT_START { \
+		g_assert (nmtst_initialized ()); \
+		if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) { \
+			g_debug ("nmtst: assert-logging: g_test_expect_message %s", G_STRINGIFY ((__VA_ARGS__))); \
+		} else { \
+			G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+			g_test_expect_message (__VA_ARGS__); \
+			G_GNUC_END_IGNORE_DEPRECATIONS \
+		} \
+	} G_STMT_END
+#undef g_test_assert_expected_messages_internal
+#define g_test_assert_expected_messages_internal(domain, file, line, func) \
+	G_STMT_START { \
+		const char *_domain = (domain); \
+		const char *_file = (file); \
+		const char *_func = (func); \
+		int _line = (line); \
+		\
+		if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) \
+			g_debug ("nmtst: assert-logging: g_test_assert_expected_messages(%s, %s:%d, %s)", _domain?:"", _file?:"", _line, _func?:""); \
+		\
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+		g_test_assert_expected_messages_internal (_domain, _file, _line, _func); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+	} G_STMT_END
+#endif
+
+inline static GRand *
+nmtst_get_rand0 (void)
+{
+	g_assert (nmtst_initialized ());
+	return __nmtst_internal.rand0;
+}
+
+inline static GRand *
+nmtst_get_rand (void)
+{
+	g_assert (nmtst_initialized ());
+
+	if (G_UNLIKELY (!__nmtst_internal.rand)) {
+		guint32 seed;
+		const char *str;
+
+		if ((str = g_getenv ("NMTST_SEED_RAND"))) {
+			gchar *s;
+			gint64 i;
+
+			i = g_ascii_strtoll (str, &s, 0);
+			g_assert (s[0] == '\0' && i >= 0 && i < G_MAXUINT32);
+
+			seed = i;
+			__nmtst_internal.rand = g_rand_new_with_seed (seed);
+		} else {
+			__nmtst_internal.rand = g_rand_new ();
+
+			seed = g_rand_int (__nmtst_internal.rand);
+			g_rand_set_seed (__nmtst_internal.rand, seed);
+		}
+		__nmtst_internal.rand_seed = seed;
+
+		g_print ("\nnmtst: initialize nmtst_get_rand() with NMTST_SEED_RAND=%u\n", seed);
+	}
+	return __nmtst_internal.rand;
+}
+
+inline static guint32
+nmtst_get_rand_int (void)
+{
+	return g_rand_int (nmtst_get_rand ());
+}
+
+inline static void *
+nmtst_rand_perm (GRand *rand, void *dst, const void *src, gsize elmt_size, gsize n_elmt)
+{
+	gsize i, j;
+	char *p_, *pj;
+	char *bu;
+
+	g_assert (dst);
+	g_assert (elmt_size > 0);
+	g_assert (n_elmt < G_MAXINT32);
+
+	if (n_elmt == 0)
+		return dst;
+
+	if (src && dst != src)
+		memcpy (dst, src, elmt_size * n_elmt);
+
+	if (!rand)
+		rand = nmtst_get_rand ();
+
+	bu = g_slice_alloc (elmt_size);
+
+	p_ = dst;
+	for (i = n_elmt; i > 1; i--) {
+		j = g_rand_int_range (rand, 0, i);
+
+		if (j != 0) {
+			pj = &p_[j * elmt_size];
+
+			/* swap */
+			memcpy (bu, p_, elmt_size);
+			memcpy (p_, pj, elmt_size);
+			memcpy (pj, bu, elmt_size);
+		}
+		p_ += elmt_size;
+	}
+
+	g_slice_free1 (elmt_size, bu);
+	return dst;
+}
+
+/*****************************************************************************/
+
+inline static gboolean
+_nmtst_main_loop_run_timeout (gpointer user_data)
+{
+	GMainLoop **p_loop = user_data;
+
+	g_assert (p_loop);
+	g_assert (*p_loop);
+
+	g_main_loop_quit (*p_loop);
+	*p_loop = NULL;
+
+	return G_SOURCE_REMOVE;
+}
+
+inline static gboolean
+nmtst_main_loop_run (GMainLoop *loop, int timeout_ms)
+{
+	GSource *source = NULL;
+	guint id = 0;
+	GMainLoop *loopx = loop;
+
+	if (timeout_ms > 0) {
+		source = g_timeout_source_new (timeout_ms);
+		g_source_set_callback (source, _nmtst_main_loop_run_timeout, &loopx, NULL);
+		id = g_source_attach (source, g_main_loop_get_context (loop));
+		g_assert (id);
+		g_source_unref (source);
+	}
+
+	g_main_loop_run (loop);
+
+	/* if the timeout was reached, return FALSE. */
+	return loopx != NULL;
+}
+
+/*****************************************************************************/
+
+inline static const char *
+nmtst_get_sudo_cmd (void)
+{
+	g_assert (nmtst_initialized ());
+	return __nmtst_internal.sudo_cmd;
+}
+
+inline static void
+nmtst_reexec_sudo (void)
+{
+	char *str;
+	char **argv;
+	int i;
+	int errsv;
+
+	g_assert (nmtst_initialized ());
+	g_assert (__nmtst_internal.orig_argv);
+
+	if (!__nmtst_internal.sudo_cmd)
+		return;
+
+	str = g_strjoinv (" ", __nmtst_internal.orig_argv);
+	__NMTST_LOG (g_message, ">> exec %s %s", __nmtst_internal.sudo_cmd, str);
+
+	argv = g_new0 (char *, 1 + g_strv_length (__nmtst_internal.orig_argv) + 1);
+	argv[0] = __nmtst_internal.sudo_cmd;
+	for (i = 0; __nmtst_internal.orig_argv[i]; i++)
+		argv[i+1] = __nmtst_internal.orig_argv[i];
+
+	execvp (__nmtst_internal.sudo_cmd, argv);
+
+	errsv = errno;
+	g_error (">> exec %s failed: %d - %s", __nmtst_internal.sudo_cmd, errsv, strerror (errsv));
+}
+
+/*****************************************************************************/
+
+inline static gsize
+nmtst_find_all_indexes (gpointer *elements,
+                        gsize n_elements,
+                        gpointer *needles,
+                        gsize n_needles,
+                        gboolean (*equal_fcn) (gpointer element, gpointer needle, gpointer user_data),
+                        gpointer user_data,
+                        gssize *out_idx)
+{
+	gsize i, j, k;
+	gsize found = 0;
+
+	for (i = 0; i < n_needles; i++) {
+		gssize idx = -1;
+
+		for (j = 0; j < n_elements; j++) {
+
+			/* no duplicates */
+			for (k = 0; k < i; k++) {
+				if (out_idx[k] == j)
+					goto next;
+			}
+
+			if (equal_fcn (elements[j], needles[i], user_data)) {
+				idx = j;
+				break;
+			}
+next:
+			;
+		}
+
+		out_idx[i] = idx;
+		if (idx >= 0)
+			found++;
+	}
+
+	return found;
+}
+
+/*****************************************************************************/
+
+#define __define_nmtst_static(NUM,SIZE) \
+inline static const char * \
+nmtst_static_##SIZE##_##NUM (const char *str) \
+{ \
+	gsize l; \
+	static char buf[SIZE]; \
+\
+	if (!str) \
+		return NULL; \
+	l = g_strlcpy (buf, str, sizeof (buf)); \
+	g_assert (l < sizeof (buf)); \
+	return buf; \
+}
+__define_nmtst_static(01, 1024)
+__define_nmtst_static(02, 1024)
+__define_nmtst_static(03, 1024)
+#undef __define_nmtst_static
+
+inline static const char *
+nmtst_uuid_generate (void)
+{
+	static char u[37];
+	gs_free char *m = NULL;
+
+	m = nm_utils_uuid_generate ();
+	g_assert (m && strlen (m) == sizeof (u) - 1);
+	memcpy (u, m, sizeof (u));
+	return u;
+}
+
+#define NMTST_SWAP(x,y) \
+	G_STMT_START { \
+		char __nmtst_swap_temp[sizeof(x) == sizeof(y) ? (signed) sizeof(x) : -1]; \
+		memcpy(__nmtst_swap_temp, &y, sizeof(x)); \
+		memcpy(&y,                &x, sizeof(x)); \
+		memcpy(&x, __nmtst_swap_temp, sizeof(x)); \
+	} G_STMT_END
+
+#define nmtst_assert_str_has_substr(str, substr) \
+	G_STMT_START { \
+		const char *__str = (str); \
+		const char *__substr = (substr); \
+		\
+		g_assert (__str); \
+		g_assert (__substr); \
+		if (strstr (__str, __substr) == NULL) \
+			g_error ("%s:%d: Expects \"%s\" but got \"%s\"", __FILE__, __LINE__, __substr, __str); \
+	} G_STMT_END
+
+inline static guint32
+nmtst_inet4_from_string (const char *str)
+{
+	guint32 addr;
+	int success;
+
+	if (!str)
+		return 0;
+
+	success = inet_pton (AF_INET, str, &addr);
+
+	g_assert (success == 1);
+
+	return addr;
+}
+
+inline static const struct in6_addr *
+nmtst_inet6_from_string (const char *str)
+{
+	static struct in6_addr addr;
+	int success;
+
+	if (!str)
+		addr = in6addr_any;
+	else {
+		success = inet_pton (AF_INET6, str, &addr);
+		g_assert (success == 1);
+	}
+
+	return &addr;
+}
+
+inline static void
+_nmtst_assert_ip4_address (const char *file, int line, in_addr_t addr, const char *str_expected)
+{
+	if (nmtst_inet4_from_string (str_expected) != addr) {
+		char buf[100];
+
+		g_error ("%s:%d: Unexpected IPv4 address: expected %s, got %s",
+		         file, line, str_expected ? str_expected : "0.0.0.0",
+		         inet_ntop (AF_INET, &addr, buf, sizeof (buf)));
+	}
+}
+#define nmtst_assert_ip4_address(addr, str_expected) _nmtst_assert_ip4_address (__FILE__, __LINE__, addr, str_expected)
+
+inline static void
+_nmtst_assert_ip6_address (const char *file, int line, const struct in6_addr *addr, const char *str_expected)
+{
+	struct in6_addr any = in6addr_any;
+
+	if (!addr)
+		addr = &any;
+
+	if (memcmp (nmtst_inet6_from_string (str_expected), addr, sizeof (*addr)) != 0) {
+		char buf[100];
+
+		g_error ("%s:%d: Unexpected IPv6 address: expected %s, got %s",
+		         file, line, str_expected ? str_expected : "::",
+		         inet_ntop (AF_INET6, addr, buf, sizeof (buf)));
+	}
+}
+#define nmtst_assert_ip6_address(addr, str_expected) _nmtst_assert_ip6_address (__FILE__, __LINE__, addr, str_expected)
+
+inline static void
+FAIL(const char *test_name, const char *fmt, ...)
+{
+	va_list args;
+	char buf[500];
+
+	g_snprintf (buf, 500, "FAIL: (%s) %s\n", test_name, fmt);
+
+	va_start (args, fmt);
+	vfprintf (stderr, buf, args);
+	va_end (args);
+	_exit (1);
+}
+
+#define ASSERT(x, test_name, fmt, ...) \
+	if (!(x)) { \
+		FAIL (test_name, fmt, ## __VA_ARGS__); \
+	}
+
+
+#define nmtst_spawn_sync(working_directory, standard_out, standard_err, assert_exit_status, ...) \
+	__nmtst_spawn_sync (working_directory, standard_out, standard_err, assert_exit_status, ##__VA_ARGS__, NULL)
+inline static gint
+__nmtst_spawn_sync (const char *working_directory, char **standard_out, char **standard_err, int assert_exit_status, ...) G_GNUC_NULL_TERMINATED;
+inline static gint
+__nmtst_spawn_sync (const char *working_directory, char **standard_out, char **standard_err, int assert_exit_status, ...)
+{
+	gint exit_status = 0;
+	GError *error = NULL;
+	char *arg;
+	va_list va_args;
+	GPtrArray *argv = g_ptr_array_new ();
+	gboolean success;
+
+	va_start (va_args, assert_exit_status);
+	while ((arg = va_arg (va_args, char *)))
+		g_ptr_array_add (argv, arg);
+	va_end (va_args);
+
+	g_assert (argv->len >= 1);
+	g_ptr_array_add (argv, NULL);
+
+	success = g_spawn_sync (working_directory,
+	                        (char**) argv->pdata,
+	                        NULL,
+	                        0 /*G_SPAWN_DEFAULT*/,
+	                        NULL,
+	                        NULL,
+	                        standard_out,
+	                        standard_err,
+	                        &exit_status,
+	                        &error);
+	if (!success)
+		g_error ("nmtst_spawn_sync(%s): %s", ((char **) argv->pdata)[0], error->message);
+	g_assert (!error);
+
+	g_assert (!standard_out || *standard_out);
+	g_assert (!standard_err || *standard_err);
+
+	if (assert_exit_status != -1) {
+		/* exit status is a guint8 on success. Set @assert_exit_status to -1
+		 * not to check for the exit status. */
+		g_assert (WIFEXITED (exit_status));
+		g_assert_cmpint (WEXITSTATUS (exit_status), ==, assert_exit_status);
+	}
+
+	g_ptr_array_free (argv, TRUE);
+	return exit_status;
+}
+
+/*******************************************************************************/
+
+inline static char *
+nmtst_file_resolve_relative_path (const char *rel, const char *cwd)
+{
+	gs_free char *cwd_free = NULL;
+
+	g_assert (rel && *rel);
+
+	if (g_path_is_absolute (rel))
+		return g_strdup (rel);
+
+	if (!cwd)
+		cwd = cwd_free = g_get_current_dir ();
+	return g_build_filename (cwd, rel, NULL);
+}
+
+inline static void
+_nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, const char *file, int line)
+{
+	gs_free char *p1 = NULL, *p2 = NULL;
+
+	p1 = nmtst_file_resolve_relative_path (f1, NULL);
+	p2 = nmtst_file_resolve_relative_path (f2, NULL);
+	g_assert (p1 && *p1);
+
+	/* Fixme: later we might need to coalesce repeated '/', "./", and "../".
+	 * For now, it's good enough. */
+	if (g_strcmp0 (p1, p2) != 0)
+		g_error ("%s:%d : filenames don't match \"%s\" vs. \"%s\" // \"%s\" - \"%s\"", file, line, f1, f2, p1, p2);
+}
+#define nmtst_assert_resolve_relative_path_equals(f1, f2) _nmtst_assert_resolve_relative_path_equals (f1, f2, __FILE__, __LINE__);
+
+/*******************************************************************************/
+
+#ifdef __NETWORKMANAGER_PLATFORM_H__
+
+inline static NMPlatformIP6Address *
+nmtst_platform_ip6_address (const char *address, const char *peer_address, guint plen)
+{
+	static NMPlatformIP6Address addr;
+
+	memset (&addr, 0, sizeof (addr));
+	addr.address = *nmtst_inet6_from_string (address);
+	addr.peer_address = *nmtst_inet6_from_string (peer_address);
+	addr.plen = plen;
+
+	return &addr;
+}
+
+inline static NMPlatformIP6Address *
+nmtst_platform_ip6_address_full (const char *address, const char *peer_address, guint plen,
+                                 int ifindex, NMIPConfigSource source, guint32 timestamp,
+                                 guint32 lifetime, guint32 preferred, guint flags)
+{
+	NMPlatformIP6Address *addr = nmtst_platform_ip6_address (address, peer_address, plen);
+
+	addr->ifindex = ifindex;
+	addr->source = source;
+	addr->timestamp = timestamp;
+	addr->lifetime = lifetime;
+	addr->preferred = preferred;
+	addr->flags = flags;
+
+	return addr;
+}
+
+inline static NMPlatformIP4Route *
+nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway)
+{
+	static NMPlatformIP4Route route;
+
+	memset (&route, 0, sizeof (route));
+	route.network = nmtst_inet4_from_string (network);
+	route.plen = plen;
+	route.gateway = nmtst_inet4_from_string (gateway);
+
+	return &route;
+}
+
+inline static NMPlatformIP4Route *
+nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gateway,
+                               int ifindex, NMIPConfigSource source,
+                               guint metric, guint mss,
+                               guint8 scope,
+                               const char *pref_src)
+{
+	NMPlatformIP4Route *route = nmtst_platform_ip4_route (network, plen, gateway);
+
+	route->ifindex = ifindex;
+	route->source = source;
+	route->metric = metric;
+	route->mss = mss;
+	route->scope_inv = nm_platform_route_scope_inv (scope);
+	route->pref_src = nmtst_inet4_from_string (pref_src);
+
+	return route;
+}
+
+inline static NMPlatformIP6Route *
+nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
+{
+	static NMPlatformIP6Route route;
+
+	memset (&route, 0, sizeof (route));
+	route.network = *nmtst_inet6_from_string (network);
+	route.plen = plen;
+	route.gateway = *nmtst_inet6_from_string (gateway);
+
+	return &route;
+}
+
+inline static NMPlatformIP6Route *
+nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gateway,
+                               int ifindex, NMIPConfigSource source,
+                               guint metric, guint mss)
+{
+	NMPlatformIP6Route *route = nmtst_platform_ip6_route (network, plen, gateway);
+
+	route->ifindex = ifindex;
+	route->source = source;
+	route->metric = metric;
+	route->mss = mss;
+
+	return route;
+}
+
+inline static int
+_nmtst_platform_ip4_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+	return nm_platform_ip4_route_cmp ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b);
+}
+
+inline static void
+nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gsize len, gboolean ignore_order)
+{
+	gsize i;
+	gs_free const NMPlatformIP4Route *c_a = NULL, *c_b = NULL;
+
+	g_assert (a);
+	g_assert (b);
+
+	if (ignore_order) {
+		a = c_a = g_memdup (a, sizeof (NMPlatformIP4Route) * len);
+		b = c_b = g_memdup (b, sizeof (NMPlatformIP4Route) * len);
+		g_qsort_with_data (c_a, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL);
+		g_qsort_with_data (c_b, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL);
+	}
+
+	for (i = 0; i < len; i++) {
+		if (nm_platform_ip4_route_cmp (&a[i], &b[i]) != 0) {
+			char buf[sizeof (_nm_utils_to_string_buffer)];
+
+			g_error ("Error comparing IPv4 route[%lu]: %s vs %s", (long unsigned) i,
+			         nm_platform_ip4_route_to_string (&a[i], NULL, 0),
+			         nm_platform_ip4_route_to_string (&b[i], buf, sizeof (buf)));
+			g_assert_not_reached ();
+		}
+	}
+}
+
+inline static int
+_nmtst_platform_ip6_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+	return nm_platform_ip6_route_cmp ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b);
+}
+
+inline static void
+nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gsize len, gboolean ignore_order)
+{
+	gsize i;
+	gs_free const NMPlatformIP6Route *c_a = NULL, *c_b = NULL;
+
+	g_assert (a);
+	g_assert (b);
+
+	if (ignore_order) {
+		a = c_a = g_memdup (a, sizeof (NMPlatformIP6Route) * len);
+		b = c_b = g_memdup (b, sizeof (NMPlatformIP6Route) * len);
+		g_qsort_with_data (c_a, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL);
+		g_qsort_with_data (c_b, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL);
+	}
+
+	for (i = 0; i < len; i++) {
+		if (nm_platform_ip6_route_cmp (&a[i], &b[i]) != 0) {
+			char buf[sizeof (_nm_utils_to_string_buffer)];
+
+			g_error ("Error comparing IPv6 route[%lu]: %s vs %s", (long unsigned) i,
+			         nm_platform_ip6_route_to_string (&a[i], NULL, 0),
+			         nm_platform_ip6_route_to_string (&b[i], buf, sizeof (buf)));
+			g_assert_not_reached ();
+		}
+	}
+}
+
+#endif
+
+
+#ifdef __NETWORKMANAGER_IP4_CONFIG_H__
+
+inline static NMIP4Config *
+nmtst_ip4_config_clone (NMIP4Config *config)
+{
+	NMIP4Config *copy = nm_ip4_config_new (-1);
+
+	g_assert (copy);
+	g_assert (config);
+	nm_ip4_config_replace (copy, config, NULL);
+	return copy;
+}
+
+#endif
+
+
+#ifdef __NETWORKMANAGER_IP6_CONFIG_H__
+
+inline static NMIP6Config *
+nmtst_ip6_config_clone (NMIP6Config *config)
+{
+	NMIP6Config *copy = nm_ip6_config_new (-1);
+
+	g_assert (copy);
+	g_assert (config);
+	nm_ip6_config_replace (copy, config, NULL);
+	return copy;
+}
+
+#endif
+
+#if (defined(__NM_SIMPLE_CONNECTION_H__) && defined(__NM_SETTING_CONNECTION_H__)) || (defined(NM_CONNECTION_H))
+
+inline static NMConnection *
+nmtst_create_minimal_connection (const char *id, const char *uuid, const char *type, NMSettingConnection **out_s_con)
+{
+	NMConnection *con;
+	NMSetting *s_base = NULL;
+	NMSettingConnection *s_con;
+	gs_free char *uuid_free = NULL;
+
+	g_assert (id);
+
+	if (uuid)
+		g_assert (nm_utils_is_uuid (uuid));
+	else
+		uuid = uuid_free = nm_utils_uuid_generate ();
+
+	if (type) {
+		GType type_g;
+
+#if defined(__NM_SIMPLE_CONNECTION_H__)
+		type_g = nm_setting_lookup_type (type);
+#else
+		type_g = nm_connection_lookup_setting_type (type);
+#endif
+
+		g_assert (type_g != G_TYPE_INVALID);
+
+		s_base = g_object_new (type_g, NULL);
+		g_assert (NM_IS_SETTING (s_base));
+	}
+
+#if defined(__NM_SIMPLE_CONNECTION_H__)
+	con = nm_simple_connection_new ();
+#else
+	con = nm_connection_new ();
+#endif
+
+	s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, id,
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_TYPE, type,
+	              NULL);
+	nm_connection_add_setting (con, NM_SETTING (s_con));
+
+	if (s_base)
+		nm_connection_add_setting (con, s_base);
+
+	if (out_s_con)
+		*out_s_con = s_con;
+	return con;
+}
+
+inline static gboolean
+_nmtst_connection_normalize_v (NMConnection *connection, va_list args)
+{
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+	GHashTable *parameters = NULL;
+	const char *p_name;
+
+	g_assert (NM_IS_CONNECTION (connection));
+
+	while ((p_name = va_arg (args, const char *))) {
+		if (!parameters)
+			parameters =  g_hash_table_new (g_str_hash, g_str_equal);
+		g_hash_table_insert (parameters, (gpointer *) p_name, va_arg (args, gpointer));
+	}
+
+	success = nm_connection_normalize (connection,
+	                                   parameters,
+	                                   &was_modified,
+	                                   &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	if (parameters)
+		g_hash_table_destroy (parameters);
+
+	return was_modified;
+}
+
+inline static gboolean
+_nmtst_connection_normalize (NMConnection *connection, ...)
+{
+	gboolean was_modified;
+	va_list args;
+
+	va_start (args, connection);
+	was_modified = _nmtst_connection_normalize_v (connection, args);
+	va_end (args);
+
+	return was_modified;
+}
+#define nmtst_connection_normalize(connection, ...) \
+    _nmtst_connection_normalize(connection, ##__VA_ARGS__, NULL)
+
+inline static NMConnection *
+_nmtst_connection_duplicate_and_normalize (NMConnection *connection, ...)
+{
+	gboolean was_modified;
+	va_list args;
+
+	g_assert (NM_IS_CONNECTION (connection));
+
+#if defined(__NM_SIMPLE_CONNECTION_H__)
+	connection = nm_simple_connection_new_clone (connection);
+#else
+	connection = nm_connection_duplicate (connection);
+#endif
+
+	va_start (args, connection);
+	was_modified = _nmtst_connection_normalize_v (connection, args);
+	va_end (args);
+
+	return connection;
+}
+#define nmtst_connection_duplicate_and_normalize(connection, ...) \
+    _nmtst_connection_duplicate_and_normalize(connection, ##__VA_ARGS__, NULL)
+
+inline static void
+nmtst_assert_connection_equals (NMConnection *a, gboolean normalize_a, NMConnection *b, gboolean normalize_b)
+{
+	gboolean compare;
+	gs_unref_object NMConnection *a2 = NULL;
+	gs_unref_object NMConnection *b2 = NULL;
+	GHashTable *out_settings = NULL;
+
+	g_assert (NM_IS_CONNECTION (a));
+	g_assert (NM_IS_CONNECTION (b));
+
+	if (normalize_a)
+		a = a2 = nmtst_connection_duplicate_and_normalize (a);
+	if (normalize_b)
+		b = b2 = nmtst_connection_duplicate_and_normalize (b);
+
+	compare = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_settings);
+	if (!compare || out_settings) {
+		const char *name, *pname;
+		GHashTable *setting;
+		GHashTableIter iter, iter2;
+
+		__NMTST_LOG (g_message, ">>> ASSERTION nmtst_assert_connection_equals() fails");
+		if (out_settings) {
+			g_hash_table_iter_init (&iter, out_settings);
+			while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &setting)) {
+				__NMTST_LOG (g_message, ">>> differences in setting '%s':", name);
+
+				g_hash_table_iter_init (&iter2, setting);
+				while (g_hash_table_iter_next (&iter2, (gpointer *) &pname, NULL))
+					__NMTST_LOG (g_message, ">>> differences in setting '%s.%s'", name, pname);
+			}
+		}
+
+#ifdef __NM_KEYFILE_INTERNAL_H__
+		{
+			gs_unref_keyfile GKeyFile *kf_a = NULL, *kf_b = NULL;
+			gs_free char *str_a = NULL, *str_b = NULL;
+
+			kf_a = nm_keyfile_write (a, NULL, NULL, NULL);
+			kf_b = nm_keyfile_write (b, NULL, NULL, NULL);
+
+			if (kf_a)
+				str_a = g_key_file_to_data (kf_a, NULL, NULL);
+			if (kf_b)
+				str_b = g_key_file_to_data (kf_b, NULL, NULL);
+
+			__NMTST_LOG (g_message, ">>> Connection A as kf (*WARNING: keyfile representation might not show the difference*):\n%s", str_a);
+			__NMTST_LOG (g_message, ">>> Connection B as kf (*WARNING: keyfile representation might not show the difference*):\n%s", str_b);
+		}
+#endif
+	}
+	g_assert (compare);
+	g_assert (!out_settings);
+
+	compare = nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT);
+	g_assert (compare);
+}
+
+inline static void
+nmtst_assert_connection_verifies_without_normalization (NMConnection *con)
+{
+	/* assert that the connection verifies and does not need any normalization */
+
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+	gs_unref_object NMConnection *clone = NULL;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+#if defined(__NM_SIMPLE_CONNECTION_H__)
+	clone = nm_simple_connection_new_clone (con);
+#else
+	clone = nm_connection_duplicate (con);
+#endif
+
+	success = nm_connection_verify (con, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	nmtst_assert_connection_equals (con, FALSE, clone, FALSE);
+	g_assert (!was_modified);
+}
+
+inline static void
+nmtst_assert_connection_verifies_and_normalizable (NMConnection *con)
+{
+	/* assert that the connection does verify, but normalization still modifies it */
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+	success = nm_connection_verify (con, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_clear_error (&error);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (was_modified);
+
+	/* again! */
+	nmtst_assert_connection_verifies_without_normalization (con);
+}
+
+inline static void
+nmtst_assert_connection_verifies_after_normalization (NMConnection *con,
+                                                      GQuark expect_error_domain,
+                                                      gint expect_error_code)
+{
+	/* assert that the connection does not verify, but normalization does fix it */
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+	success = nm_connection_verify (con, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_clear_error (&error);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (was_modified);
+
+	/* again! */
+	nmtst_assert_connection_verifies_without_normalization (con);
+}
+
+inline static void
+nmtst_assert_connection_unnormalizable (NMConnection *con,
+                                        GQuark expect_error_domain,
+                                        gint expect_error_code)
+{
+	/* assert that the connection does not verify, and it cannot be fixed by normalization */
+
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+	success = nm_connection_verify (con, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_clear_error (&error);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_assert (!was_modified);
+	g_clear_error (&error);
+}
+
+inline static void
+nmtst_assert_setting_verifies (NMSetting *setting)
+{
+	/* assert that the setting verifies without an error */
+
+	GError *error = NULL;
+	gboolean success;
+
+	g_assert (NM_IS_SETTING (setting));
+
+	success = nm_setting_verify (setting, NULL, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+}
+
+inline static void
+nmtst_assert_setting_verify_fails (NMSetting *setting,
+                                   GQuark expect_error_domain,
+                                   gint expect_error_code)
+{
+	/* assert that the setting verification fails */
+
+	GError *error = NULL;
+	gboolean success;
+
+	g_assert (NM_IS_SETTING (setting));
+
+	success = nm_setting_verify (setting, NULL, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_clear_error (&error);
+}
+
+#endif
+
+#ifdef __NM_UTILS_H__
+static inline void
+nmtst_assert_hwaddr_equals (gconstpointer hwaddr1, gssize hwaddr1_len, const char *expected, const char *loc)
+{
+	guint8 buf2[NM_UTILS_HWADDR_LEN_MAX];
+	gsize hwaddr2_len = 1;
+	const char *p;
+	gboolean success;
+
+	g_assert (hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX);
+
+	g_assert (expected);
+	for (p = expected; *p; p++) {
+		if (*p == ':' || *p == '-')
+			hwaddr2_len++;
+	}
+	g_assert (hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX);
+	g_assert (nm_utils_hwaddr_aton (expected, buf2, hwaddr2_len));
+
+	/* Manually check the entire hardware address instead of using
+	 * nm_utils_hwaddr_matches() because that function doesn't compare
+	 * entire InfiniBand addresses for various (legitimate) reasons.
+	 */
+	success = (hwaddr1_len == hwaddr2_len);
+	if (success)
+		success = !memcmp (hwaddr1, buf2, hwaddr1_len);
+	if (!success) {
+		g_error ("assert: %s: hwaddr '%s' (%zd) expected, but got %s (%zd)",
+		         loc, expected, hwaddr2_len, nm_utils_hwaddr_ntoa (hwaddr1, hwaddr1_len), hwaddr1_len);
+	}
+}
+#define nmtst_assert_hwaddr_equals(hwaddr1, hwaddr1_len, expected) \
+    nmtst_assert_hwaddr_equals (hwaddr1, hwaddr1_len, expected, G_STRLOC)
+#endif
+
+#if defined(__NM_SIMPLE_CONNECTION_H__) && defined(__NM_SETTING_CONNECTION_H__) && defined(__NM_KEYFILE_INTERNAL_H__)
+
+inline static NMConnection *
+nmtst_create_connection_from_keyfile (const char *keyfile_str, const char *keyfile_name, const char *base_dir)
+{
+	GKeyFile *keyfile;
+	GError *error = NULL;
+	gboolean success;
+	NMConnection *con;
+
+	g_assert (keyfile_str);
+
+	keyfile =  g_key_file_new ();
+	success = g_key_file_load_from_data (keyfile, keyfile_str, strlen (keyfile_str), G_KEY_FILE_NONE, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	con = nm_keyfile_read (keyfile, keyfile_name, base_dir, NULL, NULL, &error);
+	g_assert_no_error (error);
+	g_assert (NM_IS_CONNECTION (con));
+
+	g_key_file_unref (keyfile);
+
+	nmtst_connection_normalize (con);
+
+	return con;
+}
+
+#endif
+
+#ifdef __NM_CONNECTION_H__
+
+typedef enum {
+	NMTST_VARIANT_EDITOR_CONNECTION,
+	NMTST_VARIANT_EDITOR_SETTING,
+	NMTST_VARIANT_EDITOR_PROPERTY
+} NmtstVariantEditorPhase;
+
+#define NMTST_VARIANT_EDITOR(__connection_variant, __code) \
+	G_STMT_START { \
+		GVariantIter __connection_iter, *__setting_iter; \
+		GVariantBuilder __connection_builder, __setting_builder; \
+		const char *__cur_setting_name, *__cur_property_name; \
+		GVariant *__property_val; \
+		NmtstVariantEditorPhase __phase; \
+                                                                        \
+		g_variant_builder_init (&__connection_builder, NM_VARIANT_TYPE_CONNECTION); \
+		g_variant_iter_init (&__connection_iter, __connection_variant); \
+		 \
+		__phase = NMTST_VARIANT_EDITOR_CONNECTION; \
+		__cur_setting_name = NULL; \
+		__cur_property_name = NULL; \
+		__code; \
+		while (g_variant_iter_next (&__connection_iter, "{&sa{sv}}", &__cur_setting_name, &__setting_iter)) { \
+			g_variant_builder_init (&__setting_builder, NM_VARIANT_TYPE_SETTING); \
+			__phase = NMTST_VARIANT_EDITOR_SETTING; \
+			__cur_property_name = NULL; \
+			__code; \
+			 \
+			while (   __cur_setting_name \
+			       && g_variant_iter_next (__setting_iter, "{&sv}", &__cur_property_name, &__property_val)) { \
+				__phase = NMTST_VARIANT_EDITOR_PROPERTY; \
+				__code; \
+				 \
+				if (__cur_property_name) { \
+					g_variant_builder_add (&__setting_builder, "{sv}", \
+					                       __cur_property_name, \
+					                       __property_val); \
+				} \
+				g_variant_unref (__property_val); \
+			} \
+			 \
+			if (__cur_setting_name) \
+				g_variant_builder_add (&__connection_builder, "{sa{sv}}", __cur_setting_name, &__setting_builder); \
+			g_variant_iter_free (__setting_iter); \
+		} \
+		 \
+		g_variant_unref (__connection_variant); \
+		 \
+		__connection_variant = g_variant_builder_end (&__connection_builder); \
+	} G_STMT_END;
+
+#define NMTST_VARIANT_ADD_SETTING(__setting_name, __setting_variant) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_CONNECTION) \
+			g_variant_builder_add (&__connection_builder, "{s@a{sv}}", __setting_name, __setting_variant); \
+	} G_STMT_END
+
+#define NMTST_VARIANT_DROP_SETTING(__setting_name) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_SETTING && __cur_setting_name) { \
+			if (!strcmp (__cur_setting_name, __setting_name)) \
+				__cur_setting_name = NULL; \
+		} \
+	} G_STMT_END
+
+#define NMTST_VARIANT_ADD_PROPERTY(__setting_name, __property_name, __format_string, __value) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_SETTING) { \
+			if (!strcmp (__cur_setting_name, __setting_name)) { \
+				g_variant_builder_add (&__setting_builder, "{sv}", __property_name, \
+				                       g_variant_new (__format_string, __value)); \
+			} \
+		} \
+	} G_STMT_END
+
+#define NMTST_VARIANT_DROP_PROPERTY(__setting_name, __property_name) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_PROPERTY && __cur_property_name) { \
+			if (   !strcmp (__cur_setting_name, __setting_name) \
+			    && !strcmp (__cur_property_name, __property_name)) \
+				__cur_property_name = NULL; \
+		} \
+	} G_STMT_END
+
+#define NMTST_VARIANT_CHANGE_PROPERTY(__setting_name, __property_name, __format_string, __value) \
+	G_STMT_START { \
+		NMTST_VARIANT_DROP_PROPERTY (__setting_name, __property_name); \
+		NMTST_VARIANT_ADD_PROPERTY (__setting_name, __property_name, __format_string, __value); \
+	} G_STMT_END
+
+#endif /* __NM_CONNECTION_H__ */
+
+#endif /* __NM_TEST_UTILS_H__ */
diff --git a/shared/nm-version-macros.h b/shared/nm-version-macros.h
new file mode 100644
index 00000000..dff5a449
--- /dev/null
+++ b/shared/nm-version-macros.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2011, 2015 Red Hat, Inc.
+ */
+
+#ifndef __NM_VERSION_MACROS_H__
+#define __NM_VERSION_MACROS_H__
+
+/* This header must not include glib or libnm. */
+
+/**
+ * NM_MAJOR_VERSION:
+ *
+ * Evaluates to the major version number of NetworkManager which this source
+ * is compiled against.
+ */
+#define NM_MAJOR_VERSION (1)
+
+/**
+ * NM_MINOR_VERSION:
+ *
+ * Evaluates to the minor version number of NetworkManager which this source
+ * is compiled against.
+ */
+#define NM_MINOR_VERSION (1)
+
+/**
+ * NM_MICRO_VERSION:
+ *
+ * Evaluates to the micro version number of NetworkManager which this source
+ * compiled against.
+ */
+#define NM_MICRO_VERSION (90)
+
+/**
+ * NM_CHECK_VERSION:
+ * @major: major version (e.g. 1 for version 1.2.5)
+ * @minor: minor version (e.g. 2 for version 1.2.5)
+ * @micro: micro version (e.g. 5 for version 1.2.5)
+ *
+ * Returns: %TRUE if the version of the NetworkManager header files
+ * is the same as or newer than the passed-in version.
+ */
+#define NM_CHECK_VERSION(major,minor,micro)                         \
+    (NM_MAJOR_VERSION > (major) ||                                  \
+     (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION > (minor)) || \
+     (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION == (minor) && NM_MICRO_VERSION >= (micro)))
+
+
+#define NM_ENCODE_VERSION(major,minor,micro) ((major) << 16 | (minor) << 8 | (micro))
+
+#define NM_VERSION_0_9_8  (NM_ENCODE_VERSION (0, 9, 8))
+#define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10))
+#define NM_VERSION_1_0    (NM_ENCODE_VERSION (1, 0, 0))
+#define NM_VERSION_1_2    (NM_ENCODE_VERSION (1, 2, 0))
+
+#define NM_VERSION_CUR_STABLE  NM_VERSION_1_0
+#define NM_VERSION_NEXT_STABLE NM_VERSION_1_2
+
+#endif  /* __NM_VERSION_MACROS_H__ */
diff --git a/shared/nm-version-macros.h.in b/shared/nm-version-macros.h.in
new file mode 100644
index 00000000..a8ad5c8d
--- /dev/null
+++ b/shared/nm-version-macros.h.in
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2011, 2015 Red Hat, Inc.
+ */
+
+#ifndef __NM_VERSION_MACROS_H__
+#define __NM_VERSION_MACROS_H__
+
+/* This header must not include glib or libnm. */
+
+/**
+ * NM_MAJOR_VERSION:
+ *
+ * Evaluates to the major version number of NetworkManager which this source
+ * is compiled against.
+ */
+#define NM_MAJOR_VERSION (@NM_MAJOR_VERSION@)
+
+/**
+ * NM_MINOR_VERSION:
+ *
+ * Evaluates to the minor version number of NetworkManager which this source
+ * is compiled against.
+ */
+#define NM_MINOR_VERSION (@NM_MINOR_VERSION@)
+
+/**
+ * NM_MICRO_VERSION:
+ *
+ * Evaluates to the micro version number of NetworkManager which this source
+ * compiled against.
+ */
+#define NM_MICRO_VERSION (@NM_MICRO_VERSION@)
+
+/**
+ * NM_CHECK_VERSION:
+ * @major: major version (e.g. 1 for version 1.2.5)
+ * @minor: minor version (e.g. 2 for version 1.2.5)
+ * @micro: micro version (e.g. 5 for version 1.2.5)
+ *
+ * Returns: %TRUE if the version of the NetworkManager header files
+ * is the same as or newer than the passed-in version.
+ */
+#define NM_CHECK_VERSION(major,minor,micro)                         \
+    (NM_MAJOR_VERSION > (major) ||                                  \
+     (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION > (minor)) || \
+     (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION == (minor) && NM_MICRO_VERSION >= (micro)))
+
+
+#define NM_ENCODE_VERSION(major,minor,micro) ((major) << 16 | (minor) << 8 | (micro))
+
+#define NM_VERSION_0_9_8  (NM_ENCODE_VERSION (0, 9, 8))
+#define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10))
+#define NM_VERSION_1_0    (NM_ENCODE_VERSION (1, 0, 0))
+#define NM_VERSION_1_2    (NM_ENCODE_VERSION (1, 2, 0))
+
+#define NM_VERSION_CUR_STABLE  NM_VERSION_1_0
+#define NM_VERSION_NEXT_STABLE NM_VERSION_1_2
+
+#endif  /* __NM_VERSION_MACROS_H__ */