utils.js: significant modification of diff behavior

I think it's better, anyway.  I was becoming frustrated by seeing my `Date`s and `Function`s represented as objects within the diffs.  Even more frustrating is when the diff result *appears to be exactly the same* but the assertion failed anyway.  So this is my attempt at making the diffs more friendly and understandable.

Summary of changes:

- Added inner function `emptyRepresentation()`, which is called in the case that your `Object`, `Function` or `Array` has nothing "in" it.  It attempts to make a unique representation of that empty value.
- Added private API function `exports.type()`, which can be used to deduce the type of any given value.  *I exported this function mainly for testing purposes*
- Modified `exports.stringify()` to avoid `JSON.stringify()` in circumstances where `JSON.stringify()` may not be much help.  My only concern here is whether or not we should display a string in double-quotes, as to coincide with `JSON.stringify()` behavior.
  - If `value` is `undefined` or `null`, return `'[undefined]'` or `'[null]'`, respectively.   *It's possible to have strings with these same values, which may lead to confusion, but this is an edge case.*
  - If `value` is not an `Object`, `Function` or `Array`, return result of `value.toString()`.
  - If `value` is an *empty* `Object`, `Function` or `Array`, return result of function `emptyRepresentation()`.
  - If `value` has properties, call `exports.canonicalize()` on it, then return result of `JSON.stringify()`.
- Modified `exports.canonicalize()` to support the above strategy, with a couple slight differences.  The strategy is as follows.  If the value...
  - has already been seen, return string `'[Circular]'`
  - is `undefined`, return string `'[undefined]'`
  - is `null`, return value `null`.  This differs from the `stringify()` behavior, as to provide a valid JSON representation.
  - is not an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method
  - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.
  - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`
- Added many tests

Before:

```
      AssertionError: expected { Object (path, $explicit_fields, ...) } to deeply equal { Object ($accessed, $explicit_fields, ...) }
      + expected - actual
```

After:

```
      AssertionError: expected { Object (path, $explicit_fields, ...) } to deeply equal { Object ($accessed, $explicit_fields, ...) }
      + expected - actual

       {
      +  "$accessed": "{}"
      -  "$accessed": "Fri Sep 12 2014 23:00:10 GMT-0700 (PDT)"
         "$explicit_fields": "[]"
      +  "$registered": "{}"
      -  "$registered": "Fri Sep 12 2014 23:00:10 GMT-0700 (PDT)"
         "author": "Christopher Hiller <chiller@badwing.com>"
         "author.email": "chiller@badwing.com"
         "author.name": "Christopher Hiller"
         "authors": [
           "Christopher Hiller <chiller@badwing.com>"
         ]
      -  "description": "[undefined]"
         "license": "Copyright 2014 Christopher Hiller <chiller@badwing.com>"
         "name": "riffraff"
         "path": "/Volumes/samara/projects/boneskull/test"
      -  "repository": "[undefined]"
         "repository.type": "git"
      -  "repository.url": "[undefined]"
      -  "version": "[undefined]"
       }
```