def annotate(origin, reference, ops, annotation=None):
    """
    Uses a list of operations to create an annotation for how the operations
    should be applied, using an origin and a reference target

    :param origin: The original iterable
    :type origin: str or list
    :param reference: The original target
    :type reference: str or list
    :ops: The operations to apply
    :type ops: list of Operation
    :param annotation: An optional initialization for the annotation. If none
                       is provided, the annotation will be based on the
                       origin. If one is provided, it will be modified by this
                       method.
    :return: An annotation based on the operations
    :rtype: list of str
    """
    annotation = annotation or list(origin)

    for oper in ops:
        oper.annotate(annotation, origin, reference)

    for i, label in reversed(list(enumerate(annotation))):
        if label[0] == '+' and i > 0:
            annotation[i-1] += label
            del annotation[i]

    return annotation