public void layout() {
if (isLayoutInvalid) {
menu.layout();
final Size menuSize = menu.getRequiredSize(Size.createMax());
menu.setSize(menuSize);
menu.setLocation(new Location(0, 0));
final Location containerLocation = new Location(at);
final Size bounds = getViewManager().getOverlaySize();
if (containerLocation.getX() < 0) {
containerLocation.setX(0);
} else if (containerLocation.getX() + menuSize.getWidth() > bounds.getWidth()) {
containerLocation.setX(bounds.getWidth() - menuSize.getWidth());
}
if (containerLocation.getY() < 0) {
containerLocation.setY(0);
} else if (containerLocation.getY() + menuSize.getHeight() > bounds.getHeight()) {
containerLocation.setY(bounds.getHeight() - menuSize.getHeight());
}
if (submenu != null) {
submenu.layout();
final Size submenuSize = submenu.getRequiredSize(Size.createMax());
submenu.setSize(submenuSize);
int submenuOffset = submenuOffset();
final Location menuLocation = new Location();
final int containerBottom = containerLocation.getY() + submenuOffset + submenuSize.getHeight();
if (containerBottom > bounds.getHeight()) {
final int overstretch = containerBottom - bounds.getHeight();
submenuOffset -= overstretch;
}
final Location submenuLocation = new Location(0, submenuOffset);
final boolean placeToLeft = at.getX() + menuSize.getWidth() + submenuSize.getWidth() < getViewManager().getOverlaySize().getWidth();
if (placeToLeft) {
submenuLocation.setX(menuSize.getWidth() - MENU_OVERLAP);
} else {
menuLocation.setX(submenuSize.getWidth() - MENU_OVERLAP);
containerLocation.move(-submenu.getSize().getWidth() + MENU_OVERLAP, 0);
}