'Implements `.HTTPConnection.write_headers`.'

def write_headers(self, start_line, headers, chunk=None, callback=None):

    lines = []
    if self.is_client:
        self._request_start_line = start_line
        lines.append(utf8(('%s    %s    HTTP/1.1' % (start_line[0], start_line[1]))))
        self._chunking_output = ((start_line.method in ('POST', 'PUT', 'PATCH')) and ('Content-Length' not in headers) and ('Transfer-Encoding' not in headers))
    else:
        self._response_start_line = start_line
        lines.append(utf8(('HTTP/1.1    %d    %s' % (start_line[1], start_line[2]))))
        self._chunking_output = ((self._request_start_line.version == 'HTTP/1.1') and (start_line.code not in (204, 304)) and ('Content-Length' not in headers) and ('Transfer-Encoding' not in headers))
        if ((self._request_start_line.version == 'HTTP/1.0') and (self._request_headers.get('Connection', '').lower() == 'keep-alive')):
            headers['Connection'] = 'Keep-Alive'
    if self._chunking_output:
        headers['Transfer-Encoding'] = 'chunked'
    if ((not self.is_client) and ((self._request_start_line.method == 'HEAD') or (start_line.code == 304))):
        self._expected_content_remaining = 0
    elif ('Content-Length' in headers):
        self._expected_content_remaining = int(headers['Content-Length'])
    else:
        self._expected_content_remaining = None
    header_lines = (((native_str(n) + ':    ') + native_str(v)) for (n, v) in headers.get_all())
    if PY3:
        lines.extend((l.encode('latin1') for l in header_lines))
    else:
        lines.extend(header_lines)
    for line in lines:
        if ('\n' in line):
            raise ValueError(('Newline    in    header:    ' + repr(line)))
    future = None
    if self.stream.closed():
        future = self._write_future = Future()
        future.set_exception(iostream.StreamClosedError())
        future.exception()
    else:
        if (callback is not None):
            self._write_callback = stack_context.wrap(callback)
        else:
            future = self._write_future = Future()
        data = ('\r\n'.join(lines) + '\r\n\r\n')
        if chunk:
            data += self._format_chunk(chunk)
        self._pending_write = self.stream.write(data)
        self._pending_write.add_done_callback(self._on_write_complete)
    return future
