text: var util       = require('util'),
      HttpParser = require('./http_parser'),
      Base       = require('./base'),
      Draft75    = require('./draft75'),
      Draft76    = require('./draft76'),
      Hybi       = require('./hybi');
  
  var Server = function(options) {
    Base.call(this, null, null, options);
    this._http = new HttpParser('request');
  };
  util.inherits(Server, Base);
  
  var instance = {
    EVENTS: ['open', 'message', 'error', 'close'],
  
    _bindEventListeners: function() {
      this.messages.on('error', function() {});
      this.on('error', function() {});
    },
  
    parse: function(data) {
      if (this._delegate) return this._delegate.parse(data);
  
      this._http.parse(data);
      if (!this._http.isComplete()) return;
  
      this.method  = this._http.method;
      this.url     = this._http.url;
      this.headers = this._http.headers;
      this.body    = this._http.body;
  
      var self = this;
      this._delegate = Server.http(this, this._options);
      this._delegate.messages = this.messages;
      this._delegate.io = this.io;
  
      this._delegate.on('open', function() { self._open() });
      this.EVENTS.forEach(function(event) {
        this._delegate.on(event, function(e) { self.emit(event, e) });
      }, this);
  
      this.parse(this._http.body);
      this.emit('connect', new Base.ConnectEvent());
    },
  
    _open: function() {
      this.__queue.forEach(function(msg) {
        this._delegate[msg[0]].apply(this._delegate, msg[1]);
      }, this);
      this.__queue = [];
    }
  };
  
  ['setHeader', 'start', 'state', 'frame', 'text', 'binary', 'ping', 'close'].forEach(function(method) {
    instance[method] = function() {
      if (this._delegate) {
        return this._delegate[method].apply(this._delegate, arguments);
      } else {
        this.__queue.push([method, arguments]);
        return true;
      }
    };
  });
  
  for (var key in instance)
    Server.prototype[key] = instance[key];
  
  Server.isSecureRequest = function(request) {
    if (request.connection && request.connection.authorized !== undefined) return true;
    if (request.socket && request.socket.secure) return true;
  
    var headers = request.headers;
    if (!headers) return false;
    if (headers['https'] === 'on') return true;
    if (headers['x-forwarded-ssl'] === 'on') return true;
    if (headers['x-forwarded-scheme'] === 'https') return true;
    if (headers['x-forwarded-proto'] === 'https') return true;
  
    return false;
  };
  
  Server.determineUrl = function(request) {
    var scheme = this.isSecureRequest(request) ? 'wss:' : 'ws:';
    return scheme + '//' + request.headers.host + request.url;
  };
  
  Server.http = function(request, options) {
    options = options || {};
    if (options.requireMasking === undefined) options.requireMasking = true;
  
    var headers = request.headers,
        url     = this.determineUrl(request);
  
    if (headers['sec-websocket-version'])
      return new Hybi(request, url, options);
    else if (headers['sec-websocket-key1'])
      return new Draft76(request, url, options);
    else
      return new Draft75(request, url, options);
  };
  
  module.exports = Server;
  
  