docs: function setValueToType(context) {
    var t, value, parts;
    //console.log('\nsetValueToType', util.inspect(context, {depth: null}));
    if (context.schema.types) {
      //console.log('have types, checking for value', context.schema, context.newData);
      // Return default value if we don't have a value
      if (context.newData !== undefined) {
        //console.log('have types and a value', context.schema, context.newData);
        //if (schema.type && schema.type instanceof Array) {
        //}
  
        // Go through possible types and return first one that returns a value
        var thrown;
        for (t in context.schema.types) {
          thrown = false;
          //console.log('checking type ' + t + ' for ' + context.parameterName, context.schema.types[t]);
          try {
            if ((value = doValidateAdd(merge({}, context, {
                  data: undefined,
                  schema: context.schema.types[t]
                }))) !== undefined) {
              //console.log('success', value);
              context.data = value;
              //console.log(util.inspect(context, {depth: null}));
              return context.data;
            }
          } catch(err) {
            //console.log('types error thrown', err);
            if (!(err instanceof errors.DataTypeError)) {
              //console.log('error is not a DataTypeError - rethrowing');
              throw err;
            }
            thrown = err;
            //console.log('Caught a type error - not that type');
          }
        }
  
        if (thrown) {
          //console.log('throwing error', util.inspect(context, {depth: null}));
          //console.log(context);
          throw new errors.DataTypeError(typeof context.newData + ' value is '
              + 'not allowed' + (thrown.extra && thrown.extra.parameterName ?
              ' for ' + thrown.extra.parameterName : (context.parameterName ? 
              ' for ' + context.parameterName : '')), context);
        }
      }
    } else {
      if (context.schema.type instanceof Object) {
        if (context.newData !== undefined || context.schema.required) {
          if (!(context.schema.required && context.newData === undefined)
              && !(context.newData instanceof Object)) {
            throw new errors.DataTypeError('Value'
                + (context.parameterName ? ' for ' + context.parameterName : '')
                + ' must be an object (' + typeof context.newData + ' given)',
                context);
          }
  
          //console.log('\nstart', context);
  
          var newData;
          if (context.data === undefined
              || (shouldReplace(context) && context.newData !== undefined)) {
            newData = {};
          } else {
            newData = context.data;
          }
  
          var newValue;
          for (t in context.schema.type) {
            //console.log('checking newData value of ' + t);
            if ((newValue = doValidateAdd(merge({}, context, {
              schema:context.schema.type[t],
              newData: (context.newData ? context.newData[t] : undefined),
              data: newData[t],
              parameterName: (context.parameterName ? context.parameterName + '.'
                  : '') + t
            }))) !== undefined) {
              newData[t] = newValue;
            }
          }
  
          if (Object.keys(newData).length || context.newData !== undefined) {
            context.data = newData;
          }
        }
      } else if (context.newData !== undefined) {
        // If type is null start again the original schema for the value
        if (context.schema.type === null) { // magical value to represent the schema (schema within the schema)
          // Restart with base schema
          //console.log('!!!!!!!restarting with base schema', merge({}, context, {
          //  schema: context.baseSchema
          //}));
  
          if ((value = doValidateAdd(merge({}, context, {
            schema: context.baseSchema
          }))) !== undefined) {
            context.data = value;
            //console.log('got a value from null schema', util.inspect(context, {depth: null}));
          }
        } else if (typeof context.schema.type === 'string') { // A simple type or instance of a certain prototype
          //console.log('type given as string', context.schema.type);
          switch (context.schema.type) {
            case 'any':
              if (context.newData !== undefined) {
                context.data = context.newData;
              }
              break;
            case 'Number':
            case 'String':
            case 'Boolean':
            case 'Function':
              // Change Function (prototype) to function (typeof)
              context.schema.type = context.schema.type.toLowerCase();
            case 'function':
            case 'number':
            case 'string':
            case 'boolean':
              if (context.newData !== undefined) {
                if (typeof context.newData === context.schema.type) {
                  parts = [];
                  
                  // Validate string against regex if we have one
                  if (context.schema.type === 'string' && context.schema.regex
                      && !context.schema.regex.test(context.newData)) {
                    throw new errors.DataInvalidError('Value of \''
                        + context.newData + '\'' + (context.parameterName ?
                        ' for ' + context.parameterName : '') + ' does not meet '
                        + 'the required pattern of '
                        + context.schema.regex.toString(), context);
                  }
                  // Validate new value against values if have them
                  if ((context.schema.type === 'number'
                      || context.schema.type === 'string')
                      && context.schema.values
                      && context.schema.values.indexOf(context.newData) === -1) {
                    throw new errors.DataInvalidError('Value of \''
                        + context.newData + '\'' + (context.parameterName ?
                        ' for ' + context.parameterName : '') + ' is not one '
                        + 'of the allowed values ('
                        + context.schema.values.join(', ') + ')', context);
                  }
  
                  // Check number range or string length if have min/max
                  if (context.schema.type === 'number') {
                    if ((context.schema.min !== undefined
                        && context.newData < context.schema.min)
                        || (context.schema.max !== undefined
                        && context.newData >= context.schema.max)) {
                      if (context.schema.min !== undefined) {
                        parts.push('greater than or equal to '
                            + context.schema.min);
                      }
                      if (context.schema.max !== undefined) {
                        parts.push('less than ' + context.schema.max);
                      }
                      throw new errors.DataRangeError('Value'
                      + (context.parameterName ? ' for ' + context.parameterName
                      : '') + ' must be '
                          + parts.join(' and '), context);
                    }
                  } else if (context.schema.type === 'string') {
                    if ((context.schema.min !== undefined
                        && context.newData.length < context.schema.min)
                        || (context.schema.max !== undefined
                        && context.newData.length > context.schema.max)) {
                      if (context.schema.min !== undefined) {
                        parts.push('atleast ' + context.schema.min
                            + ' characters');
                      }
                      if (context.schema.max !== undefined) {
                        parts.push('no more than ' + context.schema.max
                            + ' characters');
                      }
                      throw new errors.DataRangeError('Value'
                      + (context.parameterName ? ' for ' + context.parameterName
                      : '') + ' must be '
                          + parts.join(' and '), context);
                    }
                  }
  
                  context.data = context.newData;
                } else {
                  throw new errors.DataTypeError('Value'
                      + (context.parameterName ? ' for ' + context.parameterName
                      : '') + ' must be a '
                      + context.schema.type, context);
                }
              }
              break;
            case 'Date':
              context.schema.type = 'date';
            case 'date':
              if (context.newData !== undefined) {
                  if (context.newData instanceof Date) {
                  parts = [];
  
                  if ((context.schema.min !== undefined
                      && context.newData < context.schema.min)
                      || (context.schema.max !== undefined
                      && context.newData >= context.schema.max)) {
                    if (context.schema.min !== undefined) {
                      parts.push('at or after '
                          + context.schema.min);
                    }
                    if (context.schema.max !== undefined) {
                      parts.push('before ' + context.schema.max);
                    }
                    throw new errors.DataRangeError('Value'
                    + (context.parameterName ? ' for ' + context.parameterName
                    : '') + ' must be '
                        + parts.join(' and '), context);
                  }
  
                  context.data = context.newData;
                } else {
                  throw new errors.DataTypeError('Value'
                      + (context.parameterName ? ' for ' + context.parameterName
                      : '') + ' must be a '
                      + context.schema.type, context);
                }
              }
              break;
            case 'Null':
              context.schema.type = 'null';
            case 'null':
              if (context.newData !== undefined) {
                if (context.newData === null) {
                  context.data = null;
                } else {
                  throw new errors.DataTypeError('Value'
                      + (context.parameterName ? ' for ' + context.parameterName
                      : '') + ' must be a '
                      + context.schema.type, context);
                }
              }
              break;
            default: /// @TODO Think of a safer way of doing this
              if (context.newData !== undefined) {
                var type;
                try {
                  type = eval(context.schema.type);
                } catch(error) {
                  throw new errors.SchemaError('Error determining type to test ' 
                      + 'against'
                      + (context.parameterName ? ' for ' + context.parameterName
                      : '')
                      + ': ' + error.toString(), context);
                }
                if (context.newData instanceof type) {
                  context.data = context.newData;
                } else {
                  throw new errors.DataTypeError('Value'
                      + (context.parameterName ? ' for ' + context.parameterName
                      : '') + ' must be a '
                      + context.schema.type, context);
                }
              }
              break;
          }
        }
      }
    }
  
    if (context.data === undefined
        && context.schema.default !== undefined) {
      /// @TODO Should we be checking the baseSchema default value as well?
      context.data = context.schema.default;
    }
  
    if (context.data === undefined && context.schema.required) {
      throw new errors.DataRequiredError('Value'
          + (context.parameterName ? ' for ' + context.parameterName : '')
          + ' required', context);
    }
  
    return context.data;
  }