docs: function POP3Client(port, host, options) {
  
  	if (options === undefined) options = {};
  
  	// Optional constructor arguments
  	var enabletls = options.enabletls !== undefined ? options.enabletls: false;
  	var ignoretlserrs = options.ignoretlserrs !== undefined ? options.ignoretlserrs: false;
  	var debug = options.debug || false;
  	
  	var tlsDirectOpts = options.tlsopts !== undefined ? options.tlsopts: {};
  
  	// Private variables follow
  	var self = this;
  	var response = null;
  	var checkResp = true;
  	var bufferedData = "";
  	var state = 0;
  	var locked = false;
  	var multiline = false;
  	var socket = null;
  	var tlssock = null;
  	var callback = function(resp, data) {
  
  		if (resp === false) {
  
  			locked = false;
  			callback = function() {};
  			self.emit("connect", false, data);
  
  		} else {
  
  			// Checking for APOP support
  			var banner = data.trim();
  			var bannerComponents = banner.split(" ");
  
  			for(var i=0; i < bannerComponents.length; i++) {
  
  				if (bannerComponents[i].indexOf("@") > 0) {
  
  					self.data["apop"] = true;
  					self.data["apop-timestamp"] = bannerComponents[i];
  					break;
  
  				}
  			}
  
  			state = 1;
  			self.data["banner"] = banner;
  			self.emit("connect", true, data);
  
  		}
  	};
  
  	// Public variables follow
  	this.data = {
  
  		host: host,
  		port: port,
  		banner: "",
  		stls: false,
  		apop: false,
  		username: "",
  		tls: enabletls,
  		ignoretlserrs: ignoretlserrs
  
  	};
  
  	// Privileged methods follow
  	this.setCallback = function(cb) { callback = cb; };
  	this.getCallback = function() { return callback };
  	this.setState = function(val) { state = val; };
  	this.getState = function() { return state; };
  	this.setLocked = function(val) { locked = val; };
  	this.getLocked = function() { return locked; };
  	this.setMultiline = function(val) { multiline = val; };
  	this.getMultiline = function() { return multiline; };
  
  	// Writes to remote server socket
  	this.write = function(command, argument) {
  
  		var text = command;
  
  		if (argument !== undefined) text = text + " " + argument + "\r\n";
  		else text = text + "\r\n";
  
  		if (debug) console.log("Client: " + util.inspect(text));
  
  		socket.write(text);
  
  	};
  
  	// Kills the socket connection
  	this.end = function() {
  		socket.end();
  	};
  
  	// Upgrades a standard unencrypted TCP connection to use TLS
  	// Liberally copied and modified from https://gist.github.com/848444
  	// starttls() should be a private function, but I can't figure out
  	// how to get a public prototypal method (stls) to talk to private method (starttls)
  	// which references private variables without going through a privileged method
  	this.starttls = function(options) {
  
  		var s = socket;
  		s.removeAllListeners("end");
  		s.removeAllListeners("data");
  		s.removeAllListeners("error");
  		socket=null;
  
  		var sslcontext = require('crypto').createCredentials(options);
  		var pair = tls.createSecurePair(sslcontext, false);
  		var cleartext = pipe(pair);
  
  		pair.on('secure', function() {
  
  			var verifyError = pair.ssl.verifyError();
  			cleartext.authorized = true;
  
  			if (verifyError) {
  
  				cleartext.authorized = false;
  				cleartext.authorizationError = verifyError;
  
  			}
  
  			cleartext.on("data", onData);
  			cleartext.on("error", onError);
  			cleartext.on("end", onEnd);
  			socket=cleartext;
  			(self.getCallback())(cleartext.authorized, cleartext.authorizationError);
  
  		});
  
  		cleartext._controlReleased = true;
  
  		function pipe(pair) {
  
  			pair.encrypted.pipe(s);
  			s.pipe(pair.encrypted);
  
  			pair.fd = s.fd;
  			var cleartext = pair.cleartext;
  			cleartext.socket = s;
  			cleartext.encrypted = pair.encrypted;
  			cleartext.authorized = false;
  
  			function onerror(e) {
  				if (cleartext._controlReleased) cleartext.emit('error', e);
  			}
  
  			function onclose() {
  				s.removeListener('error', onerror);
  				s.removeListener('close', onclose);
  			}
  
  			s.on('error', onerror);
  			s.on('close', onclose);
  			return cleartext;
  
  		}
  	};
  
  	// Private methods follow
  	// Event handlers follow
  	function onData(data) {
  
  		data = data.toString("ascii");
  		bufferedData += data;
  
  		if (debug) console.log("Server: " + util.inspect(data));
  
  		if (checkResp === true) {
  
  			if (bufferedData.substr(0, 3) === "+OK") {
  
  				checkResp = false;
  				response = true;
  
  			} else if (bufferedData.substr(0, 4) === "-ERR") {
  
  				checkResp = false;
  				response = false;
  
  			// The following is only used for SASL
  			} else if (multiline === false) {
  
  				checkResp = false;
  				response = true;
  
  			}
  		}
  
  		if (checkResp === false) {
  
  			if (multiline === true && (response === false || bufferedData.substr(bufferedData.length-5) === "\r\n.\r\n")) {
  
  				// Make a copy to avoid race conditions
  				var responseCopy = response;
  				var bufferedDataCopy = bufferedData;
  
  				response = null;
  				checkResp = true;
  				multiline = false;
  				bufferedData = "";
  
  				callback(responseCopy, bufferedDataCopy);
  
  			} else if (multiline === false) {
  
  				// Make a copy to avoid race conditions
  				var responseCopy = response;
  				var bufferedDataCopy = bufferedData;
  
  				response = null;
  				checkResp = true;
  				multiline = false;
  				bufferedData = "";
  
  				callback(responseCopy, bufferedDataCopy);
  
  			}
  		} 
  	}
  
  	function onError(err) {
  
  		if (err.errno === 111) self.emit("connect", false, err);
  		else self.emit("error", err);
  
  	}
  
  	function onEnd(data) {
  		self.setState(0);
  		socket = null;
  	}
  
  	function onClose() {
  		self.emit("close");
  	}
  
  	// Constructor code follows
  	// Set up EventEmitter constructor function
  	events.EventEmitter.call(this);
  
  	// Remote end socket
  	if (enabletls === true) {
  
  		tlssock = tls.connect({
              host: host,
              port: port,
              rejectUnauthorized: !self.data.ignoretlserrs
          }, function() {
  
              if (tlssock.authorized === false && 
                  self.data["ignoretlserrs"] === false)
                      self.emit("tls-error", tlssock.authorizationError);
  
          }
      );
  
  		socket = tlssock;
  
  	} else socket = new net.createConnection(port, host);
  
  	// Set up event handlers
  	socket.on("data", onData);
  	socket.on("error", onError);
  	socket.on("end", onEnd);
  	socket.on("close", onClose);
  
  }