def to_synapse_annotations(annotations):
    """Transforms a simple flat dictionary to a Synapse-style Annotation object."""
    
    if is_synapse_annotations(annotations):
        return annotations
    synapseAnnos = {}
    for key, value in annotations.iteritems():
        if key in ['id', 'etag', 'blobAnnotations', 'creationDate', 'uri']:
            synapseAnnos[key] = value
        elif key in ['stringAnnotations','longAnnotations','doubleAnnotations','dateAnnotations'] and isinstance(value, collections.Mapping):
            synapseAnnos.setdefault(key, {}).update({k:_to_list(v) for k,v in value.iteritems()})
        else:
            elements = _to_list(value)
            if all((isinstance(elem, basestring) for elem in elements)):
                synapseAnnos.setdefault('stringAnnotations', {})[key] = elements
            elif all((isinstance(elem, bool) for elem in elements)):
                synapseAnnos.setdefault('stringAnnotations', {})[key] = [str(element).lower() for element in elements]
            elif all((isinstance(elem, int) or isinstance(elem, long) for elem in elements)):
                synapseAnnos.setdefault('longAnnotations', {})[key] = elements
            elif all((isinstance(elem, float) for elem in elements)):
                synapseAnnos.setdefault('doubleAnnotations', {})[key] = elements
            elif all((_is_date(elem) for elem in elements)):
                synapseAnnos.setdefault('dateAnnotations', {})[key] = [to_unix_epoch_time(elem) for elem in elements]
            ## TODO: support blob annotations
            # elif all((isinstance(elem, ???) for elem in elements)):
            #     synapseAnnos.setdefault('blobAnnotations', {})[key] = [???(elem) for elem in elements]
            else:
                synapseAnnos.setdefault('stringAnnotations', {})[key] = [str(elem) for elem in elements]
    return synapseAnnos
def to_submission_status_annotations(annotations, is_private=True):
    """
    Converts a normal dictionary to the format used to annotate submission
    statuses, which is different from the format used to annotate entities.

    :param annotations: A normal Python dictionary whose values are strings, floats, ints or doubles

    :param isPrivate: Set privacy on all annotations at once. These can be set individually using :py:func:`set_privacy`.

    Example::

        from synapseclient.annotations import to_submission_status_annotations, from_submission_status_annotations
        from datetime import datetime as Datetime

        ## create a submission and get its status
        submission = syn.submit(evaluation, 'syn11111111')
        submission_status = syn.getSubmissionStatus(submission)

        ## add annotations
        submission_status.annotations = {'foo':'bar', 'shoe_size':12, 'IQ':12, 'timestamp':Datetime.now()}

        ## convert annotations
        submission_status.annotations = to_submission_status_annotations(submission_status.annotations)
        submission_status = syn.store(submission_status)


    Synapse categorizes these annotations by: stringAnnos, doubleAnnos,
    longAnnos. If date or blob annotations are supported, they are not
    `documented <http://rest.synapse.org/org/sagebionetworks/repo/model/annotation/Annotations.html>`_
    """
    if is_submission_status_annotations(annotations):
        return annotations
    synapseAnnos = {}
    for key, value in annotations.iteritems():
        if key in ['objectId', 'scopeId', 'stringAnnos','longAnnos','doubleAnnos']:
            synapseAnnos[key] = value
        elif isinstance(value, bool):
            synapseAnnos.setdefault('stringAnnos', []).append({ 'key':key, 'value':unicode(value).lower(), 'isPrivate':is_private })
        elif isinstance(value, int) or isinstance(value, long):
            synapseAnnos.setdefault('longAnnos', []).append({ 'key':key, 'value':value, 'isPrivate':is_private })
        elif isinstance(value, float):
            synapseAnnos.setdefault('doubleAnnos', []).append({ 'key':key, 'value':value, 'isPrivate':is_private })
        elif isinstance(value, basestring):
            synapseAnnos.setdefault('stringAnnos', []).append({ 'key':key, 'value':value, 'isPrivate':is_private })
        elif _is_date(value):
            synapseAnnos.setdefault('longAnnos', []).append({ 'key':key, 'value':to_unix_epoch_time(value), 'isPrivate':is_private })
        else:
            synapseAnnos.setdefault('stringAnnos', []).append({ 'key':key, 'value':unicode(value), 'isPrivate':is_private })
    return synapseAnnos