docs: function TCPConnection(user) {
  	this.user = user;
  
  	// Pick a CM randomly
  	if (!user._cmList || !user._cmList.tcp_servers) {
  		throw new Error("Nothing to connect to: " + (user._cmList ? "no TCP server list" : "no CM list"));
  	}
  
  	let tcpCm = user._cmList.tcp_servers[Math.floor(Math.random() * user._cmList.tcp_servers.length)];
  	user.emit('debug', 'Connecting to TCP CM: ' + tcpCm);
  	let cmParts = tcpCm.split(':');
  	let cmHost = cmParts[0];
  	let cmPort = parseInt(cmParts[1], 10);
  
  	if (user.options.httpProxy) {
  		let url = URL.parse(user.options.httpProxy);
  		url.method = 'CONNECT';
  		url.path = tcpCm;
  		url.localAddress = user.options.localAddress;
  		url.localPort = user.options.localPort;
  		if (url.auth) {
  			url.headers = {"Proxy-Authorization": "Basic " + (new Buffer(url.auth, 'utf8')).toString('base64')};
  			delete url.auth;
  		}
  
  		let connectionEstablished = false;
  		let req = HTTP.request(url);
  		req.end();
  		req.setTimeout(user.options.proxyTimeout || 5000);
  		req.on('connect', (res, socket) => {
  			if (connectionEstablished) {
  				// somehow we're already connected, or we aborted
  				socket.end();
  				return;
  			}
  
  			connectionEstablished = true;
  			req.setTimeout(0); // disable timeout
  
  			if (res.statusCode != 200) {
  				this.user.emit('error', new Error('HTTP CONNECT ' + res.statusCode + ' ' + res.statusMessage));
  				return;
  			}
  
  			this.stream = socket;
  			this._setupStream();
  		});
  
  		req.on('timeout', () => {
  			connectionEstablished = true;
  			this.user.emit('error', new Error('Proxy connection timed out'));
  		});
  
  		req.on('error', (err) => {
  			connectionEstablished = true;
  			this.user.emit('error', err);
  		});
  	} else {
  		let socket = new Socket();
  		this.stream = socket;
  		this._setupStream();
  
  		socket.connect({
  			"port": cmPort,
  			"host": cmHost,
  			"localAddress": user.options.localAddress,
  			"localPort": user.options.localPort
  		});
  		
  		this.stream.setTimeout(this.user._connectTimeout);
  	}
  }