!function(RegExpProto, _RegExp){
  function assertRegExpWrapper(fn){
    return function(){
      assert(cof(this) === REGEXP);
      return fn(this);
    }
  }
  
  // RegExp allows a regex with flags as the pattern
  if(DESC && !function(){try{return RegExp(/a/g, 'i') == '/a/i'}catch(e){}}()){
    RegExp = function RegExp(pattern, flags){
      return new _RegExp(cof(pattern) == REGEXP && flags !== undefined
        ? pattern.source : pattern, flags);
    }
    forEach.call(getNames(_RegExp), function(key){
      key in RegExp || defineProperty(RegExp, key, {
        configurable: true,
        get: function(){ return _RegExp[key] },
        set: function(it){ _RegExp[key] = it }
      });
    });
    RegExpProto[CONSTRUCTOR] = RegExp;
    RegExp[PROTOTYPE] = RegExpProto;
    hidden(global, REGEXP, RegExp);
  }
  
  // 21.2.5.3 get RegExp.prototype.flags()
  if(/./g.flags != 'g')defineProperty(RegExpProto, 'flags', {
    configurable: true,
    get: assertRegExpWrapper(createReplacer(/^.*\/(\w*)$/, '$1', true))
  });
  
  // 21.2.5.12 get RegExp.prototype.sticky()
  // 21.2.5.15 get RegExp.prototype.unicode()
  forEach.call(array('sticky,unicode'), function(key){
    key in /./ || defineProperty(RegExpProto, key, DESC ? {
      configurable: true,
      get: assertRegExpWrapper(function(){
        return false;
      })
    } : descriptor(5, false));
  });
  
  setSpecies(RegExp);
}(RegExp[PROTOTYPE], RegExp);