private void maximize() {
    if (peer == null || isMaximized()) {
      return;
    }
    if (!undecorated) {
      CWrapper.NSWindow.zoom(getNSWindowPtr());
    } else {
      deliverZoom(true);

      // We need an up to date size of the peer, so we flush the native events
      // to be sure that there are no setBounds requests in the queue.
      LWCToolkit.flushNativeSelectors();
      this.normalBounds = peer.getBounds();
      Rectangle maximizedBounds = peer.getMaximizedBounds();
      setBounds(
          maximizedBounds.x, maximizedBounds.y, maximizedBounds.width, maximizedBounds.height);
    }
  }
  /*
   * Called by the delegate to dispatch the event to Java. Event
   * coordinates are relative to non-client window are, i.e. the top-left
   * point of the client area is (insets.top, insets.left).
   */
  @Override
  public void notifyMouseEvent(
      int id,
      long when,
      int button,
      int x,
      int y,
      int screenX,
      int screenY,
      int modifiers,
      int clickCount,
      boolean popupTrigger,
      byte[] bdata) {
    // TODO: fill "bdata" member of AWTEvent
    Rectangle r = getBounds();
    // findPeerAt() expects parent coordinates
    LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
    LWWindowPeer lastWindowPeer =
        (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
    LWWindowPeer curWindowPeer = (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;

    if (id == MouseEvent.MOUSE_EXITED) {
      // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
      // to a peer from another window. So we must first check if this peer is
      // the same as lastWindowPeer
      if (lastWindowPeer == this) {
        if (isEnabled()) {
          Point lp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
          Component target = lastMouseEventPeer.getTarget();
          postMouseEnteredExitedEvent(
              target,
              MouseEvent.MOUSE_EXITED,
              when,
              modifiers,
              lp,
              screenX,
              screenY,
              clickCount,
              popupTrigger,
              button);
        }
        lastMouseEventPeer = null;
      }
    } else {
      if (targetPeer != lastMouseEventPeer) {
        // lastMouseEventPeer may be null if mouse was out of Java windows
        if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
          // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
          // later), in which case lastWindowPeer is another window
          if (lastWindowPeer != this) {
            Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
            // Additionally translate from this to lastWindowPeer coordinates
            Rectangle lr = lastWindowPeer.getBounds();
            oldp.x += r.x - lr.x;
            oldp.y += r.y - lr.y;
            Component target = lastMouseEventPeer.getTarget();
            postMouseEnteredExitedEvent(
                target,
                MouseEvent.MOUSE_EXITED,
                when,
                modifiers,
                oldp,
                screenX,
                screenY,
                clickCount,
                popupTrigger,
                button);
          } else {
            Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
            Component target = lastMouseEventPeer.getTarget();
            postMouseEnteredExitedEvent(
                target,
                MouseEvent.MOUSE_EXITED,
                when,
                modifiers,
                oldp,
                screenX,
                screenY,
                clickCount,
                popupTrigger,
                button);
          }
        }
        lastMouseEventPeer = targetPeer;
        if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
          Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
          Component target = targetPeer.getTarget();
          postMouseEnteredExitedEvent(
              target,
              MouseEvent.MOUSE_ENTERED,
              when,
              modifiers,
              newp,
              screenX,
              screenY,
              clickCount,
              popupTrigger,
              button);
        }
      }
      // TODO: fill "bdata" member of AWTEvent

      int eventButtonMask = (button > 0) ? MouseEvent.getMaskForButton(button) : 0;
      int otherButtonsPressed = modifiers & ~eventButtonMask;

      // For pressed/dragged/released events OS X treats other
      // mouse buttons as if they were BUTTON2, so we do the same
      int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;

      // MOUSE_ENTERED/EXITED are generated for the components strictly under
      // mouse even when dragging. That's why we first update lastMouseEventPeer
      // based on initial targetPeer value and only then recalculate targetPeer
      // for MOUSE_DRAGGED/RELEASED events
      if (id == MouseEvent.MOUSE_PRESSED) {

        // Ungrab only if this window is not an owned window of the grabbing one.
        if (!isGrabbing()
            && grabbingWindow != null
            && grabbingWindow != getOwnerFrameDialog(this)) {
          grabbingWindow.ungrab();
        }
        if (otherButtonsPressed == 0) {
          mouseClickButtons = eventButtonMask;
        } else {
          mouseClickButtons |= eventButtonMask;
        }

        mouseDownTarget[targetIdx] = targetPeer;
      } else if (id == MouseEvent.MOUSE_DRAGGED) {
        // Cocoa dragged event has the information about which mouse
        // button is being dragged. Use it to determine the peer that
        // should receive the dragged event.
        targetPeer = mouseDownTarget[targetIdx];
        mouseClickButtons &= ~modifiers;
      } else if (id == MouseEvent.MOUSE_RELEASED) {
        // TODO: currently, mouse released event goes to the same component
        // that received corresponding mouse pressed event. For most cases,
        // it's OK, however, we need to make sure that our behavior is consistent
        // with 1.6 for cases where component in question have been
        // hidden/removed in between of mouse pressed/released events.
        targetPeer = mouseDownTarget[targetIdx];

        if ((modifiers & eventButtonMask) == 0) {
          mouseDownTarget[targetIdx] = null;
        }

        // mouseClickButtons is updated below, after MOUSE_CLICK is sent
      }

      // check if we receive mouseEvent from outside the window's bounds
      // it can be either mouseDragged or mouseReleased
      if (curWindowPeer == null) {
        // TODO This can happen if this window is invisible. this is correct behavior in this case?
        curWindowPeer = this;
      }
      if (targetPeer == null) {
        // TODO This can happen if this window is invisible. this is correct behavior in this case?
        targetPeer = this;
      }

      Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
      if (targetPeer.isEnabled()) {
        if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) {
          postMouseEnteredExitedEvent(
              targetPeer.getTarget(),
              id,
              when,
              modifiers,
              lp,
              screenX,
              screenY,
              clickCount,
              popupTrigger,
              button);

        } else {
          MouseEvent event =
              new MouseEvent(
                  targetPeer.getTarget(),
                  id,
                  when,
                  modifiers,
                  lp.x,
                  lp.y,
                  screenX,
                  screenY,
                  clickCount,
                  popupTrigger,
                  button);
          postEvent(event);
        }
      }

      if (id == MouseEvent.MOUSE_RELEASED) {
        if ((mouseClickButtons & eventButtonMask) != 0 && targetPeer.isEnabled()) {
          postEvent(
              new MouseEvent(
                  targetPeer.getTarget(),
                  MouseEvent.MOUSE_CLICKED,
                  when,
                  modifiers,
                  lp.x,
                  lp.y,
                  screenX,
                  screenY,
                  clickCount,
                  popupTrigger,
                  button));
        }
        mouseClickButtons &= ~eventButtonMask;
      }
    }
    notifyUpdateCursor();
  }