Check new model before registration
function deepLook(obj, types) {
  if (typeof (obj) !== 'object') return obj;
  for (var key in obj) {
    if (!obj[key].type) {
      obj[key] = deepLook(obj[key], types);
    } else {
      if (!types[obj[key].type]) {
        throw new Error('No type ' + obj[key].type + ' in Types: key ' + key);
      }

      // check for range in new object
      if (typeof obj[key].min !== 'undefined'
        && typeof types[obj[key].type].min !== 'undefined'
        && types[obj[key].type].min > obj[key].min) {
        throw new Error('Key ' + key + ' minimal value (' + obj[key].min
          + ') is less than acceptable minimal in Types ('
          + types[obj[key].type].min + ')');
      }

      if (typeof obj[key].max !== 'undefined'
        && typeof types[obj[key].type].max !== 'undefined'
        && types[obj[key].type].max < obj[key].max) {
        throw new Error('Key ' + key + ' maximal value (' + obj[key].max
          + ') is in excess of maximal acceptable value in Types ('
          + types[obj[key].type].max + ')');
      }
    }

    // get properties and methods from Types
    for (var keyParent in types[obj[key].type]) {
      if (!obj[key][keyParent]) {
        obj[key][keyParent] = types[obj[key].type][keyParent];
      }
    }
  }

  return obj;
}