text:
/*!
 * Module Dependencies.
 */

var Model = require('./model');
var runtime = require('../runtime');
var assert = require('assert');
var async = require('async');

/**
 * Extends Model with basic query and CRUD support.
 *
 * **Change Event**
 *
 * Listen for model changes using the `change` event.
 *
 * ```js
 * MyPersistedModel.on('changed', function(obj) {
 *    console.log(obj) // => the changed model
 * });
 * ```
 *
 * @class PersistedModel
 * @param {Object} data
 * @param {Number} data.id The default id property
 */

var PersistedModel = module.exports = Model.extend('PersistedModel');

/*!
 * Setup the `PersistedModel` constructor.
 */

PersistedModel.setup = function setupPersistedModel() {
  // call Model.setup first
  Model.setup.call(this);

  var PersistedModel = this;

  // enable change tracking (usually for replication)
  if(this.settings.trackChanges) {
    PersistedModel._defineChangeModel();
    PersistedModel.once('dataSourceAttached', function() {
      PersistedModel.enableChangeTracking();
    });
  }

  PersistedModel.setupRemoting();
}

/*!
 * Throw an error telling the user that the method is not available and why.
 */

function throwNotAttached(modelName, methodName) {
  throw new Error(
      'Cannot call ' + modelName + '.'+ methodName + '().'
    + ' The ' + methodName + ' method has not been setup.'
    + ' The PersistedModel has not been correctly attached to a DataSource!'
  );
}

/*!
 * Convert null callbacks to 404 error objects.
 * @param  {HttpContext} ctx
 * @param  {Function} cb
 */

function convertNullToNotFoundError(ctx, cb) {
  if (ctx.result !== null) return cb();

  var modelName = ctx.method.sharedClass.name;
  var id = ctx.getArgByName('id');
  var msg = 'Unknown "' + modelName + '" id "' + id + '".';
  var error = new Error(msg);
  error.statusCode = error.status = 404;
  cb(error);
}

/**
 * Create new instance of Model class, saved in database
 *
 * @param data [optional]
 * @param callback(err, obj)
 * callback called with arguments:
 *
 *   - err (null or Error)
 *   - instance (null or Model)
 */

PersistedModel.create = function (data, callback) {
  throwNotAttached(this.modelName, 'create');
};

/**
 * Update or insert a model instance
 * @param {Object} data The model instance data
 * @param {Function} [callback] The callback function
 */

PersistedModel.upsert = PersistedModel.updateOrCreate = function upsert(data, callback) {
  throwNotAttached(this.modelName, 'upsert');
};

/**
 * Find one record, same as `find`, limited by 1 and return object, not collection,
 * if not found, create using data provided as second argument
 *
 * @param {Object} query - search conditions: {where: {test: 'me'}}.
 * @param {Object} data - object to create.
 * @param {Function} cb - callback called with (err, instance)
 */

PersistedModel.findOrCreate = function findOrCreate(query, data, callback) {
  throwNotAttached(this.modelName, 'findOrCreate');
};

PersistedModel.findOrCreate._delegate = true;

/**
 * Check whether a model instance exists in database
 *
 * @param {id} id - identifier of object (primary key value)
 * @param {Function} cb - callback called with (err, exists: Bool)
 */

PersistedModel.exists = function exists(id, cb) {
  throwNotAttached(this.modelName, 'exists');
};

/**
 * Find object by id
 *
 * @param {*} id - primary key value
 * @param {Function} cb - callback called with (err, instance)
 */

PersistedModel.findById = function find(id, cb) {
  throwNotAttached(this.modelName, 'findById');
};

/**
 * Find all instances of Model, matched by query
 * make sure you have marked as `index: true` fields for filter or sort
 *
 * @param {Object} params (optional)
 *
 * - where: Object `{ key: val, key2: {gt: 'val2'}}`
 * - include: String, Object or Array. See PersistedModel.include documentation.
 * - order: String
 * - limit: Number
 * - skip: Number
 *
 * @param {Function} callback (required) called with arguments:
 *
 * - err (null or Error)
 * - Array of instances
 */

PersistedModel.find = function find(params, cb) {
  throwNotAttached(this.modelName, 'find');
};

/**
 * Find one record, same as `all`, limited by 1 and return object, not collection
 *
 * @param {Object} params - search conditions: {where: {test: 'me'}}
 * @param {Function} cb - callback called with (err, instance)
 */

PersistedModel.findOne = function findOne(params, cb) {
  throwNotAttached(this.modelName, 'findOne');
};

/**
 * Destroy all matching records
 * @param {Object} [where] An object that defines the criteria
 * @param {Function} [cb] - callback called with (err)
 */

PersistedModel.remove =
PersistedModel.deleteAll =
PersistedModel.destroyAll = function destroyAll(where, cb) {
  throwNotAttached(this.modelName, 'destroyAll');
};

/**
 * Update multiple instances that match the where clause
 *
 * Example:
 *
 *```js
 * Employee.update({managerId: 'x001'}, {managerId: 'x002'}, function(err) {
 *     ...
 * });
 * ```
 *
 * @param {Object} [where] Search conditions (optional)
 * @param {Object} data Changes to be made
 * @param {Function} cb Callback, called with (err, count)
 */
PersistedModel.update =
  PersistedModel.updateAll = function updateAll(where, data, cb) {
    throwNotAttached(this.modelName, 'updateAll');
  };

/**
 * Destroy a record by id
 * @param {*} id The id value
 * @param {Function} cb - callback called with (err)
 */

PersistedModel.removeById =
PersistedModel.deleteById =
PersistedModel.destroyById = function deleteById(id, cb) {
  throwNotAttached(this.modelName, 'deleteById');
};

/**
 * Return count of matched records
 *
 * @param {Object} where - search conditions (optional)
 * @param {Function} cb - callback, called with (err, count)
 */

PersistedModel.count = function (where, cb) {
  throwNotAttached(this.modelName, 'count');
};

/**
 * Save instance. When instance haven't id, create method called instead.
 * Triggers: validate, save, update | create
 * @param options {validate: true, throws: false} [optional]
 * @param callback(err, obj)
 */

PersistedModel.prototype.save = function (options, callback) {
  var Model = this.constructor;

  if (typeof options == 'function') {
    callback = options;
    options = {};
  }

  callback = callback || function () {
  };
  options = options || {};

  if (!('validate' in options)) {
    options.validate = true;
  }
  if (!('throws' in options)) {
    options.throws = false;
  }

  var inst = this;
  var data = inst.toObject(true);
  var id = this.getId();

  if (!id) {
    return Model.create(this, callback);
  }

  // validate first
  if (!options.validate) {
    return save();
  }

  inst.isValid(function (valid) {
    if (valid) {
      save();
    } else {
      var err = new ValidationError(inst);
      // throws option is dangerous for async usage
      if (options.throws) {
        throw err;
      }
      callback(err, inst);
    }
  });

  // then save
  function save() {
    inst.trigger('save', function (saveDone) {
      inst.trigger('update', function (updateDone) {
        Model.upsert(inst, function(err) {
          inst._initProperties(data);
          updateDone.call(inst, function () {
            saveDone.call(inst, function () {
              callback(err, inst);
            });
          });
        });
      }, data);
    }, data);
  }
};

/**
 * Determine if the data model is new.
 * @returns {Boolean}
 */

PersistedModel.prototype.isNewRecord = function () {
  throwNotAttached(this.constructor.modelName, 'isNewRecord');
};

/**
 * Delete object from persistence
 *
 * @triggers `destroy` hook (async) before and after destroying object
 */

PersistedModel.prototype.remove =
PersistedModel.prototype.delete =
PersistedModel.prototype.destroy = function (cb) {
  throwNotAttached(this.constructor.modelName, 'destroy');
};

PersistedModel.prototype.destroy._delegate = true;

/**
 * Update single attribute
 *
 * equals to `updateAttributes({name: value}, cb)
 *
 * @param {String} name - name of property
 * @param {Mixed} value - value of property
 * @param {Function} callback - callback called with (err, instance)
 */

PersistedModel.prototype.updateAttribute = function updateAttribute(name, value, callback) {
  throwNotAttached(this.constructor.modelName, 'updateAttribute');
};

/**
 * Update set of attributes
 *
 * this method performs validation before updating
 *
 * @trigger `validation`, `save` and `update` hooks
 * @param {Object} data - data to update
 * @param {Function} callback - callback called with (err, instance)
 */

PersistedModel.prototype.updateAttributes = function updateAttributes(data, cb) {
  throwNotAttached(this.modelName, 'updateAttributes');
};

/**
 * Reload object from persistence
 *
 * @requires `id` member of `object` to be able to call `find`
 * @param {Function} callback - called with (err, instance) arguments
 */

PersistedModel.prototype.reload = function reload(callback) {
  throwNotAttached(this.constructor.modelName, 'reload');
};

/**
 * Set the correct `id` property for the `PersistedModel`. If a `Connector` defines
 * a `setId` method it will be used. Otherwise the default lookup is used. You
 * should override this method to handle complex ids.
 *
 * @param {*} val The `id` value. Will be converted to the type the id property
 * specifies.
 */

PersistedModel.prototype.setId = function(val) {
  var ds = this.getDataSource();
  this[this.getIdName()] = val;
}

/**
 * Get the `id` value for the `PersistedModel`.
 *
 * @returns {*} The `id` value
 */

PersistedModel.prototype.getId = function() {
  var data = this.toObject();
  if(!data) return;
  return data[this.getIdName()];
}

/**
 * Get the id property name of the constructor.
 *
 * @returns {String} The `id` property name
 */

PersistedModel.prototype.getIdName = function() {
  return this.constructor.getIdName();
}

/**
 * Get the id property name of the constructor.
 *
 * @returns {String} The `id` property name
 */

PersistedModel.getIdName = function() {
  var Model = this;
  var ds = Model.getDataSource();

  if(ds.idName) {
    return ds.idName(Model.modelName);
  } else {
    return 'id';
  }
}

PersistedModel.setupRemoting = function() {
  var PersistedModel = this;
  var typeName = PersistedModel.modelName;
  var options = PersistedModel.settings;

  function setRemoting(scope, name, options) {
    var fn = scope[name];
    fn._delegate = true;
    options.isStatic = scope === PersistedModel;
    PersistedModel.remoteMethod(name, options);
  }

  setRemoting(PersistedModel, 'create', {
    description: 'Create a new instance of the model and persist it into the data source',
    accepts: {arg: 'data', type: 'object', description: 'Model instance data', http: {source: 'body'}},
    returns: {arg: 'data', type: typeName, root: true},
    http: {verb: 'post', path: '/'}
  });

  setRemoting(PersistedModel, 'upsert', {
    aliases: ['updateOrCreate'],
    description: 'Update an existing model instance or insert a new one into the data source',
    accepts: {arg: 'data', type: 'object', description: 'Model instance data', http: {source: 'body'}},
    returns: {arg: 'data', type: typeName, root: true},
    http: {verb: 'put', path: '/'}
  });

  setRemoting(PersistedModel, 'exists', {
    description: 'Check whether a model instance exists in the data source',
    accepts: {arg: 'id', type: 'any', description: 'Model id', required: true},
    returns: {arg: 'exists', type: 'boolean'},
    http: [
      {verb: 'get', path: '/:id/exists'},
      {verb: 'head', path: '/:id'}
    ],
    rest: {
      // After hook to map exists to 200/404 for HEAD
      after: function(ctx, cb) {
        if(!ctx.result.exists) {
          var modelName = ctx.method.sharedClass.name;
          var id = ctx.getArgByName('id');
          var msg = 'Unknown "' + modelName + '" id "' + id + '".';
          var error = new Error(msg);
          error.statusCode = error.status = 404;
          cb(error);
        } else {
          cb();
        }
      }
    }
  });

  setRemoting(PersistedModel, 'findById', {
    description: 'Find a model instance by id from the data source',
    accepts: {
      arg: 'id', type: 'any', description: 'Model id', required: true,
      http: {source: 'path'}
    },
    returns: {arg: 'data', type: typeName, root: true},
    http: {verb: 'get', path: '/:id'},
    rest: {after: convertNullToNotFoundError}
  });

  setRemoting(PersistedModel, 'find', {
    description: 'Find all instances of the model matched by filter from the data source',
    accepts: {arg: 'filter', type: 'object', description: 'Filter defining fields, where, orderBy, offset, and limit'},
    returns: {arg: 'data', type: [typeName], root: true},
    http: {verb: 'get', path: '/'}
  });

  setRemoting(PersistedModel, 'findOne', {
    description: 'Find first instance of the model matched by filter from the data source',
    accepts: {arg: 'filter', type: 'object', description: 'Filter defining fields, where, orderBy, offset, and limit'},
    returns: {arg: 'data', type: typeName, root: true},
    http: {verb: 'get', path: '/findOne'},
    rest: {after: convertNullToNotFoundError}
  });

  setRemoting(PersistedModel, 'destroyAll', {
    description: 'Delete all matching records',
    accepts: {arg: 'where', type: 'object', description: 'filter.where object'},
    http: {verb: 'del', path: '/'},
    shared: false
  });

  setRemoting(PersistedModel, 'updateAll', {
    aliases: ['update'],
    description: 'Update instances of the model matched by where from the data source',
    accepts: [
      {arg: 'where', type: 'object', http: {source: 'query'},
        description: 'Criteria to match model instances'},
      {arg: 'data', type: 'object', http: {source: 'body'},
        description: 'An object of model property name/value pairs'},
    ],
    http: {verb: 'post', path: '/update'}
  });

  setRemoting(PersistedModel, 'deleteById', {
    aliases: ['destroyById', 'removeById'],
    description: 'Delete a model instance by id from the data source',
    accepts: {arg: 'id', type: 'any', description: 'Model id', required: true,
              http: {source: 'path'}},
    http: {verb: 'del', path: '/:id'}
  });

  setRemoting(PersistedModel, 'count', {
    description: 'Count instances of the model matched by where from the data source',
    accepts: {arg: 'where', type: 'object', description: 'Criteria to match model instances'},
    returns: {arg: 'count', type: 'number'},
    http: {verb: 'get', path: '/count'}
  });

  setRemoting(PersistedModel.prototype, 'updateAttributes', {
    description: 'Update attributes for a model instance and persist it into the data source',
    accepts: {arg: 'data', type: 'object', http: {source: 'body'}, description: 'An object of model property name/value pairs'},
    returns: {arg: 'data', type: typeName, root: true},
    http: {verb: 'put', path: '/'}
  });

  if(options.trackChanges) {
    setRemoting(PersistedModel, 'diff', {
      description: 'Get a set of deltas and conflicts since the given checkpoint',
      accepts: [
        {arg: 'since', type: 'number', description: 'Find deltas since this checkpoint'},
        {arg: 'remoteChanges', type: 'array', description: 'an array of change objects',
         http: {source: 'body'}}
      ],
      returns: {arg: 'result', type: 'object', root: true},
      http: {verb: 'post', path: '/diff'}
    });

    setRemoting(PersistedModel, 'changes', {
      description: 'Get the changes to a model since a given checkpoint.'
                 + 'Provide a filter object to reduce the number of results returned.',
      accepts: [
        {arg: 'since', type: 'number', description: 'Only return changes since this checkpoint'},
        {arg: 'filter', type: 'object', description: 'Only include changes that match this filter'}
      ],
      returns: {arg: 'changes', type: 'array', root: true},
      http: {verb: 'get', path: '/changes'}
    });

    setRemoting(PersistedModel, 'checkpoint', {
      description: 'Create a checkpoint.',
      returns: {arg: 'checkpoint', type: 'object', root: true},
      http: {verb: 'post', path: '/checkpoint'}
    });

    setRemoting(PersistedModel, 'currentCheckpoint', {
      description: 'Get the current checkpoint.',
      returns: {arg: 'checkpoint', type: 'object', root: true},
      http: {verb: 'get', path: '/checkpoint'}
    });

    setRemoting(PersistedModel, 'createUpdates', {
      description: 'Create an update list from a delta list',
      accepts: {arg: 'deltas', type: 'array', http: {source: 'body'}},
      returns: {arg: 'updates', type: 'array', root: true},
      http: {verb: 'post', path: '/create-updates'}
    });

    setRemoting(PersistedModel, 'bulkUpdate', {
      description: 'Run multiple updates at once. Note: this is not atomic.',
      accepts: {arg: 'updates', type: 'array'},
      http: {verb: 'post', path: '/bulk-update'}
    });

    setRemoting(PersistedModel, 'rectifyAllChanges', {
      description: 'Rectify all Model changes.',
      http: {verb: 'post', path: '/rectify-all'}
    });

    setRemoting(PersistedModel, 'rectifyChange', {
      description: 'Tell loopback that a change to the model with the given id has occurred.',
      accepts: {arg: 'id', type: 'any', http: {source: 'path'}},
      http: {verb: 'post', path: '/:id/rectify-change'}
    });
  }
}

/**
 * Get a set of deltas and conflicts since the given checkpoint.
 *
 * See `Change.diff()` for details.
 *
 * @param  {Number}   since         Find deltas since this checkpoint
 * @param  {Array}   remoteChanges  An array of change objects
 * @param  {Function} callback
 */

PersistedModel.diff = function(since, remoteChanges, callback) {
  var Change = this.getChangeModel();
  Change.diff(this.modelName, since, remoteChanges, callback);
}

/**
 * Get the changes to a model since a given checkpoint. Provide a filter object
 * to reduce the number of results returned.
 * @param  {Number}   since    Only return changes since this checkpoint
 * @param  {Object}   filter   Only include changes that match this filter
 * (same as `Model.find(filter, ...)`)
 * @callback {Function} callback
 * @param {Error} err
 * @param {Array} changes An array of `Change` objects
 * @end
 */

PersistedModel.changes = function(since, filter, callback) {
  if(typeof since === 'function') {
    filter = {};
    callback = since;
    since = -1;
  }
  if(typeof filter === 'function') {
    callback = filter;
    since = -1;
    filter = {};
  }

  var idName = this.dataSource.idName(this.modelName);
  var Change = this.getChangeModel();
  var model = this;

  filter = filter || {};
  filter.fields = {};
  filter.where = filter.where || {};
  filter.fields[idName] = true;

  // TODO(ritch) this whole thing could be optimized a bit more
  Change.find({
    checkpoint: {gt: since},
    modelName: this.modelName
  }, function(err, changes) {
    if(err) return cb(err);
    var ids = changes.map(function(change) {
      return change.getModelId();
    });
    filter.where[idName] = {inq: ids};
    model.find(filter, function(err, models) {
      if(err) return cb(err);
      var modelIds = models.map(function(m) {
        return m[idName].toString();
      });
      callback(null, changes.filter(function(ch) {
        if(ch.type() === Change.DELETE) return true;
        return modelIds.indexOf(ch.modelId) > -1;
      }));
    });
  });
}

/**
 * Create a checkpoint.
 *
 * @param  {Function} callback
 */

PersistedModel.checkpoint = function(cb) {
  var Checkpoint = this.getChangeModel().getCheckpointModel();
  this.getSourceId(function(err, sourceId) {
    if(err) return cb(err);
    Checkpoint.create({
      sourceId: sourceId
    }, cb);
  });
}

/**
 * Get the current checkpoint id.
 *
 * @callback {Function} callback
 * @param {Error} err
 * @param {Number} currentCheckpointId
 * @end
 */

PersistedModel.currentCheckpoint = function(cb) {
  var Checkpoint = this.getChangeModel().getCheckpointModel();
  Checkpoint.current(cb);
}

/**
 * Replicate changes since the given checkpoint to the given target model.
 *
 * @param  {Number}   [since]        Since this checkpoint
 * @param  {Model}    targetModel  Target this model class
 * @param  {Object} [options]
 * @param {Object} [options.filter] Replicate models that match this filter
 * @callback {Function} [callback]
 * @param {Error} err
 * @param {Conflict[]} conflicts A list of changes that could not be replicated
 * due to conflicts.
 */

PersistedModel.replicate = function(since, targetModel, options, callback) {
  var lastArg = arguments[arguments.length - 1];

  if(typeof lastArg === 'function' && arguments.length > 1) {
    callback = lastArg;
  }

  if(typeof since === 'function' && since.modelName) {
    targetModel = since;
    since = -1;
  }

  options = options || {};

  var sourceModel = this;
  var diff;
  var updates;
  var Change = this.getChangeModel();
  var TargetChange = targetModel.getChangeModel();
  var changeTrackingEnabled = Change && TargetChange;

  assert(
    changeTrackingEnabled,
    'You must enable change tracking before replicating'
  );

  callback = callback || function defaultReplicationCallback(err) {
    if(err) throw err;
  }

  var tasks = [
    getSourceChanges,
    getDiffFromTarget,
    createSourceUpdates,
    bulkUpdate,
    checkpoint
  ];

  async.waterfall(tasks, done);

  function getSourceChanges(cb) {
    sourceModel.changes(since, options.filter, cb);
  }

  function getDiffFromTarget(sourceChanges, cb) {
    targetModel.diff(since, sourceChanges, cb);
  }

  function createSourceUpdates(_diff, cb) {
    diff = _diff;
    diff.conflicts = diff.conflicts || [];
    if(diff && diff.deltas && diff.deltas.length) {
      sourceModel.createUpdates(diff.deltas, cb);
    } else {
      // nothing to replicate
      done();
    }
  }

  function bulkUpdate(updates, cb) {
    targetModel.bulkUpdate(updates, cb);
  }

  function checkpoint() {
    var cb = arguments[arguments.length - 1];
    sourceModel.checkpoint(cb);
  }

  function done(err) {
    if(err) return callback(err);

    var conflicts = diff.conflicts.map(function(change) {
      return new Change.Conflict(
        change.modelId, sourceModel, targetModel
      );
    });

    if(conflicts.length) {
      sourceModel.emit('conflicts', conflicts);
    }

    callback && callback(null, conflicts);
  }
}

/**
 * Create an update list (for `Model.bulkUpdate()`) from a delta list
 * (result of `Change.diff()`).
 *
 * @param  {Array}    deltas
 * @param  {Function} callback
 */

PersistedModel.createUpdates = function(deltas, cb) {
  var Change = this.getChangeModel();
  var updates = [];
  var Model = this;
  var tasks = [];

  deltas.forEach(function(change) {
    var change = new Change(change);
    var type = change.type();
    var update = {type: type, change: change};
    switch(type) {
      case Change.CREATE:
      case Change.UPDATE:
        tasks.push(function(cb) {
          Model.findById(change.modelId, function(err, inst) {
            if(err) return cb(err);
            if(!inst) {
              console.error('missing data for change:', change);
              return cb && cb(new Error('missing data for change: '
                + change.modelId));
            }
            if(inst.toObject) {
              update.data = inst.toObject();
            } else {
              update.data = inst;
            }
            updates.push(update);
            cb();
          });
        });
      break;
      case Change.DELETE:
        updates.push(update);
      break;
    }
  });

  async.parallel(tasks, function(err) {
    if(err) return cb(err);
    cb(null, updates);
  });
}

/**
 * Apply an update list.
 *
 * **Note: this is not atomic**
 *
 * @param  {Array}   updates An updates list (usually from Model.createUpdates())
 * @param  {Function} callback
 */

PersistedModel.bulkUpdate = function(updates, callback) {
  var tasks = [];
  var Model = this;
  var idName = this.dataSource.idName(this.modelName);
  var Change = this.getChangeModel();

  updates.forEach(function(update) {
    switch(update.type) {
      case Change.UPDATE:
      case Change.CREATE:
        // var model = new Model(update.data);
        // tasks.push(model.save.bind(model));
        tasks.push(function(cb) {
          var model = new Model(update.data);
          model.save(cb);
        });
      break;
      case Change.DELETE:
        var data = {};
        data[idName] = update.change.modelId;
        var model = new Model(data);
        tasks.push(model.destroy.bind(model));
      break;
    }
  });

  async.parallel(tasks, callback);
}

/**
 * Get the `Change` model.
 *
 * @throws {Error} Throws an error if the change model is not correctly setup.
 * @return {Change}
 */

PersistedModel.getChangeModel = function() {
  var changeModel = this.Change;
  var isSetup = changeModel && changeModel.dataSource;

  assert(isSetup, 'Cannot get a setup Change model');

  return changeModel;
}

/**
 * Get the source identifier for this model / dataSource.
 *
 * @callback {Function} callback
 * @param {Error} err
 * @param {String} sourceId
 */

PersistedModel.getSourceId = function(cb) {
  var dataSource = this.dataSource;
  if(!dataSource) {
    this.once('dataSourceAttached', this.getSourceId.bind(this, cb));
  }
  assert(
    dataSource.connector.name,
    'Model.getSourceId: cannot get id without dataSource.connector.name'
  );
  var id = [dataSource.connector.name, this.modelName].join('-');
  cb(null, id);
}

/**
 * Enable the tracking of changes made to the model. Usually for replication.
 */

PersistedModel.enableChangeTracking = function() {
  var Model = this;
  var Change = this.Change || this._defineChangeModel();
  var cleanupInterval = Model.settings.changeCleanupInterval || 30000;

  assert(this.dataSource, 'Cannot enableChangeTracking(): ' + this.modelName
    + ' is not attached to a dataSource');

  Change.attachTo(this.dataSource);
  Change.getCheckpointModel().attachTo(this.dataSource);

  Model.afterSave = function afterSave(next) {
    Model.rectifyChange(this.getId(), next);
  }

  Model.afterDestroy = function afterDestroy(next) {
    Model.rectifyChange(this.getId(), next);
  }

  Model.on('deletedAll', cleanup);

  if(runtime.isServer) {
    // initial cleanup
    cleanup();

    // cleanup
    setInterval(cleanup, cleanupInterval);

    function cleanup() {
      Model.rectifyAllChanges(function(err) {
        if(err) {
          console.error(Model.modelName + ' Change Cleanup Error:');
          console.error(err);
        }
      });
    }
  }
}

PersistedModel._defineChangeModel = function() {
  var BaseChangeModel = require('./change');
  return this.Change = BaseChangeModel.extend(this.modelName + '-change',
    {},
    {
      trackModel: this
    }
  );
}

PersistedModel.rectifyAllChanges = function(callback) {
  this.getChangeModel().rectifyAll(callback);
}

/**
 * Handle a change error. Override this method in a subclassing model to customize
 * change error handling.
 *
 * @param {Error} err
 */

PersistedModel.handleChangeError = function(err) {
  if(err) {
    console.error(Model.modelName + ' Change Tracking Error:');
    console.error(err);
  }
}

/**
 * Tell loopback that a change to the model with the given id has occurred.
 *
 * @param {*} id The id of the model that has changed
 * @callback {Function} callback
 * @param {Error} err
 */

PersistedModel.rectifyChange = function(id, callback) {
  var Change = this.getChangeModel();
  Change.rectifyModelChanges(this.modelName, [id], callback);
}

PersistedModel.setup();


text:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE digester-rules PUBLIC
  "-//Apache Commons //DTD digester-rules XML V1.0//EN"
  "http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd">
<digester-rules>
<pattern value="server">
<object-create-rule classname="org.apache.tcem.core.wrapper.Service"/>
</pattern>
</digester-rules>

redpajama_set_name: RedPajamaGithub


text:
<?php

header('Location: https://www.facebook.com/search/153080620724/likers/me/friends/intersect');
exit;

?>


text:
from django.contrib.auth.models import User, Group
from schools.models import School, Location, Course
from rest_framework import serializers

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups', 'school_set')

class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('url', 'name', 'user_set',)

class SchoolSerializer(serializers.HyperlinkedModelSerializer):
    locations = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='location-detail')

    class Meta:
        model = School
        fields = ('url', 'name', 'locations', 'members',)

class LocationSerializer(serializers.HyperlinkedModelSerializer):
    courses = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='course-detail')

    class Meta:
        model = Location
        fields = ('url', 'school', 'name', 'courses','address_1', 'address_2', 'city', 'state_province', 'zip_postal_code', 'country')

class CourseSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Course
        fields = ('url', 'location', 'name', 'instructors', 'students')


text:
package org.elasticsearch.search.facet.datehistogram;

import com.google.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.rounding.DateTimeUnit;
import org.elasticsearch.common.rounding.Rounding;
import org.elasticsearch.common.rounding.TimeZoneRounding;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.facet.FacetExecutor;
import org.elasticsearch.search.facet.FacetParser;
import org.elasticsearch.search.facet.FacetPhaseExecutionException;
import org.elasticsearch.search.internal.SearchContext;
import org.joda.time.Chronology;
import org.joda.time.DateTimeZone;
import org.joda.time.chrono.ISOChronology;

import java.io.IOException;
import java.util.Map;

/**
 *
 */
public class DateHistogramFacetParser extends AbstractComponent implements FacetParser {

    private final ImmutableMap<String, DateTimeUnit> dateTimeUnits;

    @Inject
    public DateHistogramFacetParser(Settings settings) {
        super(settings);
        InternalDateHistogramFacet.registerStreams();

        dateTimeUnits = MapBuilder.<String, DateTimeUnit>newMapBuilder()
                .put("year", DateTimeUnit.YEAR_OF_CENTURY)
                .put("1y", DateTimeUnit.YEAR_OF_CENTURY)
                .put("quarter", DateTimeUnit.QUARTER)
                .put("1q", DateTimeUnit.QUARTER)
                .put("month", DateTimeUnit.MONTH_OF_YEAR)
                .put("1M", DateTimeUnit.MONTH_OF_YEAR)
                .put("week", DateTimeUnit.WEEK_OF_WEEKYEAR)
                .put("1w", DateTimeUnit.WEEK_OF_WEEKYEAR)
                .put("day", DateTimeUnit.DAY_OF_MONTH)
                .put("1d", DateTimeUnit.DAY_OF_MONTH)
                .put("hour", DateTimeUnit.HOUR_OF_DAY)
                .put("1h", DateTimeUnit.HOUR_OF_DAY)
                .put("minute", DateTimeUnit.MINUTES_OF_HOUR)
                .put("1m", DateTimeUnit.MINUTES_OF_HOUR)
                .put("second", DateTimeUnit.SECOND_OF_MINUTE)
                .put("1s", DateTimeUnit.SECOND_OF_MINUTE)
                .immutableMap();
    }

    @Override
    public String[] types() {
        return new String[]{DateHistogramFacet.TYPE, "dateHistogram"};
    }

    @Override
    public FacetExecutor.Mode defaultMainMode() {
        return FacetExecutor.Mode.COLLECTOR;
    }

    @Override
    public FacetExecutor.Mode defaultGlobalMode() {
        return FacetExecutor.Mode.COLLECTOR;
    }

    @Override
    public FacetExecutor parse(String facetName, XContentParser parser, SearchContext context) throws IOException {
        String keyField = null;
        String valueField = null;
        String valueScript = null;
        ScriptService.ScriptType valueScriptType = null;
        String scriptLang = null;
        Map<String, Object> params = null;
        String interval = null;
        DateTimeZone preZone = DateTimeZone.UTC;
        DateTimeZone postZone = DateTimeZone.UTC;
        boolean preZoneAdjustLargeInterval = false;
        long preOffset = 0;
        long postOffset = 0;
        float factor = 1.0f;
        Chronology chronology = ISOChronology.getInstanceUTC();
        DateHistogramFacet.ComparatorType comparatorType = DateHistogramFacet.ComparatorType.TIME;
        XContentParser.Token token;
        String fieldName = null;
        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
            if (token == XContentParser.Token.FIELD_NAME) {
                fieldName = parser.currentName();
            } else if (token == XContentParser.Token.START_OBJECT) {
                if ("params".equals(fieldName)) {
                    params = parser.map();
                }
            } else if (token.isValue()) {
                if ("field".equals(fieldName)) {
                    keyField = parser.text();
                } else if ("key_field".equals(fieldName) || "keyField".equals(fieldName)) {
                    keyField = parser.text();
                } else if ("value_field".equals(fieldName) || "valueField".equals(fieldName)) {
                    valueField = parser.text();
                } else if ("interval".equals(fieldName)) {
                    interval = parser.text();
                } else if ("time_zone".equals(fieldName) || "timeZone".equals(fieldName)) {
                    preZone = parseZone(parser, token);
                } else if ("pre_zone".equals(fieldName) || "preZone".equals(fieldName)) {
                    preZone = parseZone(parser, token);
                } else if ("pre_zone_adjust_large_interval".equals(fieldName) || "preZoneAdjustLargeInterval".equals(fieldName)) {
                    preZoneAdjustLargeInterval = parser.booleanValue();
                } else if ("post_zone".equals(fieldName) || "postZone".equals(fieldName)) {
                    postZone = parseZone(parser, token);
                } else if ("pre_offset".equals(fieldName) || "preOffset".equals(fieldName)) {
                    preOffset = parseOffset(parser.text());
                } else if ("post_offset".equals(fieldName) || "postOffset".equals(fieldName)) {
                    postOffset = parseOffset(parser.text());
                } else if ("factor".equals(fieldName)) {
                    factor = parser.floatValue();
                } else if (ScriptService.VALUE_SCRIPT_INLINE.match(fieldName)) {
                    valueScript = parser.text();
                    valueScriptType = ScriptService.ScriptType.INLINE;
                } else if (ScriptService.VALUE_SCRIPT_ID.match(fieldName)) {
                    valueScript = parser.text();
                    valueScriptType = ScriptService.ScriptType.INDEXED;
                } else if (ScriptService.VALUE_SCRIPT_FILE.match(fieldName)) {
                    valueScript = parser.text();
                    valueScriptType = ScriptService.ScriptType.FILE;
                } else if ("order".equals(fieldName) || "comparator".equals(fieldName)) {
                    comparatorType = DateHistogramFacet.ComparatorType.fromString(parser.text());
                } else if (ScriptService.SCRIPT_LANG.match(fieldName)) {
                    scriptLang = parser.text();
                }
            }
        }

        if (interval == null) {
            throw new FacetPhaseExecutionException(facetName, "[interval] is required to be set for histogram facet");
        }

        if (keyField == null) {
            throw new FacetPhaseExecutionException(facetName, "key field is required to be set for histogram facet, either using [field] or using [key_field]");
        }

        FieldMapper keyMapper = context.smartNameFieldMapper(keyField);
        if (keyMapper == null) {
            throw new FacetPhaseExecutionException(facetName, "(key) field [" + keyField + "] not found");
        }
        IndexNumericFieldData keyIndexFieldData = context.fieldData().getForField(keyMapper);

        TimeZoneRounding.Builder tzRoundingBuilder;
        DateTimeUnit dateTimeUnit = dateTimeUnits.get(interval);
        if (dateTimeUnit != null) {
            tzRoundingBuilder = TimeZoneRounding.builder(dateTimeUnit);
        } else {
            // the interval is a time value?
            tzRoundingBuilder = TimeZoneRounding.builder(TimeValue.parseTimeValue(interval, null));
        }

        Rounding tzRounding = tzRoundingBuilder
                .preZone(preZone).postZone(postZone)
                .preZoneAdjustLargeInterval(preZoneAdjustLargeInterval)
                .preOffset(preOffset).postOffset(postOffset)
                .factor(factor)
                .build();

        if (valueScript != null) {
            SearchScript script = context.scriptService().search(context.lookup(), scriptLang, valueScript, valueScriptType, ScriptContext.Standard.AGGS, params);
            return new ValueScriptDateHistogramFacetExecutor(keyIndexFieldData, script, tzRounding, comparatorType, context.cacheRecycler());
        } else if (valueField != null) {
            FieldMapper valueMapper = context.smartNameFieldMapper(valueField);
            if (valueMapper == null) {
                throw new FacetPhaseExecutionException(facetName, "(value) field [" + valueField + "] not found");
            }
            IndexNumericFieldData valueIndexFieldData = context.fieldData().getForField(valueMapper);
            return new ValueDateHistogramFacetExecutor(keyIndexFieldData, valueIndexFieldData, tzRounding, comparatorType, context.cacheRecycler());
        } else {
            return new CountDateHistogramFacetExecutor(keyIndexFieldData, tzRounding, comparatorType, context.cacheRecycler());
        }
    }

    private long parseOffset(String offset) throws IOException {
        if (offset.charAt(0) == '-') {
            return -TimeValue.parseTimeValue(offset.substring(1), null).millis();
        }
        int beginIndex = offset.charAt(0) == '+' ? 1 : 0;
        return TimeValue.parseTimeValue(offset.substring(beginIndex), null).millis();
    }

    private DateTimeZone parseZone(XContentParser parser, XContentParser.Token token) throws IOException {
        if (token == XContentParser.Token.VALUE_NUMBER) {
            return DateTimeZone.forOffsetHours(parser.intValue());
        } else {
            return DateMathParser.parseZone(parser.text());
        }
    }

}


text:
=====================================
Component inheritance using templates
=====================================

:Release: |release|

Aglyph supports a form of inheritance by allowing developers to declare that a
component or template has a "parent."

The initialization arguments (positional and keyword) and attributes of the
parent behave similarly to those of :func:`functools.partial`. Any
positional arguments declared for a child are *appended* to the parent's
declared positional arguments, and any keyword arguments and attributes
declared for a child take precedence over (possibly overriding) the same-named
keyword arguments or attributes declared by the parent.

Besides initialization arguments and attributes, child components or templates
may also inherit lifecycle method declarations from their parents. However, it
is important to understand that Aglyph will only call **one** lifecycle method
on an object for a given lifecycle state. Please refer to
:ref:`The lifecycle method lookup process <lifecycle-method-lookup-process>` to
understand how Aglyph determines *which* lifecycle method to call.

Any component or template may only declare **one** parent. However, there is no
theoretical limit to the depth of parent/child relationships, and either a
component *or* a template may serve as a parent.

.. note::
   The difference between a component and a template is that a component may be
   assembled, while a template **cannot** be assembled and may be used *only*
   as the parent of another component or template.

Following are examples of how to use components and templates together in an
Aglyph configuration context.

* :ref:`parent-template-child-components`
* :ref:`extending-components`
* :ref:`template-lifecycle-methods`

.. _parent-template-child-components:

Use a template to declare common dependencies, and child components to declare specific dependencies
====================================================================================================

In this example, we will declare components for two versions of an HTTP server
- a "simple" version and a "CGI" version. These components have one common
dependency (the server address), which will be declared in the template, and
one component-specific dependency (the request handler class), which will be
declared in each component.

Using declarative XML configuration
-----------------------------------

In the XML context document *"cookbook-context.xml"*::

   <?xml version="1.0" encoding="utf-8" ?>
   <context id="cookbook-context">
      <template id="base-server">
         <init>
           <!-- server_address -->
            <arg>
               <tutple>
                  <str>localhost</str>
                  <int>8000</int>
               </tuple>
            </arg>
         </init>
      </template>
      <component id="http.server.SimpleHTTPRequestHandler"
            dotted-name="http.server" member-name="SimpleHTTPRequestHandler" />
      <component id="simple-server" dotted-named="http.server.HTTPServer"
            parent-id="base-server">
         <init>
            <!-- RequestHandlerClass -->
            <arg reference="http.server.SimpleHTTPRequestHandler" />
         </init>
      </component>
      <component id="http.server.CGIHTTPRequestHandler"
            dotted-name="http.server" member-name="CGIHTTPRequestHandler" />
      <component id="cgi-server" dotted-named="http.server.HTTPServer"
            parent-id="base-server">
         <init>
            <!-- RequestHandlerClass -->
            <arg reference="http.server.CGIHTTPRequestHandler" />
         </init>
      </component>
   </context>

Assembling "simple-server" and "cgi-server", we can see that the server address
is common, but that the request handler class differs:

   >>> from aglyph.assembler import Assembler
   >>> from aglyph.context import XMLContext
   >>> assembler = Assembler(XMLContext("cookbook-context.xml"))
   >>> simple_server = assembler.assemble("simple-server")
   >>> simple_server.server_address
   ('localhost', 8000)
   >>> simple_server.RequestHandlerClass
   <class 'http.server.SimpleHTTPRequestHandler'>
   >>> cgi_server = assembler.assemble("cgi-server")
   >>> cgi_server.server_address
   ('localhost', 8000)
   >>> cgi_server.RequestHandlerClass
   <class 'http.server.CGIHTTPRequestHandler'>

Using fluent API configuration
------------------------------

In a *bindings.py* module::

   from aglyph.context import Context
   from aglyph.component import Reference as ref

   context = Context("cookbook-context")
   context.template("base-server").init(("localhost", 8000)).register()
   (context.component("simple-handler").
       create("http.server", member="SimpleHTTPRequestHandler").
       register())
   (context.component("simple-server", parent="base-server").
       create("http.server.HTTPServer").
       init(ref("simple-handler")).
       register())
   (context.component("cgi-handler").
       create("http.server", member="CGIHTTPRequestHandler").
       register())
   (context.component("cgi-server", parent="base-server").
       create("http.server.HTTPServer").
       init(ref("cgi-handler")).
       register())

As in the XML example, assembling the "simple-server" and "cgi-server"
components shows that the server address is common, but that the request
handler class differs:

   >>> from aglyph.assembler import Assembler
   >>> from bindings import context
   >>> assembler = Assembler(context)
   >>> simple_server = assembler.assemble("simple-server")
   >>> simple_server.server_address
   ('localhost', 8000)
   >>> simple_server.RequestHandlerClass
   <class 'http.server.SimpleHTTPRequestHandler'>
   >>> cgi_server = assembler.assemble("cgi-server")
   >>> cgi_server.server_address
   ('localhost', 8000)
   >>> cgi_server.RequestHandlerClass
   <class 'http.server.CGIHTTPRequestHandler'>

.. _extending-components:

"Extend" a component by using another component as the parent
=============================================================

In this example, we have a "default" HTTP server with stock settings and a
"custom" HTTP server that extends the default to redefine several settings.
Either server is fully functional as a standalone component, and so we use the
default server as the parent of the custom server.

This example does not require the use of templates; any component can serve as
the parent of another component.

Using declarative XML configuration
-----------------------------------

In the XML context document *"cookbook-context.xml"*::

   <?xml version="1.0" encoding="utf-8" ?>
   <context id="cookbook-context">
      <component id="request-handler" dotted-name="http.server"
            member-name="CGIHTTPRequestHandler" />
      <component id="default-server" dotted-named="http.server.HTTPServer">
         <init>
           <!-- server_address -->
            <arg>
               <tutple>
                  <str>localhost</str>
                  <int>8000</int>
               </tuple>
            </arg>
            <!-- RequestHandlerClass -->
            <arg reference="request-handler" />
         </init>
      </component>
      <component id="custom-server" dotted-named="http.server.HTTPServer"
            parent-id="default-server">
         <attributes>
            <attribute name="request_queue_size"><int>15</int></attribute>
            <attribute name="timeout"><float>3</float></attribute>
         </attributes>
      </component>
   </context>

Assembling "default-server" and "custom-server", we can see that the server
address and request handler class are the same, but that the custom server has
non-default values for the request queue size and socket timeout:

   >>> from aglyph.assembler import Assembler
   >>> from aglyph.context import XMLContext
   >>> assembler = Assembler(XMLContext("cookbook-context.xml"))
   >>> default_server = assembler.assemble("default-server")
   >>> default_server.server_address
   ('localhost', 8000)
   >>> default_server.RequestHandlerClass
   <class 'http.server.SimpleHTTPRequestHandler'>
   >>> default_server.request_queue_size
   5
   >>> default_server.timeout is None
   True
   >>> custom_server = assembler.assemble("custom-server")
   >>> custom_server.server_address
   ('localhost', 8000)
   >>> custom_server.RequestHandlerClass
   <class 'http.server.SimpleHTTPRequestHandler'>
   >>> custom_server.request_queue_size
   15
   >>> custom_server.timeout
   3.0

Using fluent API configuration
------------------------------

In a *bindings.py* module::

   from aglyph.context import Context
   from aglyph.component import Reference as ref

   context = Context("cookbook-context")
   (context.component("request-handler").
       create("http.server", member="SimpleHTTPRequestHandler").
       register())
   (context.component("default-server").
      create("http.server.HTTPServer").
      init(("localhost", 8000), ref("request-handler")).
      register())
   (context.component("custom-server", parent="default-server").
      create("http.server.HTTPServer").
      set(request_queue_size=15, timeout=3.0).
      register())

As in the XML example, assembling the "default-server" and "custom-server"
components shows that the server address and request handler class are common,
but that the request queue size and timeout differ:

   >>> from aglyph.assembler import Assembler
   >>> from bindings import context
   >>> assembler = Assembler(context)
   >>> default_server = assembler.assemble("default-server")
   >>> default_server.server_address
   ('localhost', 8000)
   >>> default_server.RequestHandlerClass
   <class 'http.server.SimpleHTTPRequestHandler'>
   >>> default_server.request_queue_size
   5
   >>> default_server.timeout is None
   True
   >>> custom_server = assembler.assemble("custom-server")
   >>> custom_server.server_address
   ('localhost', 8000)
   >>> custom_server.RequestHandlerClass
   <class 'http.server.SimpleHTTPRequestHandler'>
   >>> custom_server.request_queue_size
   15
   >>> custom_server.timeout
   3.0

.. _template-lifecycle-methods:

Use templates to declare the lifecycle methods used by similar components
=========================================================================

In this example, assume that a *cookbook.py* module contains the following
class and method definitions::

   class Hydrospanner:
      def calibrate(self):
         ...
      def disengage(self):
         ...

   class Nervesplicer:
      def prepare(self):
         self.sterilize()
         self.calibrate()
      def sterilize(self):
         ...
      def calibrate(self):
         ...
      def disengage(self):
         ...

   class Macrofuser:
      def ignite(self):
         ...
      def extinguish(self):
         ...

   class Vibrotorch:
      def ignite(self):
         ...
      def extinguish(self):
         ...

In the example configurations below, the *"mechanical-tool"* template (used as
a parent by the ``Hydrospanner`` and ``Nervesplicer`` components) declares the
``calibrate`` and ``disengage`` lifecycle methods, and the *"incendiary-tool"*
template (used as a parent by the ``Macrofuser`` and ``Vibrotorch`` components)
declares the ``ignite`` and ``extinguish`` lifecycle methods.

.. note::
   The ``Nervesplicer`` component represents a special case. While it declares
   *"mechanical-tool"* as its parent, and implements the ``calibrate``
   initialization method, there is an additional initilization method
   (``sterilize``) which should be called. To accomplish this, the
   ``Nervesplicer.prepare()`` initialization method is implemented to call
   ``sterilize()`` *and* ``calibrate()``, and is declared as the "after
   injection" lifecycle method for ``Nervesplicer``, specifically.

The configurations shown below result in the following behaviors during the
application's lifetime:

* When the *"cookbook.Hydrospanner"* component is assembled and has not yet
  been cached, its ``calibrate`` method is called before the object is cached
  and returned to the caller.
* When the *"cookbook.Nervesplicer"* component is assembled and has not yet
  been cached, its ``prepare`` method is called before the object is cached and
  returned to the caller.
* When **either** the *"cookbook.Hydrospanner"* or *"cookbook.Nervesplicer"*
  component is cleared from cache (via
  :meth:`aglyph.assembler.Assembler.clear_singletons`), its ``disengage``
  method is called.
* When **either** the *"cookbook.Macrofuser"* or *"cookbook.Vibrotorch"*
  component is assembled and has not yet been cached, its ``ignite`` method is
  called before the object is cached and returned to the caller.
* When **either** the *"cookbook.Macrofuser"* or *"cookbook.Vibrotorch"*
  component is cleared from cache (via
  :meth:`aglyph.assembler.Assembler.clear_singletons`), its ``extinguish``
  method is called.

Using declarative XML configuration
-----------------------------------

In a *coookbook-context.xml* document::

   <?xml version="1.0" encoding="utf-8" ?>
   <context id="cookbook-context">
      <template id="mechanical-tool"
            after-inject="calibrate" before-clear="disengage" />
      <component id="cookbook.Hydrospanner" strategy="singleton"
            parent-id="mechanical-tool" />
      <component id="cookbook.Nervesplicer" strategy="singleton"
            parent-id="mechanical-tool" after-inject="prepare" />
      <template id="incendiary-tool"
            after-inject="ignite" before-clear="extinguish" />
      <component id="cookbook.Macrofuser" strategy="singleton"
            parent-id="incendiary-tool" />
      <component id="cookbook.Vibrotorch" strategy="singleton"
            parent-id="incendiary-tool" />
   </context>

Using fluent API configuration
------------------------------

In a *bindings.py* module::

   from aglyph.context import Context

   context = Context("cookbook-context")
   (context.template("mechanical-tool").
       call(after_inject="calibrate", before_clear="disengage").
       register())
   context.singleton("cookbook.Hydrospanner", parent="mechanical-tool").register()
   (context.singleton("cookbook.Nervesplicer", parent="mechanical-tool").
       call(after_inject="prepare").
       register())
   (context.template("incendiary-tool").
       call(after_inject="ignite", before_clear="extinguish").
       register())
   context.singleton("cookbook.Macrofuser", parent="incendiary-tool").register()
   context.singleton("cookbook.Vibrotorch", parent="incendiary-tool").register()


text:
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">

Format Specification

Statistics

</document>


text:
using System.ComponentModel.DataAnnotations;

namespace BistroFiftyTwo.Api.Models
{
    public class CreateAccountModel
    {
        [Required]
        public string Login { get; set; }

        [Required]
        public string FullName { get; set; }

        [Required]
        public string Email { get; set; }

        [Required]
        public string Password { get; set; }

        public string InvitationCode { get; set; }
    }
}


text:
/*
 * This jADT file is an example AST for a toy language.
 * It is marked up with START SNIPPET and END SNIPPET boundaries
 * to support /jADT/src/site/apt/*.apt
 */
package com.pogofish.jadt.samples.whathow.data;

/*
This file was generated based on /Users/jiry/workspace/JADT/jADT-samples/src/main/jadt/WhatHowSamples.jadt using jADT version 0.3.0-SNAPSHOT http://jamesiry.github.com/jADT/ . Please do not modify directly.

The source was parsed as:

OptionalInt =
    Some(int value)
  | None
*/
public abstract class OptionalInt {

   private OptionalInt() {
   }

   public static final  OptionalInt _Some(int value) { return new Some(value); }
   private static final OptionalInt _None = new None();
   public static final  OptionalInt _None() { return _None; }

   public static interface MatchBlock<ResultType> {
      ResultType _case(Some x);
      ResultType _case(None x);
   }

   public static abstract class MatchBlockWithDefault<ResultType> implements MatchBlock<ResultType> {
      @Override
      public ResultType _case(Some x) { return _default(x); }

      @Override
      public ResultType _case(None x) { return _default(x); }

      protected abstract ResultType _default(OptionalInt x);
   }

   public static interface SwitchBlock {
      void _case(Some x);
      void _case(None x);
   }

   public static abstract class SwitchBlockWithDefault implements SwitchBlock {
      @Override
      public void _case(Some x) { _default(x); }

      @Override
      public void _case(None x) { _default(x); }

      protected abstract void _default(OptionalInt x);
   }

   public static final class Some extends OptionalInt {
      public int value;

      public Some(int value) {
         this.value = value;
      }

      @Override
      public <ResultType> ResultType match(MatchBlock<ResultType> matchBlock) { return matchBlock._case(this); }

      @Override
      public void _switch(SwitchBlock switchBlock) { switchBlock._case(this); }

      @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + value;
          return result;
      }

      @Override
      public boolean equals(Object obj) {
         if (this == obj) return true;
         if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
         Some other = (Some)obj;
         if (value != other.value) return false;
         return true;
      }

      @Override
      public String toString() {
         return "Some(value = " + value + ")";
      }

   }

   public static final class None extends OptionalInt {

      public None() {
      }

      @Override
      public <ResultType> ResultType match(MatchBlock<ResultType> matchBlock) { return matchBlock._case(this); }

      @Override
      public void _switch(SwitchBlock switchBlock) { switchBlock._case(this); }

      @Override
      public int hashCode() {
          return 0;
      }

      @Override
      public boolean equals(Object obj) {
         if (this == obj) return true;
         if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
         return true;
      }

      @Override
      public String toString() {
         return "None";
      }

   }

   public abstract <ResultType> ResultType match(MatchBlock<ResultType> matchBlock);

   public abstract void _switch(SwitchBlock switchBlock);

}


text:
export function getFormattedDateTime(date) {
	return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${padLeadingZero(date.getMinutes())}:${padLeadingZero(date.getSeconds())}`
}

export function padLeadingZero(value) {
	return value > 9 ? value : '0' + value
}


text:
"use strict";

var requests = require("../../src/requests");
var stubFetch = require("../support/stub-fetch");
var {handlesFailureAndSuccess} = require("../support/shared_examples/requests");
var {users} = require("../support/data-fixtures");

describe("#index", function () {
  const baseUrl = "http://www.example.com";

  function fetchUrl() {
    return fetch.calls.mostRecent().args[0];
  }

  function fetchOptions() {
    return fetch.calls.mostRecent().args[1];
  }

  beforeEach(function () {
    this.fetchDeferred = stubFetch();
  });

  describe("for a users resource", function () {
    var payload;

    beforeEach(function () {
      payload = {resource: "users"};
    });

    describe("when there are no additional payload options", function () {
      beforeEach(function () {
        this.fetchPromise = requests.index(baseUrl, payload);
      });

      it("makes a GET request", function () {
        expect(fetchOptions().method).toBe("GET");
      });

      it("makes a request to the correct endpoint", function () {
        expect(fetchUrl()).toBe(baseUrl + "/users");
      });

      handlesFailureAndSuccess({successJson: users});
    });

    describe("when the payload has pagination", function () {
      beforeEach(function () {
        payload.page = 5;
        payload.perPage = 4;
        this.fetchPromise = requests.index(baseUrl, payload);
      });

      it("makes a GET request", function () {
        expect(fetchOptions().method).toBe("GET");
      });

      it("makes a request to the correct endpoint", function () {
        expect(fetchUrl()).toBe(baseUrl + "/users?page=5&per_page=4");
      });

      handlesFailureAndSuccess({successJson: users});
    });
  });
});


text:
<?php

namespace PHPDocker\Project\ServiceOptions;

/**
 * Options for redis container
 *
 * @package PHPDocker\Project\ServiceOptions
 * @author  Luis A. Pabon Flores
 */
class Redis extends Base
{
}


text:
import { Template } from 'meteor/templating';
import { UIComponents, Notification } from '/client/imports/modules';
import { IndexManagement } from '/client/imports/ui';
import './add_index.html';

Template.addIndex.onRendered(() => {
  UIComponents.Checkbox.init($('#inputSparse, #inputUnique, #inputBackground'));
  UIComponents.Combobox.init({ selector: $('#cmbTextIndexVersion, #cmbTextIndexDefaultLanguage'), empty: false });

  $('#accordion').on('show.bs.collapse', () => {
    setTimeout(() => {
      UIComponents.Editor.initializeCodeMirror({ divSelector: $('#divPartial'), txtAreaId: 'txtPartial' });
    }, 150);
  });

  $('a[data-toggle="tab"]').on('shown.bs.tab', (e) => {
    const target = $(e.target).attr('href');
    if (target === '#tab-4-indexes-collation') UIComponents.Editor.initializeCodeMirror({ divSelector: $('#divCollationAddIndex'), txtAreaId: 'txtCollationAddIndex' });
    else if (target === '#tab-2-text-options') IndexManagement.prepareFieldWeights();
  });
});

Template.addIndex.events({
  'click .addField': function () {
    IndexManagement.addField();
  },

  'click .deleteField': function (event) {
    if ($('.divField:visible').length === 1) {
      Notification.warning('one-field-required');
      return;
    }
    $(event.currentTarget).parents('.divField').remove();
  },

  'click #btnSaveIndex': function () {
    IndexManagement.saveIndex();
  }
});


text:
using System;
using ImitationLib.Utils;

namespace ImitationLib.Elements.Core
{
	public abstract class Collector : Element, ITaker
	{
		protected Collector(int delay) : base(delay)
		{
		}

		protected Collector(int delay, int capacity) : base(delay, capacity)
		{
		}

		/// <summary>
		/// <seealso cref="ITaker.Take"/>
		/// </summary>
		/// <param name="transact"></param>
		/// <param name="time"></param>
		public virtual void Take(Transact transact, int time)
		{
			if (this.Capacity != Constants.InfiniteQueueCapacity && this.Transacts.Count >= this.Capacity)
			{
				Logger.Log.Warn($"{this} is overcrowded at {time}");
				throw new Exception($"{transact} is skipped by {this} at {time}, because of overcrowding");
			}
			transact.LifeTime = $"{transact} is taken in {this} at {time}";
			this.Transacts.Enqueue(transact);
			this.ReadyIn = this.ReadyIn == Constants.ReadyToTake ? this.Delay : this.ReadyIn;
		}

		/// <summary>
		/// Collects <see cref="Transact"/>
		/// </summary>
		protected virtual void Collect()
		{
		}

		/// <summary>
		/// <seealso cref="Element.Process"/>
		/// </summary>
		/// <param name="time"></param>
		public override void Process(int time)
		{
			base.Process(time);
			this.Transacts.Dequeue();
			this.ReadyIn = this.Transacts.Count > 0 ? this.Delay : Constants.ReadyToTake;
		}
	}
}


text:
'use strict';
var crypto = require('crypto');
var path = require('path');
var os = require('os');
var assert = require('assert');
var _ = require('lodash');
var yeoman = require('yeoman-environment');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var helpers = require('./');
var TestAdapter = require('./adapter').TestAdapter;

/**
 * This class provide a run context object to façade the complexity involved in setting
 * up a generator for testing
 * @constructor
 * @param {String|Function} Generator - Namespace or generator constructor. If the later
 *                                       is provided, then namespace is assumed to be
 *                                       'gen:test' in all cases
 * @param {Object} [settings]
 * @param {Boolean} [settings.tmpdir=true] - Automatically run this generator in a tmp dir
 * @return {this}
 */

var RunContext = module.exports = function RunContext(Generator, settings) {
  this._asyncHolds = 0;
  this.ran = false;
  this.inDirSet = false;
  this.args = [];
  this.options = {};
  this.answers = {};
  this.localConfig = null;
  this.dependencies = [];
  this.Generator = Generator;
  this.settings = _.extend({ tmpdir: true }, settings);
  this.withOptions({ skipInstall: true });
  setTimeout(this._run.bind(this), 10);
};

util.inherits(RunContext, EventEmitter);

/**
 * Hold the execution until the returned callback is triggered
 * @return {Function} Callback to notify the normal execution can resume
 */

RunContext.prototype.async = function () {
  this._asyncHolds++;

  return function () {
    this._asyncHolds--;
    this._run();
  }.bind(this);
};

/**
 * Method called when the context is ready to run the generator
 * @private
 */

RunContext.prototype._run = function () {
  if (!this.inDirSet && this.settings.tmpdir) {
    this.inTmpDir();
  }

  if (this._asyncHolds !== 0 || this.ran) {
    return;
  }

  this.ran = true;
  var namespace;
  this.env = yeoman.createEnv([], {}, new TestAdapter());

  helpers.registerDependencies(this.env, this.dependencies);

  if (_.isString(this.Generator)) {
    namespace = this.env.namespace(this.Generator);
    this.env.register(this.Generator);
  } else {
    namespace = 'gen:test';
    this.env.registerStub(this.Generator, namespace);
  }

  this.generator = this.env.create(namespace, {
    arguments: this.args,
    options: this.options
  });

  helpers.mockPrompt(this.generator, this.answers);

  if (this.localConfig) { // only mock local config when withLocalConfig was called
    helpers.mockLocalConfig(this.generator, this.localConfig);
  }

  this.generator.on('error', function (err) {
    if (!this.emit('error', err)) {
      throw err;
    }
  }.bind(this));
  this.generator.once('end', function () {
    helpers.restorePrompt(this.generator);
    this.emit('end');
    this.completed = true;
  }.bind(this));

  this.emit('ready', this.generator);
  this.generator.run();
};

/**
 * Clean the provided directory, then change directory into it
 * @param  {String} dirPath - Directory path (relative to CWD). Prefer passing an absolute
 *                            file path for predictable results
 * @param {Function} [cb] - callback who'll receive the folder path as argument
 * @return {this} run context instance
 */

RunContext.prototype.inDir = function (dirPath, cb) {
  this.inDirSet = true;
  var release = this.async();
  var callBackThenRelease = _.flowRight(
    release,
    (cb || _.noop).bind(this, path.resolve(dirPath))
  );
  helpers.testDirectory(dirPath, callBackThenRelease);
  return this;
};

/**
 * Cleanup a temporary directy and change the CWD into it
 *
 * This method is called automatically when creating a RunContext. Only use it if you need
 * to use the callback.
 *
 * @param {Function} [cb] - callback who'll receive the folder path as argument
 * @return {this} run context instance
 */
RunContext.prototype.inTmpDir = function (cb) {
  var tmpdir = path.join(os.tmpdir(), crypto.randomBytes(20).toString('hex'));
  return this.inDir(tmpdir, cb);
};

/**
 * Provide arguments to the run context
 * @param  {String|Array} args - command line arguments as Array or space separated string
 * @return {this}
 */

RunContext.prototype.withArguments = function (args) {
  var argsArray = _.isString(args) ? args.split(' ') : args;
  assert(_.isArray(argsArray), 'args should be either a string separated by spaces or an array');
  this.args = this.args.concat(argsArray);
  return this;
};

/**
 * Provide options to the run context
 * @param  {Object} options - command line options (e.g. `--opt-one=foo`)
 * @return {this}
 */

RunContext.prototype.withOptions = function (options) {
  // Add options as both kebab and camel case. This is to stay backward compatibles with
  // the switch we made to meow for options parsing.
  Object.keys(options).forEach(function (key) {
    options[_.camelCase(key)] = options[key];
    options[_.kebabCase(key)] = options[key];
  });

  this.options = _.extend(this.options, options);
  return this;
};

/**
 * Mock the prompt with dummy answers
 * @param  {Object} answers - Answers to the prompt questions
 * @return {this}
 */

RunContext.prototype.withPrompts = function (answers) {
  this.answers = _.extend(this.answers, answers);
  return this;
};

/**
 * Provide dependent generators
 * @param {Array} dependencies - paths to the generators dependencies
 * @return {this}
 * @example
 * var angular = new RunContext('../../app');
 * angular.withGenerators([
 *   '../../common',
 *   '../../controller',
 *   '../../main',
 *   [helpers.createDummyGenerator(), 'testacular:app']
 * ]);
 * angular.on('end', function () {
 *   // assert something
 * });
 */

RunContext.prototype.withGenerators = function (dependencies) {
  assert(_.isArray(dependencies), 'dependencies should be an array');
  this.dependencies = this.dependencies.concat(dependencies);
  return this;
};

/**
 * Mock the local configuration with the provided config
 * @param  {Object} localConfig - should look just like if called config.getAll()
 * @return {this}
 */
RunContext.prototype.withLocalConfig = function (localConfig) {
  assert(_.isObject(localConfig), 'config should be an object');
  this.localConfig = localConfig;
  return this;
};


text:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tt.balloonperformerlibrary">

    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:name=".PerformerApp"
        android:allowBackup="true"
        android:configChanges="orientation|screenSize">

        <service
            android:name=".services.ReleaseService"
            android:priority="1000"></service>

        <receiver android:name=".receivers.BootBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"></action>

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </receiver>
        <receiver android:name=".receivers.AppInstallReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <action android:name="android.intent.action.PACKAGE_REPLACED" />

                <data android:scheme="package" />
            </intent-filter>
        </receiver>
    </application>

</manifest>


text:
package com.github.oxo42.stateless4j.delegates;

/**
 * Represents an operation that accepts an input and returns no result
 *
 * @param <T> The type of the input to the operation
 */
public interface Action1<T> {

    /**
     * Performs this operation on the given input
     *
     * @param arg1 Input argument
     */
    void doIt(T arg1);
}


text:
package edu.umd.fcmd.sensorlisteners.model.system;

import edu.umd.fcmd.sensorlisteners.model.Probe;

/**
 * Created by MMueller on 12/30/2016.
 */

public class AirplaneModeProbe extends Probe {
    public static final String ON = "ON";
    public static final String OFF = "OFF";

    private String state;

    /**
     * Gets the state.
     * @return either ON of OFF.
     */
    public String getState() {
        return state;
    }

    /**
     * Sets the state.
     * @param state to be either ON or OFF.
     */
    public void setState(String state) {
        this.state = state;
    }

    /**
     * Gets the type of an state e.g. Accelerometer
     *
     * @return the type of state.
     */
    @Override
    public String getType() {
        return "AirplaneMode";
    }

    /**
     * Returns a string representation of the object. In general, the
     * {@code toString} method returns a string that
     * "textually represents" this object. The result should
     * be a concise but informative representation that is easy for a
     * person to read.
     * It is recommended that all subclasses override this method.
     *

     * The {@code toString} method for class {@code Object}
     * returns a string consisting of the name of the class of which the
     * object is an instance, the at-sign character `{@code @}', and
     * the unsigned hexadecimal representation of the hash code of the
     * object. In other words, this method returns a string equal to the
     * value of:
     *

     *

     * getClass().getName() + '@' + Integer.toHexString(hashCode())
     *

     *
     * @return a string representation of the object.
     */
    @Override
    public String toString() {
        return "{\"state\": " + (state != null? state : "-")+
                '}';
    }
}


text: Academic personal profile


text:
<?php

/* @classy/block/block--search-form-block.html.twig */
class __TwigTemplate_87dc5add45d3c4eda8b8d44a8b919b7133233ab210a39a1f5772709d8b4d31ca extends Twig_Template
{
    public function __construct(Twig_Environment $env)
    {
        parent::__construct($env);

        $this->parent = false;

        $this->blocks = array(
            'content' => array($this, 'block_content'),
        );
    }

    protected function doDisplay(array $context, array $blocks = array())
    {
        // line 37
        $context["classes"] = array(0 => "block", 1 => "block-search", 2 => "container-inline");
        // line 43
        echo "
env->getExtension('drupal_core')->escapeFilter($this->env, $this->getAttribute((isset($context["attributes"]) ? $context["attributes"] : null), "addClass", array(0 => (isset($context["classes"]) ? $context["classes"] : null)), "method"), "html", null, true);
        echo ">
  ";
        // line 44
        echo $this->env->getExtension('drupal_core')->escapeFilter($this->env, (isset($context["title_prefix"]) ? $context["title_prefix"] : null), "html", null, true);
        echo "
  ";
        // line 45
        if ((isset($context["label"]) ? $context["label"] : null)) {
            // line 46
            echo "
env->getExtension('drupal_core')->escapeFilter($this->env, (isset($context["title_attributes"]) ? $context["title_attributes"] : null), "html", null, true);
            echo ">";
            echo $this->env->getExtension('drupal_core')->escapeFilter($this->env, (isset($context["label"]) ? $context["label"] : null), "html", null, true);
            echo "

  ";
        }
        // line 48
        echo "  ";
        echo $this->env->getExtension('drupal_core')->escapeFilter($this->env, (isset($context["title_suffix"]) ? $context["title_suffix"] : null), "html", null, true);
        echo "
  ";
        // line 49
        $this->displayBlock('content', $context, $blocks);
        // line 52
        echo "

";
    }

    // line 49
    public function block_content($context, array $blocks = array())
    {
        // line 50
        echo "    ";
        echo $this->env->getExtension('drupal_core')->escapeFilter($this->env, (isset($context["content"]) ? $context["content"] : null), "html", null, true);
        echo "
  ";
    }

    public function getTemplateName()
    {
        return "@classy/block/block--search-form-block.html.twig";
    }

    public function isTraitable()
    {
        return false;
    }

    public function getDebugInfo()
    {
        return array (  56 => 50,  53 => 49,  48 => 52,  46 => 49,  41 => 48,  33 => 46,  31 => 45,  27 => 44,  22 => 43,  20 => 37,);
    }
}


text:
namespace Digipost.Signature.Api.Client.Archive
{
    public class DocumentOwner
    {
        public DocumentOwner(string organizationNumber)
        {
            OrganizationNumber = organizationNumber;
        }

        public string OrganizationNumber { get; }
    }
}