'Finds the index of the closing char that matches the opening char.
For example, this could be used to find the end of a Mako expression,
where the open and close characters would be \'{\' and \'}\'.
Arguments:
start_delim: If provided (e.g. \'${\' for Mako expressions), the
closing character must be found before the next start_delim.
open_char: The opening character to be matched (e.g \'{\')
close_char: The closing character to be matched (e.g \'}\')
template: The template to be searched.
start_index: The start index of the last open char.
num_open_chars: The current number of open chars.
strings: A list of ParseStrings already parsed
Returns:
A dict containing the following, or None if unparseable:
close_char_index: The index of the closing character
strings: a list of ParseStrings'

def _find_closing_char_index(self, start_delim, open_char, close_char, template, start_index, num_open_chars=0, strings=None):

    strings = ([] if (strings is None) else strings)
    start_index = self._uncommented_start_index(template, start_index)
    while (start_index is not None):
        close_char_index = template.find(close_char, start_index)
        if (close_char_index < 0):
            return None
        open_char_index = template.find(open_char, start_index, close_char_index)
        parse_string = ParseString(template, start_index, close_char_index)
        valid_index_list = [close_char_index]
        if (0 <= open_char_index):
            valid_index_list.append(open_char_index)
        if (parse_string.start_index is not None):
            valid_index_list.append(parse_string.start_index)
        min_valid_index = min(valid_index_list)
        start_index = self._uncommented_start_index(template, min_valid_index)
        if (start_index == min_valid_index):
            break
    if (start_index is None):
        return None
    if (parse_string.start_index == min_valid_index):
        strings.append(parse_string)
        if (parse_string.end_index is None):
            return None
        else:
            return self._find_closing_char_index(start_delim, open_char, close_char, template, start_index=parse_string.end_index, num_open_chars=num_open_chars, strings=strings)
    if (open_char_index == min_valid_index):
        if (start_delim is not None):
            start_delim_index = template.find(start_delim, start_index, close_char_index)
            if (0 <= start_delim_index < open_char_index):
                return None
        return self._find_closing_char_index(start_delim, open_char, close_char, template, start_index=(open_char_index + 1), num_open_chars=(num_open_chars + 1), strings=strings)
    if (num_open_chars == 0):
        return {'close_char_index': close_char_index, 'strings': strings}
    else:
        return self._find_closing_char_index(start_delim, open_char, close_char, template, start_index=(close_char_index + 1), num_open_chars=(num_open_chars - 1), strings=strings)
