docs: function generateRemodel(scope, ctrlName, isPartial, fnOrObj, directiveScope) {
          if (!fnOrObj) { return true; }
          directiveScope = directiveScope || {};
  
          // return true in case expecting a promise
          var formerRemodel = function () { return true; };
          if (scope.remodel) {
              formerRemodel = scope.remodel;
          }
  
          // remodeling will call the model function
          scope.remodel = function () {
              var locals = {
                  currentScope:   scope,
                  defaults:       scope.defaults
              };
  
              try {
  
                  // if the partial model() is a function or an array with a function at the end,
                  // inject it and set the return value on the scope
                  if (angular.isFunction(fnOrObj) ||
                      (angular.isArray(fnOrObj) && angular.isFunction(fnOrObj[fnOrObj.length - 1]))) {
  
                      return $q.when($injector.invoke(fnOrObj, null, locals))
                          .then(function (model) {
                              angular.forEach(model, function (modelVal, modelName) {
                                  if (directiveScope[modelName]) {
                                      throw new Error(ctrlName + ' model() should not return ' + modelName + ' from the parent scope');
                                  }
  
                                  scope[modelName] = modelVal;
                              });
                              //return true;
                              return formerRemodel();
                          });
                  }
                  // else it should be an object so loop through
                  else {
                      var updates = [];
                      angular.forEach(fnOrObj, function (val, name) {
                          if (name === 'end') {
                              return;
                          }
  
                          if (directiveScope[name]) {
                              throw new Error(ctrlName + ' model() should not return ' + name + ' from the parent scope');
                          }
  
                          // if a function inject it and set returned value on scope[name]
                          if (angular.isFunction(val) ||
                              (angular.isArray(val) && angular.isFunction(val[val.length - 1]))) {
  
                              updates.push($q.when($injector.invoke(val, null, locals))
                                  .then(function (model) {
                                      scope[name] = model;
                                      return model;
                                  }));
                          }
                          // else just set the value on scope[name]
                          else {
                              updates.push($q.when(scope[name] = val));  // think we can just do this instead of larger wrapper
                          }
                      });
                      return $q.all(updates).then(function () {
                          return formerRemodel();
                      });
                  }
  
              }
              catch (ex) {
                  /* eslint no-console:0 */
                  console.log(ctrlName + ' has err ');
                  throw ex;
              }
          };
  
          // for partials, we want to remodel right away
          return isPartial ? scope.remodel() : true;
      }