Returns the mirror for a specified value or object.

@param {value or Object} value the value or object to retreive the mirror for
@param {boolean} transient indicate whether this object is transient and
should not be added to the mirror cache. The default is not transient.
@returns {Mirror} the mirror reflects the passed value or object
function MakeMirror(value, opt_transient) {
  var mirror;

  // Look for non transient mirrors in the mirror cache.
  if (!opt_transient && mirror_cache_enabled_) {
    for (var id in mirror_cache_) {
      mirror = mirror_cache_[id];
      if (mirror.value() === value) {
        return mirror;
      }
      // Special check for NaN as NaN == NaN is false.
      if (mirror.isNumber() && IsNaN(mirror.value()) &&
          typeof value == 'number' && IsNaN(value)) {
        return mirror;
      }
    }
  }

  if (IS_UNDEFINED(value)) {
    mirror = new UndefinedMirror();
  } else if (IS_NULL(value)) {
    mirror = new NullMirror();
  } else if (IS_BOOLEAN(value)) {
    mirror = new BooleanMirror(value);
  } else if (IS_NUMBER(value)) {
    mirror = new NumberMirror(value);
  } else if (IS_STRING(value)) {
    mirror = new StringMirror(value);
  } else if (IS_SYMBOL(value)) {
    mirror = new SymbolMirror(value);
  } else if (IS_ARRAY(value)) {
    mirror = new ArrayMirror(value);
  } else if (IS_DATE(value)) {
    mirror = new DateMirror(value);
  } else if (IS_FUNCTION(value)) {
    mirror = new FunctionMirror(value);
  } else if (IS_REGEXP(value)) {
    mirror = new RegExpMirror(value);
  } else if (IS_ERROR(value)) {
    mirror = new ErrorMirror(value);
  } else if (IS_SCRIPT(value)) {
    mirror = new ScriptMirror(value);
  } else if (IS_MAP(value) || IS_WEAKMAP(value)) {
    mirror = new MapMirror(value);
  } else if (IS_SET(value) || IS_WEAKSET(value)) {
    mirror = new SetMirror(value);
  } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) {
    mirror = new IteratorMirror(value);
  } else if (ObjectIsPromise(value)) {
    mirror = new PromiseMirror(value);
  } else if (IS_GENERATOR(value)) {
    mirror = new GeneratorMirror(value);
  } else {
    mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE, opt_transient);
  }

  if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror;
  return mirror;
}