(function() {
  let obj = {
    foo() {}
  };

  window.addEventListener('message', (ev) => {
    let name = JSON.parse(ev.data).name;

    obj[ev.data](); // NOT OK: might not be a function

    obj[name]();    // NOT OK: might not be a function

    try {
      obj[name]();  // OK: exception is caught
    } catch(e) {}

    let fn = obj[name];
    fn();           // NOT OK: might not be a function
    if (typeof fn == 'function') {
      fn();         // NOT OK: might be `valueOf`
      obj[name]();  // NOT OK: might be `__defineSetter__`
      new fn();     // NOT OK: might be `valueOf` or `toString`
    }

    if (obj[name])
      obj[name]();  // NOT OK
    if (typeof obj[name] === 'function')
      obj[name]();  // NOT OK

    if (obj.hasOwnProperty(name)) {
      obj[name]();  // NOT OK, but not flagged
    }

    let key = "$" + name;
    obj[key]();     // NOT OK
    if (typeof obj[key] === 'function')
      obj[key]();   // OK - but still flagged

    if (typeof fn === 'function') {
      fn.apply(obj); // OK
    }
  });

  let obj2 = Object.create(null);
  obj2.foo = function() {};

  window.addEventListener('message', (ev) => {
    let name = JSON.parse(ev.data).name;
    let fn = obj2[name];
    fn();           // NOT OK: might not be a function
    if (typeof fn == 'function')
      fn();         // OK: cannot be from prototype
  });
})();
