diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..011e9f8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/modulemd-2.0.0.tar.xz
diff --git a/.libmodulemd.metadata b/.libmodulemd.metadata
new file mode 100644
index 0000000..c29b91c
--- /dev/null
+++ b/.libmodulemd.metadata
@@ -0,0 +1 @@
+e242f10ac0185da47cc54d0253cb0f8a80633ff4 SOURCES/modulemd-2.0.0.tar.xz
diff --git a/SOURCES/0001-Don-t-fail-merges-when-default-streams-differ.patch b/SOURCES/0001-Don-t-fail-merges-when-default-streams-differ.patch
new file mode 100644
index 0000000..1daa97a
--- /dev/null
+++ b/SOURCES/0001-Don-t-fail-merges-when-default-streams-differ.patch
@@ -0,0 +1,543 @@
+From 774f36026f1d3a4215be67845c2873135ceab6e4 Mon Sep 17 00:00:00 2001
+From: Stephen Gallagher <sgallagh@redhat.com>
+Date: Wed, 16 Jan 2019 13:21:44 -0500
+Subject: [PATCH] Don't fail merges when default streams differ
+
+Instead of failing the merge on a default stream conflict, we will
+instead treat it as having no default set. This is safe because if
+the module is not yet installed, then this just means its packages
+aren't visible and it needs to be selected explicitly.
+
+If some packages from it are already installed, then the module
+stream is already set, and thus changing the default won't matter.
+
+Update documentation to reflect modified field in Defaults
+
+Resolves: rhbz#1666871
+
+Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
+---
+ .../modulemd-1.0/private/modulemd-private.h   |  2 +
+ modulemd/v1/modulemd-defaults.c               | 39 +++++++----
+ modulemd/v1/tests/test-modulemd-defaults.c    | 66 ++++++++++++++++++-
+ .../modulemd-module-index-merger.h            | 18 +++--
+ .../private/modulemd-defaults-v1-private.h    |  2 +
+ modulemd/v2/modulemd-defaults-v1.c            | 59 +++++++++++------
+ modulemd/v2/tests/ModulemdTests/merger.py     | 33 +++++++---
+ .../v2/tests/test_data/overriding-nodejs.yaml | 11 ++++
+ test_data/defaults/overriding-nodejs.yaml     | 10 +++
+ 9 files changed, 191 insertions(+), 49 deletions(-)
+ create mode 100644 modulemd/v2/tests/test_data/overriding-nodejs.yaml
+ create mode 100644 test_data/defaults/overriding-nodejs.yaml
+
+diff --git a/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h b/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h
+index 20604efab843de6ac64cd9e181ce93d7e3a798fe..e9a785aed0d38598ce08d58e7e507d01698788a0 100644
+--- a/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h
++++ b/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h
+@@ -24,10 +24,12 @@ enum
+   MD_VERSION_MAX = G_MAXUINT64
+ };
+ 
+ #define MD_VERSION_LATEST MD_VERSION_2
+ 
++#define DEFAULT_MERGE_CONFLICT "__merge_conflict__"
++
+ ModulemdModule *
+ modulemd_module_new_from_modulestream (ModulemdModuleStream *stream);
+ 
+ ModulemdModuleStream *
+ modulemd_module_peek_modulestream (ModulemdModule *self);
+diff --git a/modulemd/v1/modulemd-defaults.c b/modulemd/v1/modulemd-defaults.c
+index 77ce30733945e30ffb8368986fa8c54c45697b5a..d44076eef0ac3bffae05f74b852fb6b51c2aee64 100644
+--- a/modulemd/v1/modulemd-defaults.c
++++ b/modulemd/v1/modulemd-defaults.c
+@@ -12,10 +12,11 @@
+  */
+ 
+ #include "modulemd.h"
+ #include "modulemd-defaults.h"
+ #include "modulemd-simpleset.h"
++#include "private/modulemd-private.h"
+ #include "private/modulemd-yaml.h"
+ 
+ 
+ GQuark
+ modulemd_defaults_error_quark (void)
+@@ -146,19 +147,38 @@ modulemd_defaults_set_default_stream (ModulemdDefaults *self,
+ const gchar *
+ modulemd_defaults_peek_default_stream (ModulemdDefaults *self)
+ {
+   g_return_val_if_fail (self, NULL);
+ 
++  if (self->default_stream &&
++      g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT))
++    {
++      /* During an index merge, we determined that this was in conflict
++       * with another set of ModulemdDefaults for the same module. If we
++       * see this, treat it as no default stream when querying for it.
++       */
++      return NULL;
++    }
+   return self->default_stream;
+ }
+ 
+ 
+ gchar *
+ modulemd_defaults_dup_default_stream (ModulemdDefaults *self)
+ {
+   g_return_val_if_fail (self, NULL);
+ 
++  if (self->default_stream &&
++      g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT))
++    {
++      /* During an index merge, we determined that this was in conflict
++       * with another set of ModulemdDefaults for the same module. If we
++       * see this, treat it as no default stream when querying for it.
++       */
++      return NULL;
++    }
++
+   return g_strdup (self->default_stream);
+ }
+ 
+ 
+ void
+@@ -753,28 +773,25 @@ modulemd_defaults_merge (ModulemdDefaults *first,
+   /* They had the same 'modified' value (such as both zero, for
+    * backwards-compatibility with 1.7.x and older.
+    * Merge them as best we can.
+    */
+ 
++  defaults = modulemd_defaults_copy (first);
++
+   /* First check for incompatibilities with the streams */
+-  if (g_strcmp0 (modulemd_defaults_peek_default_stream (first),
+-                 modulemd_defaults_peek_default_stream (second)))
++  if (g_strcmp0 (first->default_stream, second->default_stream))
+     {
+       /* Default streams don't match and override is not set.
+        * Return an error
+        */
+-      g_set_error (
+-        error,
+-        MODULEMD_DEFAULTS_ERROR,
+-        MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS,
+-        "Conflicting default streams when merging defaults for module %s",
+-        modulemd_defaults_peek_module_name (first));
+-      return NULL;
++      /* They have conflicting default streams */
++      g_info ("Module stream mismatch in merge: %s != %s",
++              first->default_stream,
++              second->default_stream);
++      modulemd_defaults_set_default_stream (defaults, DEFAULT_MERGE_CONFLICT);
+     }
+ 
+-  defaults = modulemd_defaults_copy (first);
+-
+   /* Merge the profile defaults */
+   profile_defaults = modulemd_defaults_peek_profile_defaults (defaults);
+ 
+   g_hash_table_iter_init (&iter,
+                           modulemd_defaults_peek_profile_defaults (second));
+diff --git a/modulemd/v1/tests/test-modulemd-defaults.c b/modulemd/v1/tests/test-modulemd-defaults.c
+index 5d032d83cbca4046af13719f68bdbc6778d6879e..35142b885b3ec30f5109d53befe17be3e08d7b5a 100644
+--- a/modulemd/v1/tests/test-modulemd-defaults.c
++++ b/modulemd/v1/tests/test-modulemd-defaults.c
+@@ -602,10 +602,11 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
+ {
+   g_autofree gchar *yaml_base_path = NULL;
+   g_autofree gchar *yaml_override_path = NULL;
+   g_autoptr (GPtrArray) base_objects = NULL;
+   g_autoptr (GPtrArray) override_objects = NULL;
++  g_autoptr (GPtrArray) override_nodejs_objects = NULL;
+   g_autoptr (GPtrArray) merged_objects = NULL;
+   g_autoptr (ModulemdPrioritizer) prioritizer = NULL;
+   g_autoptr (GError) error = NULL;
+   GHashTable *htable = NULL;
+   gint64 prio;
+@@ -618,10 +619,22 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
+ 
+   base_objects = modulemd_objects_from_file (yaml_base_path, &error);
+   g_assert_nonnull (base_objects);
+   g_assert_cmpint (base_objects->len, ==, 7);
+ 
++
++  yaml_override_path =
++    g_strdup_printf ("%s/test_data/defaults/overriding-nodejs.yaml",
++                     g_getenv ("MESON_SOURCE_ROOT"));
++  g_assert_nonnull (yaml_override_path);
++
++  override_nodejs_objects =
++    modulemd_objects_from_file (yaml_override_path, &error);
++  g_clear_pointer (&yaml_override_path, g_free);
++  g_assert_nonnull (override_nodejs_objects);
++  g_assert_cmpint (override_nodejs_objects->len, ==, 1);
++
+   yaml_override_path = g_strdup_printf (
+     "%s/test_data/defaults/overriding.yaml", g_getenv ("MESON_SOURCE_ROOT"));
+   g_assert_nonnull (yaml_override_path);
+ 
+   override_objects = modulemd_objects_from_file (yaml_override_path, &error);
+@@ -659,10 +672,52 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
+       fprintf (stderr, "Merge error: %s", error->message);
+     }
+   g_assert_true (result);
+ 
+ 
++  /*
++   * Test that importing the nodejs overrides at the same priority level fails.
++   *
++   * This YAML has a conflicting default stream which should be ignored and set
++   * to "no default stream".
++   */
++
++  result = modulemd_prioritizer_add (
++    prioritizer, override_nodejs_objects, prio, &error);
++  g_assert_true (result);
++
++  merged_objects = modulemd_prioritizer_resolve (prioritizer, &error);
++  g_assert_nonnull (merged_objects);
++  g_assert_cmpint (merged_objects->len, ==, 3);
++
++  for (gint i = 0; i < merged_objects->len; i++)
++    {
++      if (MODULEMD_IS_DEFAULTS (g_ptr_array_index (merged_objects, i)))
++        {
++          defaults = g_ptr_array_index (merged_objects, i);
++          if (!g_strcmp0 (modulemd_defaults_peek_module_name (defaults),
++                          "nodejs"))
++            {
++              g_assert_null (modulemd_defaults_peek_default_stream (defaults));
++            }
++        }
++    }
++
++  g_clear_pointer (&merged_objects, g_ptr_array_unref);
++
++
++  /* Start over and test profile conflicts */
++  g_clear_pointer (&prioritizer, g_object_unref);
++  prioritizer = modulemd_prioritizer_new ();
++  result = modulemd_prioritizer_add (prioritizer, base_objects, prio, &error);
++  if (!result)
++    {
++      fprintf (stderr, "Merge error: %s", error->message);
++    }
++  g_assert_true (result);
++
++
+   /*
+    * Test that importing the overrides at the same priority level fails.
+    *
+    * These objects have several conflicts with the base objects that cannot be
+    * merged.
+@@ -671,11 +726,11 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
+     modulemd_prioritizer_add (prioritizer, override_objects, prio, &error);
+   g_assert_false (result);
+   g_assert_cmpstr (
+     g_quark_to_string (error->domain), ==, "modulemd-defaults-error-quark");
+   g_assert_cmpint (
+-    error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS);
++    error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES);
+   g_clear_pointer (&error, g_error_free);
+ 
+   /* The object's internal state is undefined after an error, so delete it */
+   g_clear_pointer (&prioritizer, g_object_unref);
+ 
+@@ -987,11 +1042,11 @@ modulemd_defaults_test_index_prioritizer (DefaultsFixture *fixture,
+     modulemd_prioritizer_add_index (prioritizer, override_index, prio, &error);
+   g_assert_false (result);
+   g_assert_cmpstr (
+     g_quark_to_string (error->domain), ==, "modulemd-defaults-error-quark");
+   g_assert_cmpint (
+-    error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS);
++    error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES);
+   g_clear_pointer (&error, g_error_free);
+ 
+   /* The object's internal state is undefined after an error, so delete it */
+   g_clear_pointer (&prioritizer, g_object_unref);
+ 
+@@ -1138,10 +1193,15 @@ modulemd_regressions_issue44 (DefaultsFixture *fixture,
+   g_assert_true (result);
+ 
+ 
+   /* Add another almost-identical document, except with a conflicting default
+    * stream set.
++   *
++   * NOTE: when this was written (for issue 44 on GitHub), this was meant to be
++   * a hard error. As of 1.8.1 we expect this to just result in having no
++   * default stream for this module. This test has been slightly modified so
++   * that the expected result is now a pass.
+    */
+   yaml_conflicting_path = g_strdup_printf (
+     "%s/test_data/defaults/issue44-2.yaml", g_getenv ("MESON_SOURCE_ROOT"));
+   g_assert_nonnull (yaml_conflicting_path);
+ 
+@@ -1149,11 +1209,11 @@ modulemd_regressions_issue44 (DefaultsFixture *fixture,
+     modulemd_objects_from_file (yaml_conflicting_path, &error);
+   g_assert_nonnull (conflicting_objects);
+ 
+   result =
+     modulemd_prioritizer_add (prioritizer, conflicting_objects, 0, &error);
+-  g_assert_false (result);
++  g_assert_true (result);
+ }
+ 
+ 
+ static void
+ modulemd_regressions_issue45 (DefaultsFixture *fixture,
+diff --git a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
+index 27cccb738dc805724268afa04acc13d4e250eae2..b019f0ed856684a003e9c2f6abefc70e1448246a 100644
+--- a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
++++ b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
+@@ -51,22 +51,30 @@ G_BEGIN_DECLS
+  * there exists two #ModulemdModuleStream entries that have different content
+  * for the same NSVC, the behavior is undefined.
+  *
+  * Merging #ModulemdDefaults entries behaves as follows:
+  *
++ * - Within a ModuleIndex, if two or more default entries reference the same
++ *   module, the one with the highest modified field will be used and the
++ *   others discarded.
++ * - When merging ModuleIndexes, if two or more indexes contain Defaults for
++ *   the same module, but different modified values, the one with the highest
++ *   modified value will be used and the others discarded.
+  * - Any module default that is provided by a single repository is
+  *   authoritative.
+  * - If the repos have different priorities (not common), then the default for
+  *   this module and stream name coming from the repo of higher priority will
+- *   be used and the default from the lower-priority repo will not be included.
++ *   be used and the default from the lower-priority repo will not be included
++ *   even if it has a higher modified value.
+  * - If the repos have the same priority (such as "fedora" and "updates" in the
+- *   Fedora Project), the entries will be merged as follows:
+- *   - If both repositories specify a default stream for the module, use it.
++ *   Fedora Project) and modified value, the entries will be merged as follows:
++ *   - If both repositories specify the same default stream for the module, use
++ *     it.
+  *   - If either repository specifies a default stream for the module and the
+  *     other does not, use the one specified.
+- *   - If both repositories specify different streams, this is an unresolvable
+- *     merge conflict and the merge resolution will fail and report an error.
++ *   - If both repositories specify different default streams, the merge will
++ *     unset the default stream and proceed with the merge.
+  *   - If both repositories specify a set of default profiles for a stream and
+  *     the sets are equivalent, use that set.
+  *   - If one repository specifies a set of default profiles for a stream and
+  *     the other does not, use the one specified.
+  *   - If both repositories specify a set of default profiles for a stream and
+diff --git a/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h b/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h
+index 9cac6cc53175a0eecca986f4fa96a7b7b1070957..de2ede98e6fb49bfd792b5f2913868fad6ff27db 100644
+--- a/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h
++++ b/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h
+@@ -26,10 +26,12 @@ G_BEGIN_DECLS
+  * @stability: private
+  * @short_description: #ModulemdDefault methods that should only be used by
+  * internal consumers.
+  */
+ 
++#define DEFAULT_MERGE_CONFLICT "__merge_conflict__"
++
+ /**
+  * modulemd_defaults_v1_parse_yaml:
+  * @subdoc: (in): A #ModulemdSubdocumentInfo representing a defaults document
+  * of metadata version 1.
+  * @strict: (in): Whether the parser should return failure if it encounters an
+diff --git a/modulemd/v2/modulemd-defaults-v1.c b/modulemd/v2/modulemd-defaults-v1.c
+index c8f983105b529519365d0a653d8d07715f610b97..1c1cdd7b1036734a477b72d12f12526af1de777d 100644
+--- a/modulemd/v2/modulemd-defaults-v1.c
++++ b/modulemd/v2/modulemd-defaults-v1.c
+@@ -179,11 +179,22 @@ modulemd_defaults_v1_get_default_stream (ModulemdDefaultsV1 *self,
+ {
+   const gchar *default_stream = NULL;
+   g_return_val_if_fail (MODULEMD_IS_DEFAULTS_V1 (self), NULL);
+ 
+   if (!intent)
+-    return self->default_stream;
++    {
++      if (self->default_stream &&
++          g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT))
++        {
++          /* During an index merge, we determined that this was in conflict
++           * with another set of ModulemdDefaults for the same module. If we
++           * see this, treat it as no default stream when querying for it.
++           */
++          return NULL;
++        }
++      return self->default_stream;
++    }
+ 
+   default_stream = g_hash_table_lookup (self->intent_default_streams, intent);
+   if (default_stream)
+     {
+       if (default_stream[0] == '\0')
+@@ -1159,12 +1170,10 @@ ModulemdDefaults *
+ modulemd_defaults_v1_merge (const gchar *module_name,
+                             ModulemdDefaultsV1 *from,
+                             ModulemdDefaultsV1 *into,
+                             GError **error)
+ {
+-  const gchar *into_default_stream;
+-  const gchar *from_default_stream;
+   g_autoptr (ModulemdDefaultsV1) merged = NULL;
+   GHashTableIter iter;
+   gpointer key, value;
+   GHashTable *intent_profiles = NULL;
+   GHashTable *merged_intent_profiles = NULL;
+@@ -1175,37 +1184,45 @@ modulemd_defaults_v1_merge (const gchar *module_name,
+   g_autoptr (GError) nested_error = NULL;
+ 
+   merged = modulemd_defaults_v1_new (module_name);
+ 
+   /* Merge the default streams */
+-  into_default_stream = modulemd_defaults_v1_get_default_stream (into, NULL);
+-  from_default_stream = modulemd_defaults_v1_get_default_stream (from, NULL);
+-
+-  if (into_default_stream && !from_default_stream)
++  if (into->default_stream && !from->default_stream)
+     {
+       modulemd_defaults_v1_set_default_stream (
+-        merged, into_default_stream, NULL);
++        merged, into->default_stream, NULL);
+     }
+-  else if (from_default_stream && !into_default_stream)
++  else if (from->default_stream && !into->default_stream)
+     {
+       modulemd_defaults_v1_set_default_stream (
+-        merged, from_default_stream, NULL);
++        merged, from->default_stream, NULL);
+     }
+-  else if (into_default_stream && from_default_stream)
++  else if (into->default_stream && from->default_stream)
+     {
+-      if (!g_str_equal (into_default_stream, from_default_stream))
++      if (g_str_equal (into->default_stream, DEFAULT_MERGE_CONFLICT))
+         {
+-          g_set_error (error,
+-                       MODULEMD_ERROR,
+-                       MODULEMD_ERROR_VALIDATE,
+-                       "Module stream mismatch in merge: %s != %s",
+-                       into_default_stream,
+-                       from_default_stream);
+-          return NULL;
++          /* A previous pass over this same module encountered a merge
++           * conflict, so we need to propagate that.
++           */
++          modulemd_defaults_v1_set_default_stream (
++            merged, DEFAULT_MERGE_CONFLICT, NULL);
++        }
++      else if (!g_str_equal (into->default_stream, from->default_stream))
++        {
++          /* They have conflicting default streams */
++          g_info ("Module stream mismatch in merge: %s != %s",
++                  into->default_stream,
++                  from->default_stream);
++          modulemd_defaults_v1_set_default_stream (
++            merged, DEFAULT_MERGE_CONFLICT, NULL);
++        }
++      else
++        {
++          /* They're the same, so store that */
++          modulemd_defaults_v1_set_default_stream (
++            merged, into->default_stream, NULL);
+         }
+-      modulemd_defaults_v1_set_default_stream (
+-        merged, into_default_stream, NULL);
+     }
+   else
+     {
+       /* Both values were NULL.
+        * Nothing to do, leave it blank.
+diff --git a/modulemd/v2/tests/ModulemdTests/merger.py b/modulemd/v2/tests/ModulemdTests/merger.py
+index e7cbf4214bb111fbc5732fe983ee5ccee134fd83..49c2722959486aeb250d88daf7f068cacc8c3fe7 100644
+--- a/modulemd/v2/tests/ModulemdTests/merger.py
++++ b/modulemd/v2/tests/ModulemdTests/merger.py
+@@ -104,26 +104,41 @@ class TestModuleIndexMerger(TestBase):
+         self.assertEqual(
+             len(httpd_defaults.get_default_profiles_for_stream('2.4', 'workstation')), 1)
+         self.assertEqual(
+             len(httpd_defaults.get_default_profiles_for_stream('2.6', 'workstation')), 3)
+ 
++        # Get another set of objects that will override the default stream for
++        # nodejs
++        override_nodejs_index = Modulemd.ModuleIndex()
++        override_nodejs_index.update_from_file(
++            path.join(
++                self.source_root,
++                "modulemd/v2/tests/test_data/overriding-nodejs.yaml"), True)
++
++        # Test that adding both of these at the same priority level results in
++        # the no default stream
++        merger = Modulemd.ModuleIndexMerger()
++        merger.associate_index(base_index, 0)
++        merger.associate_index(override_nodejs_index, 0)
++
++        merged_index = merger.resolve()
++        self.assertIsNotNone(merged_index)
++
++        nodejs = merged_index.get_module('nodejs')
++        self.assertIsNotNone(nodejs)
++
++        nodejs_defaults = nodejs.get_defaults()
++        self.assertIsNotNone(nodejs_defaults)
++        self.assertIsNone(nodejs_defaults.get_default_stream())
++
+         # Get another set of objects that will override the above
+         override_index = Modulemd.ModuleIndex()
+         override_index.update_from_file(
+             path.join(
+                 self.source_root,
+                 "modulemd/v2/tests/test_data/overriding.yaml"), True)
+ 
+-        # Test that adding both of these at the same priority level fails
+-        # with a merge conflict.
+-        merger = Modulemd.ModuleIndexMerger()
+-        merger.associate_index(base_index, 0)
+-        merger.associate_index(override_index, 0)
+-
+-        with self.assertRaisesRegex(GLib.GError, 'Module stream mismatch in merge'):
+-            merged_index = merger.resolve()
+-
+         # Test that override_index at a higher priority level succeeds
+         # Test that adding both of these at the same priority level fails
+         # with a merge conflict.
+         # Use randomly-selected high and low values to make sure we don't have
+         # sorting issues.
+diff --git a/modulemd/v2/tests/test_data/overriding-nodejs.yaml b/modulemd/v2/tests/test_data/overriding-nodejs.yaml
+new file mode 100644
+index 0000000000000000000000000000000000000000..b588f5f542d84755fa74fc1dbf059c0766d2a712
+--- /dev/null
++++ b/modulemd/v2/tests/test_data/overriding-nodejs.yaml
+@@ -0,0 +1,11 @@
++---
++# Override the default stream
++document: modulemd-defaults
++version: 1
++data:
++    module: nodejs
++    stream: '9.0'
++    profiles:
++        '6.0': [default]
++        '8.0': [super]
++        '9.0': [supermegaultra]
+\ No newline at end of file
+diff --git a/test_data/defaults/overriding-nodejs.yaml b/test_data/defaults/overriding-nodejs.yaml
+new file mode 100644
+index 0000000000000000000000000000000000000000..937a2b899afc6b5254fd3b3e61e5b32035a3130a
+--- /dev/null
++++ b/test_data/defaults/overriding-nodejs.yaml
+@@ -0,0 +1,10 @@
++---
++document: modulemd-defaults
++version: 1
++data:
++    module: nodejs
++    stream: '9.0'
++    profiles:
++        '6.0': [default]
++        '8.0': [super]
++        '9.0': [supermegaultra]
+\ No newline at end of file
+-- 
+2.20.1
+
diff --git a/SOURCES/0001-Include-modified-value-when-copying-Defaults-objects.patch b/SOURCES/0001-Include-modified-value-when-copying-Defaults-objects.patch
new file mode 100644
index 0000000..ad3ee96
--- /dev/null
+++ b/SOURCES/0001-Include-modified-value-when-copying-Defaults-objects.patch
@@ -0,0 +1,106 @@
+From f66d185dd5c2c1750b3626c2e0bdfeab63e427b6 Mon Sep 17 00:00:00 2001
+From: Stephen Gallagher <sgallagh@redhat.com>
+Date: Fri, 11 Jan 2019 08:36:11 -0500
+Subject: [PATCH] Include modified value when copying Defaults objects
+
+The symptom of this was that any defaults object read from a YAML
+stream would end up stored in the ModuleIndex with the a zero for
+the modified value.
+
+Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
+---
+ modulemd/v2/modulemd-defaults.c             |  7 ++++--
+ modulemd/v2/tests/ModulemdTests/defaults.py | 25 +++++++++++++++++++++
+ 2 files changed, 30 insertions(+), 2 deletions(-)
+
+diff --git a/modulemd/v2/modulemd-defaults.c b/modulemd/v2/modulemd-defaults.c
+index 9e5c31b499704ae7a8543c91b9ea3bbf0dbf981d..c577d4a0c3db45319c8e0582b4cc07f3943836fa 100644
+--- a/modulemd/v2/modulemd-defaults.c
++++ b/modulemd/v2/modulemd-defaults.c
+@@ -91,14 +91,18 @@ modulemd_defaults_copy (ModulemdDefaults *self)
+ 
+ 
+ static ModulemdDefaults *
+ modulemd_defaults_default_copy (ModulemdDefaults *self)
+ {
++  g_autoptr (ModulemdDefaults) copy = NULL;
+   g_return_val_if_fail (MODULEMD_IS_DEFAULTS (self), NULL);
+ 
+-  return modulemd_defaults_new (modulemd_defaults_get_mdversion (self),
++  copy = modulemd_defaults_new (modulemd_defaults_get_mdversion (self),
+                                 modulemd_defaults_get_module_name (self));
++  modulemd_defaults_set_modified (copy, modulemd_defaults_get_modified (self));
++
++  return g_steal_pointer (&copy);
+ }
+ 
+ 
+ gboolean
+ modulemd_defaults_validate (ModulemdDefaults *self, GError **error)
+@@ -214,11 +218,10 @@ modulemd_defaults_set_modified (ModulemdDefaults *self, guint64 modified)
+ {
+   g_return_if_fail (MODULEMD_IS_DEFAULTS (self));
+ 
+   ModulemdDefaultsPrivate *priv =
+     modulemd_defaults_get_instance_private (self);
+-
+   priv->modified = modified;
+ }
+ 
+ 
+ guint64
+diff --git a/modulemd/v2/tests/ModulemdTests/defaults.py b/modulemd/v2/tests/ModulemdTests/defaults.py
+index ddac23bbed573b3725feb8cb0090fb878a1f4f22..9a783d25617fc53f59448bc32a68c6e2755dd034 100644
+--- a/modulemd/v2/tests/ModulemdTests/defaults.py
++++ b/modulemd/v2/tests/ModulemdTests/defaults.py
+@@ -10,11 +10,13 @@
+ # This program is free software.
+ # For more information on the license, see COPYING.
+ # For more information on free software, see
+ # <https://www.gnu.org/philosophy/free-sw.en.html>.
+ 
++import os
+ import sys
++
+ try:
+     import unittest
+     import gi
+     gi.require_version('Modulemd', '2.0')
+     from gi.repository import Modulemd
+@@ -92,10 +94,33 @@ class TestDefaults(TestBase):
+ 
+         # Ensure we cannot set the module_name
+         with self.expect_signal():
+             defs.props.module_name = None
+ 
++    def test_modified(self):
++        defs = Modulemd.Defaults.new(
++            Modulemd.DefaultsVersionEnum.LATEST, 'foo')
++        self.assertIsNotNone(defs)
++
++        self.assertEqual(defs.get_modified(), 0)
++
++        defs.set_modified(201901110830)
++
++        self.assertEqual(defs.get_modified(), 201901110830)
++
++        # Load a defaults object into an Index
++        index = Modulemd.ModuleIndex.new()
++        index.update_from_file("%s/mod-defaults/spec.v1.yaml" % (
++            os.getenv('MESON_SOURCE_ROOT')), True)
++        module_names = index.get_module_names()
++        self.assertEqual(len(module_names), 1)
++
++        defs = index.get_module(index.get_module_names()[0]).get_defaults()
++        self.assertIsNotNone(defs)
++
++        self.assertEqual(defs.get_modified(), 201812071200)
++
+     def test_validate(self):
+         defs = Modulemd.Defaults.new(
+             Modulemd.DefaultsVersionEnum.LATEST, 'foo')
+         assert defs
+ 
+-- 
+2.20.1
+
diff --git a/SPECS/libmodulemd.spec b/SPECS/libmodulemd.spec
new file mode 100644
index 0000000..abf46d8
--- /dev/null
+++ b/SPECS/libmodulemd.spec
@@ -0,0 +1,428 @@
+%global libmodulemd_version 2.0.0
+%global libmodulemd_v1_version 1.8.0
+
+Name:           libmodulemd
+Version:        %{libmodulemd_version}
+Release:        5%{?dist}
+Summary:        Module metadata manipulation library
+
+License:        MIT
+URL:            https://github.com/fedora-modularity/libmodulemd
+Source0:        %{url}/releases/download/%{name}-%{version}/modulemd-%{version}.tar.xz
+
+BuildRequires:  meson >= 0.45.1-3
+BuildRequires:  pkgconfig
+BuildRequires:  gcc
+BuildRequires:  gcc-c++
+BuildRequires:  pkgconfig(gobject-2.0)
+BuildRequires:  pkgconfig(gobject-introspection-1.0)
+BuildRequires:  pkgconfig(yaml-0.1)
+BuildRequires:  pkgconfig(gtk-doc)
+BuildRequires:  python3-devel
+BuildRequires:  python3-gobject-base
+%ifarch %{valgrind_arches}
+BuildRequires:  valgrind
+%endif
+
+Obsoletes:      python2-modulemd < 1.3.4
+Obsoletes:      python3-modulemd < 1.3.4
+
+# Make sure we upgrade libmodulemd1 to match
+Conflicts:      libmodulemd1 < %{libmodulemd_v1_version}-%{release}
+
+# Patches
+Patch0001: 0001-Include-modified-value-when-copying-Defaults-objects.patch
+Patch0002: 0001-Don-t-fail-merges-when-default-streams-differ.patch
+
+%description
+C Library for manipulating module metadata files.
+See https://github.com/fedora-modularity/libmodulemd/blob/master/README.md for
+more details.
+
+
+%package -n python3-%{name}
+Summary: Python 3 bindings for %{name}
+BuildArch: noarch
+Requires: libmodulemd = %{version}-%{release}
+Requires: python3-gobject-base
+Obsoletes: python3-modulemd < 1.3.4
+
+%description -n python3-%{name}
+Python 3 bindings for %{name}
+
+
+%package devel
+Summary:        Development files for libmodulemd
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+
+
+%description devel
+Development files for libmodulemd.
+
+
+%package -n libmodulemd1
+Summary: Compatibility package for libmodulemd 1.x
+Version: %{libmodulemd_v1_version}
+Obsoletes: libmodulemd < 2
+Provides: libmodulemd = %{libmodulemd_v1_version}-%{release}
+Provides: libmodulemd%{?_isa} = %{libmodulemd_v1_version}-%{release}
+
+%description -n libmodulemd1
+Compatibility library for libmodulemd 1.x
+
+
+%package -n libmodulemd1-devel
+Summary: Compatibility development package for libmodulemd 1.x
+Version: %{libmodulemd_v1_version}
+Requires: libmodulemd1%{?_isa} = %{libmodulemd_v1_version}-%{release}
+Conflicts: %{name}-devel
+Obsoletes: libmodulemd-devel < 2
+Provides: libmodulemd-devel = %{libmodulemd_v1_version}-%{release}
+RemovePathPostfixes: .compat
+
+
+%description -n libmodulemd1-devel
+Development files for libmodulemd 1.x
+
+
+%package -n python3-libmodulemd1
+Summary: Python 3 bindings for %{name}1
+Version: %{libmodulemd_v1_version}
+BuildArch: noarch
+Requires: libmodulemd1 = %{libmodulemd_v1_version}-%{release}
+Requires: python3-gobject-base
+
+%description -n python3-libmodulemd1
+Python 3 bindings for libmodulemd1
+
+
+%prep
+%autosetup -p1 -n modulemd-%{libmodulemd_version}
+
+
+%build
+%define _vpath_builddir api1
+%meson -Ddeveloper_build=false -Dbuild_api_v1=true -Dbuild_api_v2=false
+%meson_build
+
+%define _vpath_builddir api2
+%meson -Ddeveloper_build=false -Dbuild_api_v1=false -Dbuild_api_v2=true
+%meson_build
+
+
+%check
+
+export LC_CTYPE=C.utf8
+
+%ifarch %{power64}
+# Valgrind is broken on ppc64[le] with GCC7:
+# https://bugs.kde.org/show_bug.cgi?id=386945
+export MMD_SKIP_VALGRIND=1
+%endif
+%ifnarch %{valgrind_arches}
+export MMD_SKIP_VALGRIND=1
+%endif
+
+%define _vpath_builddir api1
+%meson_test
+
+%define _vpath_builddir api2
+%meson_test
+
+
+%install
+%define _vpath_builddir api1
+%meson_install
+
+%define _vpath_builddir api2
+%meson_install
+
+ln -s libmodulemd.so.%{libmodulemd_v1_version} \
+      %{buildroot}%{_libdir}/%{name}.so.compat
+
+
+%files
+%license COPYING
+%doc README.md
+%{_bindir}/modulemd-validator
+%{_libdir}/%{name}.so.2*
+%dir %{_libdir}/girepository-1.0
+%{_libdir}/girepository-1.0/Modulemd-2.0.typelib
+%{python3_sitearch}/gi/overrides/
+
+
+%files devel
+%{_libdir}/%{name}.so
+%{_libdir}/pkgconfig/modulemd-2.0.pc
+%{_includedir}/modulemd-2.0/
+%dir %{_datadir}/gir-1.0
+%{_datadir}/gir-1.0/Modulemd-2.0.gir
+%dir %{_datadir}/gtk-doc
+%dir %{_datadir}/gtk-doc/html
+%{_datadir}/gtk-doc/html/modulemd-2.0/
+
+
+%files -n python3-%{name}
+
+
+%files -n python3-libmodulemd1
+
+
+%files -n libmodulemd1
+%license COPYING
+%doc README.md
+%{_bindir}/modulemd-validator-v1
+%{_libdir}/%{name}.so.1*
+%dir %{_libdir}/girepository-1.0
+%{_libdir}/girepository-1.0/Modulemd-1.0.typelib
+
+
+%files -n libmodulemd1-devel
+%{_libdir}/%{name}.so.compat
+%{_libdir}/pkgconfig/modulemd.pc
+%{_includedir}/modulemd/
+%dir %{_datadir}/gir-1.0
+%{_datadir}/gir-1.0/Modulemd-1.0.gir
+%dir %{_datadir}/gtk-doc
+%dir %{_datadir}/gtk-doc/html
+%{_datadir}/gtk-doc/html/modulemd-1.0/
+
+
+%changelog
+* Fri Jan 18 2019 Stephen Gallagher <sgallagh@redhat.com> - 2.0.0-5
+- Don't fail merges when default streams differ
+- Resolves: rhbz#1666871
+
+* Wed Jan 16 2019 Stephen Gallagher <sgallagh@redhat.com> - 2.0.0-4
+- Include modified value when copying Defaults objects
+- Resolves: rhbz#1665465
+
+* Thu Dec 13 2018 Stephen Gallagher <sgallagh@redhat.com> - 2.0.0-3
+- Keep libmodulemd1 in sync with libmodulemd
+
+* Thu Dec 13 2018 Stephen Gallagher <sgallagh@redhat.com> - 2.0.0-2
+- Fix package location of modulemd-validator
+
+* Thu Dec 13 2018 Stephen Gallagher <sgallagh@redhat.com> - 2.0.0-1
+- Update to 2.0.0 final
+- Assorted fixes for validation
+- Add modulemd-validator tool based on v2 code
+- Fix a crash when merging defaults
+- Add missing BuildRequires
+
+* Tue Dec 11 2018 Stephen Gallagher <sgallagh@redhat.com> - 2.0.0-0.beta2
+- Update to 2.0.0beta2
+- Better validation of stored content during read and write operations
+- ModuleIndex now returns FALSE if any subdocument fails
+- Fix tests on 32-bit platforms
+- Make unknown keys in YAML maps non-fatal for libmodulemd1
+- Make unknown keys in YAML maps optionally fatal for libmodulemd 2.x
+- Fix RPM version requirements for libmodulemd1
+
+* Mon Dec 10 2018 Stephen Gallagher <sgallagh@redhat.com> - 2.0.0-0.beta1
+- Total rewrite to 2.0 API
+- Resolves: rhbz#1646436
+
+* Thu Aug 09 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.6.2-2
+- Fix backwards-incompatible API change
+- Resolves: rhbz#1607083
+
+* Tue Aug 07 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.6.2-1
+- Update to 1.6.2
+- Make buildorder a signed integer to match modulemd specification
+- Obsolete unsupported pythonX-modulemd packages
+
+* Fri Aug  3 2018 Florian Weimer <fweimer@redhat.com> - 1.6.1-2
+- Honor %%{valgrind_arches}
+
+* Fri Jul 20 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.6.1-1
+- Update to 1.6.1
+- Fix header include ordering
+- Suppress empty sections from .dump() ordering
+
+* Wed Jul 18 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.6.0-1
+- Update to 1.6.0
+- Adds Modulemd.ModuleStream object, deprecating Modulemd.Module
+- Adds Modulemd.Translation and Modulemd.TranslationEntry objects
+- Adds Modulemd.ImprovedModule object that collects streams, defaults and
+  translations together
+- Adds new Modulemd.index_from_*() funtions to get a hash table of
+  Modulemd.ImprovedModule objects for easier searching
+- Moves function documentation to the public headers
+- Corrects the license headers to MIT (they were incorrectly listed as MITNFA
+  in previous releases)
+- Makes the "eol" field optional for Modulemd.ServiceLevel
+- Clean up HTML documentation
+- Fixes a type error on 32-bit systems
+
+* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Sat Jun 23 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.5.2-1
+- Update to libdmodulemd 1.5.2
+- Don't free uninitialized memory
+
+* Fri Jun 22 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.5.1-2
+- Fix buildopts property not being initialized
+
+* Tue Jun 19 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.5.1-1
+- Update to version 1.5.1
+- Re-enable build-time tests
+
+* Mon Jun 18 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.5.0-2
+- Temporarily disable build-time tests
+
+* Mon Jun 18 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.5.0-1
+- Update to version 1.5.0
+- Adds support for "intents" in Modulemd.Defaults
+- Adds `Modulemd.get_version()`
+- Adds support for RPM whitelists in the buildopts
+- Adds a new object: Modulemd.Buildopts
+- Deprecates Modulemd.Module.get_rpm_buildopts()
+- Deprecates Modulemd.Module.set_rpm_buildopts()
+- Fixes some missing license blurbs
+
+* Tue May 08 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.4.1-1
+- Update to version 1.4.1
+- Improve output from modulemd-validator
+- Drop upstreamed patches
+
+* Wed Apr 25 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.4.0-2
+- Fix pointer math error
+- Fix compilation failure in Fedora build system
+
+* Wed Apr 25 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.4.0-1
+- Update to version 1.4.0
+- Adds new API for returning failed YAML subdocuments
+- Stop emitting log messages by default (polluting consumer logs)
+- Validate RPM artifacts for proper NEVRA format
+- Improve the validator tool
+- Drop upstreamed patch
+
+* Mon Apr 16 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.3.0-2
+- Fix serious error in modulemd-defaults emitter
+
+* Fri Apr 13 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.3.0-1
+- Update to version 1.3.0
+- New Public Objects:
+  * Modulemd.Prioritizer - tool to merge module defaults
+- New Public Functions:
+  * Modulemd.SimpleSet.is_equal()
+  * Modulemd.Defaults.copy()
+  * Modulemd.Defaults.merge()
+
+* Wed Apr 04 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.2.0-1
+- Update to version 1.2.0
+- New Functions:
+  * Modulemd.objects_from_file()
+  * Modulemd.objects_from_string()
+  * Modulemd.dump()
+  * Modulemd.dumps()
+  * Modulemd.Defaults.new_from_file()
+  * Modulemd.Defaults.new_from_string()
+- Deprecated Functions:
+  * Modulemd.Module.new_all_from_file()
+  * Modulemd.Module.new_all_from_file_ext()
+  * Modulemd.Module.new_all_from_string()
+  * Modulemd.Module.new_all_from_string_ext()
+  * Modulemd.Module.dump_all()
+  * Modulemd.Module.dumps_all()
+- Bugfixes
+  * Properly use G_BEGIN_DECLS and G_END_DECLS in headers
+  * Assorted fixes for memory ownership in GObject Introspection
+
+* Fri Mar 23 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.1.3-2
+- Fix missing G_END_DECL from public headers
+
+* Mon Mar 19 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.1.3-1
+- Fix numerous memory leaks
+- Drop upstreamed patch
+
+* Thu Mar 15 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.1.2-1
+- Update to version 1.1.2
+- Revert backwards-incompatible API change
+- Fix version string in pkgconfig file
+
+* Thu Mar 15 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.1.1-1
+- Update to version 1.1.1
+- Make default stream and profiles optional
+- Fixes: https://github.com/fedora-modularity/libmodulemd/issues/25
+- Fixes: https://github.com/fedora-modularity/libmodulemd/issues/26
+- Fixes: https://github.com/fedora-modularity/libmodulemd/issues/27
+
+* Wed Mar 14 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.1.0-1
+- Update to version 1.1.0
+- Adds support for handling modulemd-defaults YAML documents
+- Adds peek()/dup() routines to all object properties
+- Adds Modulemd.Module.dup_nsvc() to retrieve the canonical form of the unique module identifier.
+- Adds support for boolean types in the XMD section
+- Revert obsoletion of pythonX-modulemd packages for now
+
+* Tue Mar 13 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.0.4-2
+- Obsolete unsupported pythonX-modulemd packages
+
+* Tue Feb 27 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.0.4-1
+- Update to 1.0.4
+- Rework version autodetection
+- Avoid infinite loop on unparseable YAML
+
+* Sun Feb 25 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.0.3-1
+- RPM components are properly emitted when no module components exist
+- Parser works around late determination of modulemd version
+
+* Fri Feb 16 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.0.2-1
+- Be more strict with certain parser edge-cases
+- Replace popt argument processing with glib
+- Drop upstreamed patches
+
+* Thu Feb 15 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.0.1-2
+- Handle certain unlikely format violations
+
+* Thu Feb 15 2018 Stephen Gallagher <sgallagh@redhat.com> - 1.0.1-1
+- Support modulemd v2
+- Add tool to do quick validation of modulemd
+- Fix memory management
+- Warn and ignore unparseable sub-documents in the YAML
+- Fix several memory issues detected by Coverity scan
+
+* Tue Feb 06 2018 Stephen Gallagher <sgallagh@redhat.com> - 0.2.2-1
+- Update to libmodulemd 0.2.2
+- Fix numerous minor memory leaks
+- Fix issues with EOL/SL dates
+
+* Tue Feb 06 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.2.1-3
+- Own appropriate directories
+
+* Fri Feb 02 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.2.1-2
+- Switch to %%ldconfig_scriptlets
+
+* Fri Jan 05 2018 Stephen Gallagher <sgallagh@redhat.com> - 0.2.1-1
+- Update to libmodulemd 0.2.1
+- Add 'name' property for Profiles
+
+* Thu Oct 05 2017 Stephen Gallagher <sgallagh@redhat.com> - 0.2.0-2
+- Add missing BuildRequires for gtk-doc
+
+* Thu Oct 05 2017 Stephen Gallagher <sgallagh@redhat.com> - 0.2.0-1
+- Update to libmodulemd 0.2.0
+- Adds gtk-doc generated documentation
+- (ABI-break) Makes all optional properties accept NULL as a value to clear
+  them
+- (ABI-break) Modulemd.SimpleSet takes a STRV (char **) instead of a
+  GLib.PtrArray
+- Fixes a bug where the name was not always set for components
+- Adds support for dumping YAML from the introspected API
+- Includes add/remove routines for profiles
+
+* Sat Sep 30 2017 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.1.0-5
+- Use %%_isa in Requires for main package from devel
+
+* Mon Sep 18 2017 Stephen Gallagher <sgallagh@redhat.com> - 0.1.0-4
+- Correct the license to MIT
+
+* Mon Sep 18 2017 Stephen Gallagher <sgallagh@redhat.com> - 0.1.0-3
+- Modifications requested during package review
+
+* Fri Sep 15 2017 Stephen Gallagher <sgallagh@redhat.com> - 0.1.0-2
+- First public release
+