docs: function Command(args) {
    if (false === (this instanceof Command)) throw new Error('new operator required');
    if (typeof args == 'function') { // shorthand for function command
      args = {type: 'Function', contents: args};
    }
    if (args instanceof Procedure) { // shorthand for Procedure command
      args = {type: 'Procedure', contents: args};
    }
    args = args || {};
    var i;
    var unusedProperties = getInvalidProperties(args,
      ['name', 'description', 'type', 'contents', 'scope', 'timeout', 'theme', 'icon', 'bucket', 'presentationMode','location','images']);
    var errorList = [];
    for (i = 0; i < unusedProperties.length; i++) errorList.push('invalid property: ' + unusedProperties[i]);
    if (errorList.length > 1) throw new Error('error creating Command: multiple errors');
    if (errorList.length) throw new Error('error creating Command: ' + errorList[0]);
    for (i in args) this[i] = args[i];
    this.name = this.name || "a command"; // name is optional
    if ('string' != typeof this.name) throw new Error('name must be string');
    if ('undefined' == typeof this.description) this.description = this.name + ' Command';
    if ('undefined' == typeof this.type) this.type = 'Stub';
    if (!contains(Command.getTypes(), this.type)) throw new Error('Invalid command type: ' + this.type);
    switch (this.type) {
      case 'Stub':
        break;
      case 'Menu':
        if (!(this.contents instanceof Array)) throw new Error('contents must be array of menu items');
        if (!this.contents.length) throw new Error('contents must be array of menu items');
        for (i in this.contents) {
          if (this.contents.hasOwnProperty(i))
            if (typeof this.contents[i] != 'string' && !(this.contents[i] instanceof Command))
              throw new Error('contents must be array of menu items');
        }
        break;
      case 'Presentation':
        if (!(this.contents instanceof Presentation)) throw new Error('contents must be a Presentation');
        this.presentationMode = this.presentationMode || 'View';
        if (!contains(Command.getPresentationModes(), this.presentationMode)) throw new Error('Invalid presentationMode: ' + this.presentationMode);
        //['View', 'Edit', 'List']
        break;
      case 'Function':
        if (typeof this.contents != 'function') throw new Error('contents must be a Function');
        break;
      case 'Procedure':
        if (!(this.contents instanceof Procedure)) throw new Error('contents must be a Procedure');
        break;
      default:
        throw new TypeError();
    }
    if ('undefined' != typeof this.scope)
      if (!((this.scope instanceof Model) || (this.scope instanceof List)))
        throw new Error('optional scope property must be Model or List');
    if ('undefined' != typeof this.timeout)
      if (typeof this.timeout != 'number') throw new Error('timeout must be a Number');
    if ('undefined' != typeof this.timeout)
      if (typeof this.timeout != 'number') throw new Error('timeout must be a Number');
    if ('undefined' != typeof this.theme) {
      if ('string' != typeof this.theme) throw new Error('invalid theme');
      if (!contains(['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'], this.theme))
        throw new Error('invalid theme');
    }
    if ('undefined' != typeof this.icon) {
      if ('string' != typeof this.icon) throw new Error('invalid icon');
      if (!contains(['fa', 'glyphicon'], this.icon.split('-')[0]) || !this.icon.split('-')[1])
        throw new Error('invalid icon');
    }
  
    // Validations done
    this._eventListeners = [];
  }