<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _reconstruct(keyvals, dialect, keep_order=False, sort_attribute_values=False):
 """ Reconstructs the original attributes string according to the dialect. Parameters ========== keyvals : dict Attributes from a GFF/GTF feature dialect : dict Dialect containing info on how to reconstruct a string version of the attributes keep_order : bool If True, then perform sorting of attribute keys to ensure they are in the same order as those provided in the original file. Default is False, which saves time especially on large data sets. sort_attribute_values : bool If True, then sort values to ensure they will always be in the same order. Mostly only useful for testing; default is False. """

    if not dialect:
        raise AttributeStringError()
    if not keyvals:
        return ""
    parts = []

    # Re-encode when reconstructing attributes
    if constants.ignore_url_escape_characters or dialect['fmt'] != 'gff3':
        attributes = keyvals
    else:
        attributes = {}
        for k, v in keyvals.items():
            attributes[k] = []
            for i in v:
                attributes[k].append(''.join([quoter[j] for j in i]))

    # May need to split multiple values into multiple key/val pairs
    if dialect['repeated keys']:
        items = []
        for key, val in attributes.items():
            if len(val) > 1:
                for v in val:
                    items.append((key, [v]))
            else:
                items.append((key, val))
    else:
        items = list(attributes.items())

    def sort_key(x):
        # sort keys by their order in the dialect; anything not in there will
        # be in arbitrary order at the end.
        try:
            return dialect['order'].index(x[0])
        except ValueError:
            return 1e6

    if keep_order:
        items.sort(key=sort_key)

    for key, val in items:

        # Multival sep is usually a comma:
        if val:
            if sort_attribute_values:
                val = sorted(val)

            val_str = dialect['multival separator'].join(val)

            if val_str:

                # Surround with quotes if needed
                if dialect['quoted GFF2 values']:
                    val_str = '"%s"' % val_str

                # Typically "=" for GFF3 or " " otherwise
                part = dialect['keyval separator'].join([key, val_str])
        else:
            if dialect['fmt'] == 'gtf':
                part = dialect['keyval separator'].join([key, '""'])
            else:
                part = key
        parts.append(part)

    # Typically ";" or "; "
    parts_str = dialect['field separator'].join(parts)

    # Sometimes need to add this
    if dialect['trailing semicolon']:
        parts_str += ';'

    return parts_str