Substitute references within a string that is using ${key} syntax by calling the `handler_method` on every
        occurrence of this structure. The value returned by this method directly replaces the reference structure.

        Ex:
            text = "${key1}-hello-${key2}
            def handler_method(full_ref, ref_value):
                return "foo"

            _sub_all_refs(text, handler_method) will output "foo-hello-foo"

        :param string text: Input text
        :param handler_method: Method to be called to handle each occurrence of ${blah} reference structure.
            First parameter to this method is the full reference structure Ex: ${LogicalId.Property}.
            Second parameter is just the value of the reference such as "LogicalId.Property"

        :return string: Text with all reference structures replaced as necessary

def _sub_all_refs(self, text, handler_method):
        """
        Substitute references within a string that is using ${key} syntax by calling the `handler_method` on every
        occurrence of this structure. The value returned by this method directly replaces the reference structure.

        Ex:
            text = "${key1}-hello-${key2}
            def handler_method(full_ref, ref_value):
                return "foo"

            _sub_all_refs(text, handler_method) will output "foo-hello-foo"

        :param string text: Input text
        :param handler_method: Method to be called to handle each occurrence of ${blah} reference structure.
            First parameter to this method is the full reference structure Ex: ${LogicalId.Property}.
            Second parameter is just the value of the reference such as "LogicalId.Property"

        :return string: Text with all reference structures replaced as necessary
        """

        # RegExp to find pattern "${logicalId.property}" and return the word inside bracket
        logical_id_regex = '[A-Za-z0-9\.]+|AWS::[A-Z][A-Za-z]*'
        ref_pattern = re.compile(r'\$\{(' + logical_id_regex + ')\}')

        # Find all the pattern, and call the handler to decide how to substitute them.
        # Do the substitution and return the final text
        return re.sub(ref_pattern,
                      # Pass the handler entire string ${logicalId.property} as first parameter and "logicalId.property"
                      # as second parameter. Return value will be substituted
                      lambda match: handler_method(match.group(0), match.group(1)),
                      text)