when merging values add option to ignore missing references that are overwritten and never used
diff --git a/reclass/datatypes/tests/test_parameters.py b/reclass/datatypes/tests/test_parameters.py
index 719c828..07786c1 100644
--- a/reclass/datatypes/tests/test_parameters.py
+++ b/reclass/datatypes/tests/test_parameters.py
@@ -7,6 +7,8 @@
 # Released under the terms of the Artistic Licence 2.0
 #
 
+import copy
+
 from reclass.settings import Settings
 from reclass.datatypes import Parameters
 from reclass.errors import InfiniteRecursionError, InterpolationError
@@ -19,6 +21,17 @@
 SIMPLE = {'one': 1, 'two': 2, 'three': 3}
 SETTINGS = Settings()
 
+class MockDevice(object):
+    def __init__(self):
+        self._text = ''
+
+    def write(self, s):
+        self._text += s
+        return
+
+    def text(self):
+        return self._text
+
 class TestParameters(unittest.TestCase):
 
     def _construct_mocked_params(self, iterable=None, settings=SETTINGS):
@@ -500,5 +513,50 @@
             p1.interpolate()
         self.assertEqual(error.exception.message, "-> \n   Bad references, at gamma\n      ${beta}")
 
+    def test_ignore_overwriten_missing_reference(self):
+        settings = copy.deepcopy(SETTINGS)
+        settings.ignore_overwritten_missing_references = True
+        p1 = Parameters({'alpha': '${beta}'}, settings, '')
+        p2 = Parameters({'alpha': '${gamma}'}, settings, '')
+        p3 = Parameters({'gamma': 3}, settings, '')
+        r1 = {'alpha': 3, 'gamma': 3}
+        p1.merge(p2)
+        p1.merge(p3)
+        err1 = "[WARNING] Reference '${beta}' undefined\n"
+        with mock.patch('sys.stderr', new=MockDevice()) as std_err:
+            p1.interpolate()
+        self.assertEqual(p1.as_dict(), r1)
+        self.assertEqual(std_err.text(), err1)
+
+    def test_ignore_overwriten_missing_reference_last_value(self):
+        # an error should be raised if the last reference to be merged
+        # is missing even if ignore_overwritten_missing_references is true
+        settings = copy.deepcopy(SETTINGS)
+        settings.ignore_overwritten_missing_references = True
+        p1 = Parameters({'alpha': '${gamma}'}, settings, '')
+        p2 = Parameters({'alpha': '${beta}'}, settings, '')
+        p3 = Parameters({'gamma': 3}, settings, '')
+        p1.merge(p2)
+        p1.merge(p3)
+        with self.assertRaises(InterpolationError) as error:
+            p1.interpolate()
+        self.assertEqual(error.exception.message, "-> \n   Cannot resolve ${beta}, at alpha")
+
+    def test_ignore_overwriten_missing_reference_dict(self):
+        # setting ignore_overwritten_missing_references to true should
+        # not change the behaviour for dicts
+        settings = copy.deepcopy(SETTINGS)
+        settings.ignore_overwritten_missing_references = True
+        p1 = Parameters({'alpha': '${beta}'}, settings, '')
+        p2 = Parameters({'alpha': '${gamma}'}, settings, '')
+        p3 = Parameters({'gamma': {'one': 1, 'two': 2}}, settings, '')
+        err1 = "[WARNING] Reference '${beta}' undefined\n"
+        p1.merge(p2)
+        p1.merge(p3)
+        with self.assertRaises(InterpolationError) as error, mock.patch('sys.stderr', new=MockDevice()) as std_err:
+            p1.interpolate()
+        self.assertEqual(error.exception.message, "-> \n   Cannot resolve ${beta}, at alpha")
+        self.assertEqual(std_err.text(), err1)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/reclass/defaults.py b/reclass/defaults.py
index 82f49b2..9fbb478 100644
--- a/reclass/defaults.py
+++ b/reclass/defaults.py
@@ -17,10 +17,13 @@
 OPT_PRETTY_PRINT = True
 OPT_NO_REFS = False
 OPT_OUTPUT = 'yaml'
+
 OPT_IGNORE_CLASS_NOTFOUND = False
 OPT_IGNORE_CLASS_NOTFOUND_REGEXP = ['.*']
 OPT_IGNORE_CLASS_NOTFOUND_WARNING = True
 
+OPT_IGNORE_OVERWRITTEN_MISSING_REFERENCES = False
+
 OPT_ALLOW_SCALAR_OVER_DICT = False
 OPT_ALLOW_SCALAR_OVER_LIST = False
 OPT_ALLOW_LIST_OVER_SCALAR = False
diff --git a/reclass/settings.py b/reclass/settings.py
index 987e707..44078ad 100644
--- a/reclass/settings.py
+++ b/reclass/settings.py
@@ -26,6 +26,7 @@
 
         self.ignore_class_notfound_warning = options.get('ignore_class_notfound_warning', OPT_IGNORE_CLASS_NOTFOUND_WARNING)
 
+        self.ignore_overwritten_missing_references = options.get('ignore_overwritten_missing_references', OPT_IGNORE_OVERWRITTEN_MISSING_REFERENCES)
 
         self.ref_parser = reclass.values.parser_funcs.get_ref_parser(self.escape_character, self.reference_sentinels, self.export_sentinels)
         self.simple_ref_parser = reclass.values.parser_funcs.get_simple_ref_parser(self.escape_character, self.reference_sentinels, self.export_sentinels)
diff --git a/reclass/values/compitem.py b/reclass/values/compitem.py
index 5786934..2134ea8 100644
--- a/reclass/values/compitem.py
+++ b/reclass/values/compitem.py
@@ -49,3 +49,6 @@
 
     def __repr__(self):
         return 'CompItem(%r)' % self._items
+
+    def __str__(self):
+        return ''.join([ str(i) for i in self._items ])
diff --git a/reclass/values/refitem.py b/reclass/values/refitem.py
index ebb9708..0ae65e6 100644
--- a/reclass/values/refitem.py
+++ b/reclass/values/refitem.py
@@ -5,10 +5,12 @@
 #
 
 from item import Item
+from reclass.defaults import REFERENCE_SENTINELS
 from reclass.settings import Settings
 from reclass.utils.dictpath import DictPath
 from reclass.errors import ResolveError
 
+
 class RefItem(Item):
 
     def __init__(self, items, settings):
@@ -62,3 +64,7 @@
 
     def __repr__(self):
         return 'RefItem(%r)' % self._items
+
+    def __str__(self):
+        strings = [ str(i) for i in self._items ]
+        return '{0}{1}{2}'.format(REFERENCE_SENTINELS[0], ''.join(strings), REFERENCE_SENTINELS[1])
diff --git a/reclass/values/scaitem.py b/reclass/values/scaitem.py
index df574d9..6fd3194 100644
--- a/reclass/values/scaitem.py
+++ b/reclass/values/scaitem.py
@@ -37,3 +37,6 @@
 
     def __repr__(self):
         return 'ScaItem({0!r})'.format(self._value)
+
+    def __str__(self):
+        return str(self._value)
diff --git a/reclass/values/value.py b/reclass/values/value.py
index cbd5ce2..4ec6051 100644
--- a/reclass/values/value.py
+++ b/reclass/values/value.py
@@ -83,3 +83,6 @@
 
     def __repr__(self):
         return 'Value(%r)' % self._item
+
+    def __str__(self):
+        return str(self._item)
diff --git a/reclass/values/valuelist.py b/reclass/values/valuelist.py
index f89a0c3..6201564 100644
--- a/reclass/values/valuelist.py
+++ b/reclass/values/valuelist.py
@@ -5,6 +5,9 @@
 #
 
 import copy
+import sys
+
+from reclass.errors import ResolveError
 
 class ValueList(object):
 
@@ -87,12 +90,22 @@
 
         output = None
         deepCopied = False
+        last_error = None
         for n, value in enumerate(self._values):
+            try:
+                new = value.render(context, inventory)
+            except ResolveError as e:
+                if self._settings.ignore_overwritten_missing_references and not isinstance(output, (dict, list)) and n != (len(self._values)-1):
+                    new = None
+                    last_error = e
+                    print >>sys.stderr, "[WARNING] Reference '%s' undefined" % (str(value))
+                else:
+                    raise e
+
             if output is None:
-                output = self._values[n].render(context, inventory)
+                output = new
                 deepCopied = False
             else:
-                new = value.render(context, inventory)
                 if isinstance(output, dict) and isinstance(new, dict):
                     p1 = Parameters(output, self._settings, None)
                     p2 = Parameters(new, self._settings, None)
@@ -109,6 +122,10 @@
                     raise TypeError('Cannot merge %s over %s' % (repr(self._values[n]), repr(self._values[n-1])))
                 else:
                     output = new
+
+        if isinstance(output, (dict, list)) and last_error is not None:
+            raise last_error
+
         return output
 
     def __repr__(self):