docs: function Casper(options) {
      "use strict";
      /*jshint maxstatements:40*/
      // init & checks
      if (!(this instanceof Casper)) {
          return new Casper(options);
      }
      // default options
      this.defaults = {
          clientScripts:       [],
          colorizerType:       'Colorizer',
          exitOnError:         true,
          logLevel:            "error",
          httpStatusHandlers:  {},
          safeLogs:            true,
          onAlert:             null,
          onDie:               null,
          onError:             null,
          onLoadError:         null,
          onPageInitialized:   null,
          onResourceReceived:  null,
          onResourceRequested: null,
          onRunComplete:       function _onRunComplete() {
              this.exit();
          },
          onStepComplete:      null,
          onStepTimeout:       function _onStepTimeout(timeout, stepNum) {
              this.die("Maximum step execution timeout exceeded for step " + stepNum);
          },
          onTimeout:           function _onTimeout(timeout) {
              this.die(f("Script timeout of %dms reached, exiting.", timeout));
          },
          onWaitTimeout:       function _onWaitTimeout(timeout) {
              this.die(f("Wait timeout of %dms expired, exiting.", timeout));
          },
          page:                null,
          pageSettings:        {
              localToRemoteUrlAccessEnabled: true,
              userAgent:                     defaultUserAgent
          },
          remoteScripts:       [],
          stepTimeout:         null,
          timeout:             null,
          verbose:             false,
          retryTimeout:        20,
          waitTimeout:         5000,
          clipRect : null,
          viewportSize : null,
      };
      // options
      this.options = utils.mergeObjects(this.defaults, options);
      // factories
      this.cli = phantom.casperArgs;
      this.options.logLevel = this.cli.get('log-level', this.options.logLevel);
      this.options.verbose = this.cli.get('direct', this.options.verbose);
      this.colorizer = this.getColorizer();
      this.mouse = mouse.create(this);
      this.popups = pagestack.create();
      // properties
      this.checker = null;
      this.currentResponse = {};
      this.currentUrl = 'about:blank';
      this.currentHTTPStatus = null;
      this.history = [];
      this.loadInProgress = false;
      this.navigationRequested = false;
      this.browserInitializing = false;
      this.logFormats = {};
      this.logLevels = ["debug", "info", "warning", "error"];
      this.logStyles = {
          debug:   'INFO',
          info:    'PARAMETER',
          warning: 'COMMENT',
          error:   'ERROR'
      };
      this.page = null;
      this.pendingWait = false;
      this.requestUrl = 'about:blank';
      this.resources = [];
      this.result = {
          log:    [],
          status: "success",
          time:   0
      };
      this.started = false;
      this.step = -1;
      this.steps = [];
      this.waiters = [];
      this._test = undefined;
      this.__defineGetter__('test', function() {
          if (!phantom.casperTest) {
              throw new CasperError('casper.test property is only available using the `casperjs test` command');
          }
          if (!utils.isObject(this._test)) {
              this._test = tester.create(this);
          }
          return this._test;
      });
  
      // init phantomjs error handler
      this.initErrorHandler();
  
      this.on('error', function(msg, backtrace) {
          if (/^(Assertion|Termination|TimedOut)Error/.test(msg)) {
              return;
          }
          var c = this.getColorizer();
          var match = /^(.*): __mod_error(.*):: (.*)/.exec(msg);
          var notices = [];
          if (match && match.length === 4) {
              notices.push('  in module ' + match[2]);
              msg = match[3];
          }
          console.error(c.colorize(msg, 'RED_BAR', 80));
          notices.forEach(function(notice) {
              console.error(c.colorize(notice, 'COMMENT'));
          });
          backtrace.forEach(function(item) {
              var message = fs.absolute(item.file) + ":" + c.colorize(item.line, "COMMENT");
              if (item['function']) {
                  message += " in " + c.colorize(item['function'], "PARAMETER");
              }
              console.error("  " + message);
          });
      });
  
      // deprecated feature event handler
      this.on('deprecated', function onDeprecated(message) {
          this.warn('[deprecated] ' + message);
      });
  
      // dispatching an event when instance has been constructed
      this.emit('init');
  }