old_contents: /*
   * Copyright (c) 2012 Mathieu Turcotte
   * Licensed under the MIT license.
   */
  
  var events = require('events');
  var util = require('util');
  
  /**
   * Backoff driver.
   * @param backoffStrategy Backoff delay generator/strategy.
   * @constructor
   */
  function Backoff(backoffStrategy) {
      events.EventEmitter.call(this);
  
      this.backoffStrategy_ = backoffStrategy;
      this.maxNumberOfRetry_ = -1;
      this.backoffNumber_ = 0;
      this.backoffDelay_ = 0;
      this.timeoutID_ = -1;
  
      this.handlers = {
          backoff: this.onBackoff_.bind(this)
      };
  }
  util.inherits(Backoff, events.EventEmitter);
  
  /**
   * Sets a limit, greater than 0, on the maximum number of backoffs. A 'fail'
   * event will be emitted when the limit is reached.
   * @param maxNumberOfRetry The maximum number of backoffs.
   */
  Backoff.prototype.failAfter = function(maxNumberOfRetry) {
      if (maxNumberOfRetry < 1) {
          throw new Error('Maximum number of retry must be greater than 0. ' +
                          'Actual: ' + maxNumberOfRetry);
      }
  
      this.maxNumberOfRetry_ = maxNumberOfRetry;
  };
  
  /**
   * Starts a backoff operation.
   * @param err Optional paramater to let listeners know why the backoff
   *     operation what started.
   */
  Backoff.prototype.backoff = function(err) {
      if (this.timeoutID_ !== -1) {
          throw new Error('Backoff in progress.');
      }
  
      if (this.backoffNumber_ === this.maxNumberOfRetry_) {
          this.emit('fail', err);
          this.reset();
      } else {
          this.backoffDelay_ = this.backoffStrategy_.next();
          this.timeoutID_ = setTimeout(this.handlers.backoff, this.backoffDelay_);
          this.emit('backoff', this.backoffNumber_, this.backoffDelay_, err);
      }
  };
  
  /**
   * Backoff completion handler.
   * @private
   */
  Backoff.prototype.onBackoff_ = function() {
      this.timeoutID_ = -1;
      this.emit('ready', this.backoffNumber_, this.backoffDelay_);
      this.backoffNumber_++;
  };
  
  /**
   * Stops any backoff operation and resets the backoff
   * delay to its inital value.
   */
  Backoff.prototype.reset = function() {
      this.backoffNumber_ = 0;
      this.backoffStrategy_.reset();
      clearTimeout(this.timeoutID_);
      this.timeoutID_ = -1;
  };
  
  module.exports = Backoff;
  
new_contents: /*
   * Copyright (c) 2012 Mathieu Turcotte
   * Licensed under the MIT license.
   */
  
  var events = require('events');
  var util = require('util');
  
  /**
   * Backoff driver.
   * @param backoffStrategy Backoff delay generator/strategy.
   * @constructor
   */
  function Backoff(backoffStrategy) {
      events.EventEmitter.call(this);
  
      this.backoffStrategy_ = backoffStrategy;
      this.maxNumberOfRetry_ = -1;
      this.backoffNumber_ = 0;
      this.backoffDelay_ = 0;
      this.timeoutID_ = -1;
  
      this.handlers = {
          backoff: this.onBackoff_.bind(this)
      };
  }
  util.inherits(Backoff, events.EventEmitter);
  
  /**
   * Sets a limit, greater than 0, on the maximum number of backoffs. A 'fail'
   * event will be emitted when the limit is reached.
   * @param maxNumberOfRetry The maximum number of backoffs.
   */
  Backoff.prototype.failAfter = function(maxNumberOfRetry) {
      if (maxNumberOfRetry < 1) {
          throw new Error('Maximum number of retry must be greater than 0. ' +
                          'Actual: ' + maxNumberOfRetry);
      }
  
      this.maxNumberOfRetry_ = maxNumberOfRetry;
  };
  
  /**
   * Starts a backoff operation.
   * @param err Optional paramater to let the listeners know why the backoff
   *     operation was started.
   */
  Backoff.prototype.backoff = function(err) {
      if (this.timeoutID_ !== -1) {
          throw new Error('Backoff in progress.');
      }
  
      if (this.backoffNumber_ === this.maxNumberOfRetry_) {
          this.emit('fail', err);
          this.reset();
      } else {
          this.backoffDelay_ = this.backoffStrategy_.next();
          this.timeoutID_ = setTimeout(this.handlers.backoff, this.backoffDelay_);
          this.emit('backoff', this.backoffNumber_, this.backoffDelay_, err);
      }
  };
  
  /**
   * Handles the backoff timeout completion.
   * @private
   */
  Backoff.prototype.onBackoff_ = function() {
      this.timeoutID_ = -1;
      this.emit('ready', this.backoffNumber_, this.backoffDelay_);
      this.backoffNumber_++;
  };
  
  /**
   * Stops any backoff operation and resets the backoff delay to its inital
   * value.
   */
  Backoff.prototype.reset = function() {
      this.backoffNumber_ = 0;
      this.backoffStrategy_.reset();
      clearTimeout(this.timeoutID_);
      this.timeoutID_ = -1;
  };
  
  module.exports = Backoff;
  
subject: Update comments.