docs: function setRuleModel (roles, rule, rules, origRule) {
      // allow/deny is last element of rule
      var allow = rule.pop()
      // blanket rule for all models
      if (rule.length === 0) {
          // create role access rule map
          if (!rules.allow) {
              rules.allow = {}
          }
          // set rule for each role
          _.each(roles, role => {
              rules.allow[role] = allow
          })
          // break
          return
      }
  
      // model name is first clause of rule
      var model = rule.shift()
      // create map of models
      if (!rules.model) {
          rules.model = {}
      }
      // create entry for model
      if (!rules.model[model]) {
          rules.model[model] = {}
      }
  
      // blanket rule for single model
      if (rule.length === 0) {
          // create role access rule map
          if (!rules.model[model].allow) {
              rules.model[model].allow = {}
          }
          // set rule for each role
          _.each(roles, role => {
              rules.model[model].allow[role] = allow
          })
          // break
          return
      }
  
      // action follows model name
      var action = rule.shift()
      // create map of actions
      if (!rules.model[model].action) {
          rules.model[model].action = {}
      }
      // create entry for action
      if (!rules.model[model].action[action]) {
          rules.model[model].action[action] = {}
      }
  
      // create action does not have any options
      if (action === 'create') {
          // there should be no more rule clauses
          if (rule.length === 0) {
              // create role access rule map
              if (!rules.model[model].action[action].allow) {
                  rules.model[model].action[action].allow = {}
              }
              // set rule for each role
              _.each(roles, role => {
                  rules.model[model].action[action].allow[role] = allow
              })
              // break
              return
          }
          else {
              throw new Error('invalid rule '+origRule)
          }
      }
      // all other actions apply to existing model instances and can
      // apply either to any instance or to instances owned by session
      else {
          // if there are two rule clauses then next is a state
          if (rule.length === 2) {
              var state = rule.shift()
              // create map of states
              if (!rules.model[model].action[action].state) {
                  rules.model[model].action[action].state = {}
              }
              // create entry for state
              if (!rules.model[model].action[action].state[state]) {
                  rules.model[model].action[action].state[state] = {}
              }
              // own/any clause follows state
              rules = rules.model[model].action[action].state[state]
          }
          // otherwise own/any clause follows action
          else {
              rules = rules.model[model].action[action]
          }
          // there must be one additional rule clause
          if (rule.length === 1) {
              var scope = rule.shift()
              // scope must be own or any
              assert.ok(scope === 'own' || scope === 'any', 'invalid rule '+origRule)
              // create map for scope
              if (!rules[scope]) {
                  rules[scope] = {}
              }
              // create role access rule map
              if (!rules[scope].allow) {
                  rules[scope].allow = {}
              }
              // set rule for each role
              _.each(roles, role => {
                  rules[scope].allow[role] = allow
              })
          }
          else {
              throw new Error('invalid rule '+origRule)
          }
      }
  }