text: /**
   * This is the closure class for use in expressInterest to re express with exponential falloff.
   * Copyright (C) 2015 Regents of the University of California.
   * @author: Jeff Thompson <jefft0@remap.ucla.edu>
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   * A copy of the GNU Lesser General Public License is in the file COPYING.
   */
  
  /**
   * An ExponentialReExpress is used by onTimeout to express the interest again
   * with double the interestLifetime. See ExponentialReExpress.makeOnTimeout,
   * which you should call instead of the private constructor.
   * Create a new ExponentialReExpressClosure where upcall responds to UPCALL_INTEREST_TIMED_OUT
   *   by expressing the interest again with double the interestLifetime. If the interesLifetime goes
   *   over maxInterestLifetime, then call callerClosure.upcall with UPCALL_INTEREST_TIMED_OUT.
   * When upcall is not UPCALL_INTEREST_TIMED_OUT, just call callerClosure.upcall.
   */
  var ExponentialReExpress = function ExponentialReExpress
    (face, onData, onTimeout, settings)
  {
    settings = (settings || {});
    this.face = face;
    this.callerOnData = onData;
    this.callerOnTimeout = onTimeout;
  
    this.maxInterestLifetime = (settings.maxInterestLifetime || 16000);
  };
  
  exports.ExponentialReExpress = ExponentialReExpress;
  
  /**
   * Return a callback to use in expressInterest for onTimeout which will express
   * the interest again with double the interestLifetime. If the interesLifetime
   * goes over maxInterestLifetime (see settings below), then call the provided
   * onTimeout. If a Data packet is received, this calls the provided onData.
   * Use it like this:
   *   var onData = function() { ... };
   *   var onTimeout = function() { ... };
   *   face.expressInterest
   *     (interest, onData,
   *      ExponentialReExpress.makeOnTimeout(face, onData, onTimeout));
   * @param {Face} face This calls face.expressInterest.
   * @param {function} onData When a matching data packet is received, this calls
   * onData(interest, data) where interest is the interest given to
   * expressInterest and data is the received Data object. This is normally the
   * same onData you initially passed to expressInterest.
   * @param {function} onTimeout If the interesLifetime goes over
   * maxInterestLifetime, this calls onTimeout(interest).
   * @param {Object} settings (optional) If not null, an associative array with
   * the following defaults:
   * {
   *   maxInterestLifetime: 16000 // milliseconds
   * }
   * @returns {function} The onTimeout callback to pass to expressInterest.
   */
  ExponentialReExpress.makeOnTimeout = function(face, onData, onTimeout, settings)
  {
    var reExpress = new ExponentialReExpress(face, onData, onTimeout, settings);
    return function(interest) { reExpress.onTimeout(interest); };
  };
  
  ExponentialReExpress.prototype.onTimeout = function(interest)
  {
    var interestLifetime = interest.getInterestLifetimeMilliseconds();
    if (interestLifetime == null)
      // Can't re-express.
      return this.callerOnTimeout(interest);
  
    var nextInterestLifetime = interestLifetime * 2;
    if (nextInterestLifetime > this.maxInterestLifetime)
      return this.callerOnTimeout(interest);
  
    var nextInterest = interest.clone();
    nextInterest.setInterestLifetimeMilliseconds(nextInterestLifetime);
    var thisObject = this;
    this.face.expressInterest
      (nextInterest, this.callerOnData,
       function(localInterest) { thisObject.onTimeout(localInterest); });
  };
  