function Lazy(source) {
    if (isArray(source)) {
      return new ArrayWrapper(source);

    } else if (typeof source === "string") {
      return new StringWrapper(source);

    } else if (source instanceof Sequence) {
      return source;
    }

    if (Lazy.extensions) {
      var extensions = Lazy.extensions, length = extensions.length, result;
      while (!result && length--) {
        result = extensions[length](source);
      }
      if (result) {
        return result;
      }
    }

    return new ObjectWrapper(source);
  }
Wraps an object and returns a {@link Sequence}. For `null` or `undefined`,
simply returns an empty sequence (see {@link Lazy.strict} for a stricter
implementation).

- For **arrays**, Lazy will create a sequence comprising the elements in
  the array (an {@link ArrayLikeSequence}).
- For **objects**, Lazy will create a sequence of key/value pairs
  (an {@link ObjectLikeSequence}).
- For **strings**, Lazy will create a sequence of characters (a
  {@link StringLikeSequence}).

@public
@param {Array|Object|string} source An array, object, or string to wrap.
@returns {Sequence} The wrapped lazy object.

@exampleHelpers
// Utility functions to provide to all examples
function increment(x) { return x + 1; }
function isEven(x) { return x % 2 === 0; }
function isPositive(x) { return x > 0; }
function isNegative(x) { return x < 0; }

// HACK!
// autodoc tests for private methods don't pull in all variables defined
// within the current scope :(
var isArray = Array.isArray;

@examples
Lazy([1, 2, 4])       // instanceof Lazy.ArrayLikeSequence
Lazy({ foo: "bar" })  // instanceof Lazy.ObjectLikeSequence
Lazy("hello, world!") // instanceof Lazy.StringLikeSequence
Lazy()                // sequence: []
Lazy(null)            // sequence: []