def parse_grandchildren_using_function(parent, child_tag, parse_function,
    tag=None, optional=False):
    """
    Find and parse grandchildren using a specified function.
    
    :param parent: The parent ``Element`` object.
    :param child_tag: The name of the child tag.
    :param parse_function: A function which accepts an ``Element`` and returns an object.
    :param tag: Thet ag name of tehs pecific type of grandchild to parse, or None to parse all grandchildren. 
    :param optional: If False, raise an exception if no parent node is found.
    
    :raises: An Exception if no parent node with the tag name specified by 
        ``child_class.PARENT_TAG_NAME`` is found and ``optional`` is ``False``.
    
    :returns: A list of objects.
    """
    node = parent.find(child_tag)
    if node == None:
        if optional:
            return []
        else:
            raise Exception(
                'Node {0} does not contain required child node {1}.'.format
                (parent.tag, tag))
    else:
        if tag == None:
            nodes = node.getchildren()
        else:
            nodes = node.findall(tag)
        children = []
        for n in nodes:
            c = parse_function(n)
            if c != None:
                children.append(c)
        return children
