'When the session is created it\'s type (client/server) is determined from the beginning.
socket argument is the pre-created socket-like object.
It must have the following methods: send, recv, fileno, close.
owner is the \'master\' instance that have Dispatcher plugged into it and generally
will take care about all session events.
xmlns is the stream namespace that will be used. Client must set this argument
If server sets this argument than stream will be dropped if opened with some another namespace.
peer is the name of peer instance. This is the flag that differentiates client session from
server session. Client must set it to the name of the server that will be connected, server must
leave this argument alone.'

def __init__(self, socket, owner, xmlns=None, peer=None):

    self.xmlns = xmlns
    if peer:
        self.TYP = 'client'
        self.peer = peer
        self._socket_state = SOCKET_UNCONNECTED
    else:
        self.TYP = 'server'
        self.peer = None
        self._socket_state = SOCKET_ALIVE
    self._sock = socket
    self._send = socket.send
    self._recv = socket.recv
    self.fileno = socket.fileno
    self._registered = 0
    self.Dispatcher = owner.Dispatcher
    self.DBG_LINE = 'session'
    self.DEBUG = owner.Dispatcher.DEBUG
    self._expected = {}
    self._owner = owner
    if (self.TYP == 'server'):
        self.ID = `random.random()`[2:]
    else:
        self.ID = None
    self.sendbuffer = ''
    self._stream_pos_queued = None
    self._stream_pos_sent = 0
    self.deliver_key_queue = []
    self.deliver_queue_map = {}
    self.stanza_queue = []
    self._session_state = SESSION_NOT_AUTHED
    self.waiting_features = []
    for feature in [NS_TLS, NS_SASL, NS_BIND, NS_SESSION]:
        if (feature in owner.features):
            self.waiting_features.append(feature)
    self.features = []
    self.feature_in_process = None
    self.slave_session = None
    self.StartStream()
