public void remove(int index) {
    synchronized (treeLock) {
      int n = nChildren - 1;

      if (index < 0 && index > n) {
        return;
      }

      Component c = children[index];

      if ((c.flags & IS_ADD_NOTIFIED) != 0) {
        c.removeNotify();
      }

      if (layoutm != null) {
        layoutm.removeLayoutComponent(c);
      }

      // Remove from container
      c.parent = null;
      if (index > -1 && index < n) {
        System.arraycopy(children, index + 1, children, index, n - index);
      }
      children[n] = null;
      nChildren--;

      if ((cntrListener != null) || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0) {
        AWTEvent.sendEvent(ContainerEvt.getEvent(this, ContainerEvent.COMPONENT_REMOVED, c), false);
      }

      if ((flags & IS_VALID) != 0) invalidate();

      c.flags &= ~IS_PARENT_SHOWING;
      c.propagateParentShowing(false);

      // Like in addImpl, this wouldn't be required in case we are subsequently
      // validated, again. However, native widgets cause a repaint regardless
      // of this validation
      if ((c.flags & IS_NATIVE_LIKE) != 0) repaint(c.x, c.y, c.width, c.height);
    }
  }
  protected void addImpl(Component child, Object constraints, int index) {

    synchronized (treeLock) {
      if (index < -1 || index > nChildren) {
        throw new IllegalArgumentException("bad index: " + index);
      }
      // This test isn't done because we actually need this functionality
      // for the native windowing system
      // else if (child instanceof Window) {
      //   throw new IllegalArgumentException("component is Window");
      // }
      else if (child instanceof Container && this.parent == child) {
        throw new IllegalArgumentException("child is a bad container");
      }

      if (child.parent != null) {
        child.parent.remove(child);
      }

      if (children == null) {
        children = new Component[3];
      } else if (nChildren == children.length) {
        Component[] old = children;
        children = new Component[nChildren * 2];
        System.arraycopy(old, 0, children, 0, nChildren);
      }

      if (index < 0 || nChildren == 0 || index == nChildren) { // append
        children[nChildren] = child;
      } else if (index < nChildren) { // insert at index
        System.arraycopy(children, index, children, index + 1, nChildren - index);
        children[index] = child;
      }

      nChildren++;
      child.parent = this;

      if ((flags & IS_VALID) != 0) invalidate();

      // if we are already addNotified (this is a subsequent add),
      // we immediately have to addNotify the child, too
      if ((flags & IS_ADD_NOTIFIED) != 0) {
        child.addNotify();

        // This isn't required in case we are subsequently validated (what is the
        // correct thing to do), but native widgets would cause a repaint regardless
        // of that. Comment this out if you believe in correct apps
        if ((child.flags & IS_NATIVE_LIKE) != 0) child.repaint();
      }

      // inherit parent attributes (if not overriden by child)
      if ((flags & (IS_PARENT_SHOWING | IS_VISIBLE)) == (IS_PARENT_SHOWING | IS_VISIBLE)) {
        child.flags |= IS_PARENT_SHOWING;
        child.propagateParentShowing(false);
      }
      if ((child.flags & IS_BG_COLORED) == 0) child.propagateBgClr(bgClr);
      if ((child.flags & IS_FG_COLORED) == 0) child.propagateFgClr(fgClr);
      if ((child.flags & IS_FONTIFIED) == 0) child.propagateFont(font);

      // Some LayoutManagers track adding/removing components. Since this seems to be
      // done after a potential addNotify, inform them here
      // (wouldn't it be nice to have a single LayoutManager interface?)
      if (layoutm != null) {
        if (layoutm instanceof LayoutManager2) {
          ((LayoutManager2) layoutm).addLayoutComponent(child, constraints);
        }
        if (constraints instanceof String) {
          layoutm.addLayoutComponent((String) constraints, child);
        }
      }

      if ((cntrListener != null) || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0) {
        AWTEvent.sendEvent(
            ContainerEvt.getEvent(this, ContainerEvent.COMPONENT_ADDED, child), false);
      }
    }
  }