whole_func_string: function checkType(obj, field, expType, mustHave, min, max) {
      let value = typeof (obj) === 'object' ? obj[field] : obj;
      if (value === undefined) {
          return getDefault(obj, field, mustHave);
      }
      // Try to convert value to expected type
      let type = expType[0] === '[' ? Object.prototype.toString.call(value) : typeof value;
      if (type === 'string') {
          switch (expType) {
              case 'number':
                  value = checkType.strToFloat(value);
                  type = typeof value;
                  break;
              case 'integer':
              case 'zoom':
                  obj[field] = value = checkType.strToInt(value);
                  type = typeof value;
                  break;
              case 'boolean':
                  obj[field] = value = !!value;
                  type = typeof value;
                  break;
              case 'string-array':
                  obj[field] = value = [value];
                  type = typeof value;
                  break;
              case 'number-array':
                  value = checkType.strToFloat(value);
                  type = typeof value;
                  if (type === 'number') {
                      obj[field] = value = [value];
                  }
                  break;
          }
      } else if (type === 'number' && expType === 'number-array') {
          obj[field] = value = [value];
          type = typeof value;
      }
  
      // validate the type
      switch (expType) {
          case 'string-array':
              if (!Array.isArray(value) ||
                  !_.all(value, v => typeof v === 'string' && v.length > 0)
              ) {
                  throw new Err('Invalid %s param: expecting a string or an array of strings', field);
              }
              break;
          case 'number-array':
              let isValid = Array.isArray(value);
              if (isValid) {
                  value = _.map(value, v => {
                      v = checkType.strToFloat(v);
                      if (typeof v !== 'number') {
                          isValid = false;
                      }
                      return v;
                  });
              }
              if (!isValid) {
                  throw new Err('Invalid %s param: expecting a number or an array of numbers', field);
              }
              obj[field] = value;
              break;
          case 'array':
              if (!Array.isArray(value)) {
                  throw new Err('Invalid %s param type %s given, was expecting an array',
                      field, type);
              }
              break;
          case 'integer':
              if (!Number.isInteger(value)) {
                  throw new Err('Invalid %s param type %s given, was expecting an integer',
                      field, type);
              }
              break;
          case 'zoom':
              if (!qidx.isValidZoom(value)) {
                  throw new Err('Invalid %s param - an integer zoom value was expected', field);
              }
              break;
          default:
              if (type !== expType) {
                  throw new Err('Invalid %s param type %s given, was expecting %s',
                      field, type, expType);
              }
              break;
      }
  
      // validate ranges
      switch (expType) {
          case 'number':
          case 'integer':
          case 'zoom':
              if (min !== undefined && value < min) {
                  throw new Err('Invalid %s param - must be at least %d, but given %d',
                      field, min, value);
              }
              if (max !== undefined && value > max) {
                  throw new Err('Invalid %s param - must be at most %d, but given %d',
                      field, max, value);
              }
              break;
          case 'string':
              if (min !== undefined && value.length < min) {
                  throw new Err('Invalid %s param - the string must be at least %d symbols',
                      field, min);
              }
              break;
          case 'boolean':
              if (value === false) {
                  // convert false into undefined
                  delete obj[field];
                  return false;
              }
              break;
          case 'string-array':
          case 'number-array':
              if (min !== undefined && value.length < min) {
                  throw new Err('Invalid %s param - it must have at least %d values, but given %d',
                      field, min, value.length);
              }
              if (max !== undefined && value.length > max) {
                  throw new Err('Invalid %s param - it must have at least %d values, but given %d',
                      field, max, value.length);
              }
              break;
      }
  
      return true;
  }
func_code_string: function checkType(obj, field, expType, mustHave, min, max) {
      let value = typeof (obj) === 'object' ? obj[field] : obj;
      if (value === undefined) {
          return getDefault(obj, field, mustHave);
      }
      // Try to convert value to expected type
      let type = expType[0] === '[' ? Object.prototype.toString.call(value) : typeof value;
      if (type === 'string') {
          switch (expType) {
              case 'number':
                  value = checkType.strToFloat(value);
                  type = typeof value;
                  break;
              case 'integer':
              case 'zoom':
                  obj[field] = value = checkType.strToInt(value);
                  type = typeof value;
                  break;
              case 'boolean':
                  obj[field] = value = !!value;
                  type = typeof value;
                  break;
              case 'string-array':
                  obj[field] = value = [value];
                  type = typeof value;
                  break;
              case 'number-array':
                  value = checkType.strToFloat(value);
                  type = typeof value;
                  if (type === 'number') {
                      obj[field] = value = [value];
                  }
                  break;
          }
      } else if (type === 'number' && expType === 'number-array') {
          obj[field] = value = [value];
          type = typeof value;
      }
  
      // validate the type
      switch (expType) {
          case 'string-array':
              if (!Array.isArray(value) ||
                  !_.all(value, v => typeof v === 'string' && v.length > 0)
              ) {
                  throw new Err('Invalid %s param: expecting a string or an array of strings', field);
              }
              break;
          case 'number-array':
              let isValid = Array.isArray(value);
              if (isValid) {
                  value = _.map(value, v => {
                      v = checkType.strToFloat(v);
                      if (typeof v !== 'number') {
                          isValid = false;
                      }
                      return v;
                  });
              }
              if (!isValid) {
                  throw new Err('Invalid %s param: expecting a number or an array of numbers', field);
              }
              obj[field] = value;
              break;
          case 'array':
              if (!Array.isArray(value)) {
                  throw new Err('Invalid %s param type %s given, was expecting an array',
                      field, type);
              }
              break;
          case 'integer':
              if (!Number.isInteger(value)) {
                  throw new Err('Invalid %s param type %s given, was expecting an integer',
                      field, type);
              }
              break;
          case 'zoom':
              if (!qidx.isValidZoom(value)) {
                  throw new Err('Invalid %s param - an integer zoom value was expected', field);
              }
              break;
          default:
              if (type !== expType) {
                  throw new Err('Invalid %s param type %s given, was expecting %s',
                      field, type, expType);
              }
              break;
      }
  
      // validate ranges
      switch (expType) {
          case 'number':
          case 'integer':
          case 'zoom':
              if (min !== undefined && value < min) {
                  throw new Err('Invalid %s param - must be at least %d, but given %d',
                      field, min, value);
              }
              if (max !== undefined && value > max) {
                  throw new Err('Invalid %s param - must be at most %d, but given %d',
                      field, max, value);
              }
              break;
          case 'string':
              if (min !== undefined && value.length < min) {
                  throw new Err('Invalid %s param - the string must be at least %d symbols',
                      field, min);
              }
              break;
          case 'boolean':
              if (value === false) {
                  // convert false into undefined
                  delete obj[field];
                  return false;
              }
              break;
          case 'string-array':
          case 'number-array':
              if (min !== undefined && value.length < min) {
                  throw new Err('Invalid %s param - it must have at least %d values, but given %d',
                      field, min, value.length);
              }
              if (max !== undefined && value.length > max) {
                  throw new Err('Invalid %s param - it must have at least %d values, but given %d',
                      field, max, value.length);
              }
              break;
      }
  
      return true;
  }
func_documentation_string: Utility method to check the type of the object's property