<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def ssl_wrap_socket( socket: socket.socket, ssl_options: Union[Dict[str, Any], ssl.SSLContext], server_hostname: str = None, **kwargs: Any ) -> ssl.SSLSocket: """Returns an ``ssl.SSLSocket`` wrapping the given socket. ``ssl_options`` may be either an `ssl.SSLContext` object or a dictionary (as accepted by `ssl_options_to_context`). Additional keyword arguments are passed to ``wrap_socket`` (either the `~ssl.SSLContext` method or the `ssl` module function as appropriate). """

    context = ssl_options_to_context(ssl_options)
    if ssl.HAS_SNI:
        # In python 3.4, wrap_socket only accepts the server_hostname
        # argument if HAS_SNI is true.
        # TODO: add a unittest (python added server-side SNI support in 3.4)
        # In the meantime it can be manually tested with
        # python3 -m tornado.httpclient https://sni.velox.ch
        return context.wrap_socket(socket, server_hostname=server_hostname, **kwargs)
    else:
        return context.wrap_socket(socket, **kwargs)