lib/heads.js
function AbstractRoboHydraHead(props) {
    // If you don't pass props at all, created a "generic", valid
    // RoboHydra head. This is useful for inheritance and for when you
    // don't really care about the behaviour of the head (you just
    // want one created)
    props = props || {path: '/.*', handler: function(_, res) {res.end();}};

    this.type = 'generic';
    this._importProperties(AbstractRoboHydraHead, props);

    var self = this;
    this._attached = !props.detached;
    this.requestParamNames = [];
    this.path = this._normalizePath(props.path || '/.*').
            replace(/:(\w+)/g,
                    function(_, name) {
                        self.requestParamNames.push(name);
                        return '([^/]+)';
                    });
    if (typeof this.reset !== 'function') {
        throw new InvalidRoboHydraHeadException("Property 'reset' must be a function");
    }
    this.reset();
}
function AbstractRoboHydraHead(props) {
    // If you don't pass props at all, created a "generic", valid
    // RoboHydra head. This is useful for inheritance and for when you
    // don't really care about the behaviour of the head (you just
    // want one created)
    props = props || {path: '/.*', handler: function(_, res) {res.end();}};

    this.type = 'generic';
    this._importProperties(AbstractRoboHydraHead, props);

    var self = this;
    this._attached = !props.detached;
    this.requestParamNames = [];
    this.path = this._normalizePath(props.path || '/.*').
            replace(/:(\w+)/g,
                    function(_, name) {
                        self.requestParamNames.push(name);
                        return '([^/]+)';
                    });
    if (typeof this.reset !== 'function') {
        throw new InvalidRoboHydraHeadException("Property 'reset' must be a function");
    }
    this.reset();
}
/*

Notes on creating RoboHydraHead* classes:

By convention, all classes set a 'parent' property.

By convention, all classes have a 'type' property with a simple
name for the class. This is used in the admin UI.

All classes have an array of mandatory properties and optional
properties in 'mandatoryProperties' and 'optionalProperties'.

Classes should always provide a set of default properties in the
constructor if no argument is passed at all, to ease the creation
of other classes inheriting from it.

All class constructors call "_importProperties" with the current
class and the property object received as a parameter, to copy the
relevant properties to the object, and check that there are no
invalid properties.

All class constructors call "inherit" with the parent class (always
available as CurrentClass.parent, see above) with the property
object received as a parameter, plus any extra properties to be
passed to the parent class.