<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def copy_object(self, bucket_name, object_name, object_source, conditions=None, source_sse=None, sse=None, metadata=None):
 """ Copy a source object on object storage server to a new object. NOTE: Maximum object size supported by this API is 5GB. Examples: :param bucket_name: Bucket of new object. :param object_name: Name of new object. :param object_source: Source object to be copied. :param conditions: :class:`CopyConditions` object. Collection of supported CopyObject conditions. :param metadata: Any user-defined metadata to be copied along with destination object. """

        is_valid_bucket_name(bucket_name)
        is_non_empty_string(object_name)
        is_non_empty_string(object_source)

        headers = {}

        # Preserving the user-defined metadata in headers
        if metadata is not None:
            headers = amzprefix_user_metadata(metadata)
            headers["x-amz-metadata-directive"] = "REPLACE"

        if conditions:
            for k, v in conditions.items():
                headers[k] = v

        # Source argument to copy_object can only be of type copy_SSE_C
        if source_sse:
            is_valid_source_sse_object(source_sse)
            headers.update(source_sse.marshal())

        #Destination argument to copy_object cannot be of type copy_SSE_C
        if sse:
            is_valid_sse_object(sse)
            headers.update(sse.marshal())

        headers['X-Amz-Copy-Source'] = queryencode(object_source)
        response = self._url_open('PUT',
                                  bucket_name=bucket_name,
                                  object_name=object_name,
                                  headers=headers)

        return parse_copy_object(bucket_name, object_name, response.data)