private Dimension processLayout(Container target, int caller) {
		Dimension result = null;
		synchronized (target.getTreeLock()) {
			layoutInProgress = true;
			if (layoutTable == null) computeLayoutTable(target);
			int nr = getIntProperty("nRows");
			int nc = getIntProperty("nColumns");
			int[] heights = new int[nr];
			int[] widths = new int[nc];
			int nComponents = target.getComponentCount();
			for (int i = 0; i < nComponents; i++) {
				Component comp = target.getComponent(i);
				TableConstraints tc = (TableConstraints) layoutTable.get(comp);
				int column = tc.gridx;
				int row = tc.gridy;
				int width = getIntProperty("width" + column);
				int height = getIntProperty("height" + row);
				if (width == 0) {
					if (caller == MINIMUM_LAYOUT_SIZE_MODE || useStrictGridBagModel) {
						width = getMinimumComponentSize(comp).width;
					} else {
						width = getPreferredComponentSize(comp).width;
					}
					width += 2 * tc.ipadx + tc.insets.left + tc.insets.right;
				}
				if (height == 0) {
					if (caller == MINIMUM_LAYOUT_SIZE_MODE || useStrictGridBagModel) {
						height = getMinimumComponentSize(comp).height;
					} else {
						height = getPreferredComponentSize(comp).height;
					}
					height += 2 * tc.ipady + tc.insets.top + tc.insets.bottom;
				}
				widths[column] = Math.max(widths[column], width);
				heights[row] = Math.max(heights[row], height);
			}
			int width = hGap;
			int height = vGap;
			double[] weightX = new double[nc];
			double[] weightY = new double[nr];
			double totalX = 0;
			double totalY = 0;
			for (int column = 0; column < nc; column++) {
				width += widths[column] + hGap;
				weightX[column] = getDoubleProperty("weightx" + column);
				totalX += weightX[column];
			}
			for (int row = 0; row < nr; row++) {
				height += heights[row] + vGap;
				weightY[row] = getDoubleProperty("weighty" + row);
				totalY += weightY[row];
			}
			if (caller == LAYOUT_CONTAINER_MODE) {
				Dimension size = target.getSize();
				Insets insets = target.getInsets();
				size.width -= insets.left + insets.right;
				size.height -= insets.top + insets.bottom;
				int extraX = size.width - width;
				int extraY = size.height - height;
				int startX = insets.left;
				int startY = insets.top;
				if (totalX == 0) {
					switch (horizontalAlignment) {
					  case LEFT:
						extraX = 0;
						break;
					  case CENTER:
						startX += extraX / 2;
						extraX = 0;
						break;
					  case RIGHT:
						startX += extraX;
						extraX = 0;
						break;
					  case FILL:
						totalX = nc;
						for (int column = 0; column < nc; column++) {
							weightX[column] = 1;
						}
						break;
					}
				}
				if (totalY == 0) {
					switch (verticalAlignment) {
					  case TOP:
						extraY = 0;
						break;
					  case CENTER:
						startY += extraY / 2;
						extraY = 0;
						break;
					  case BOTTOM:
						startY += extraY;
						extraY = 0;
						break;
					  case FILL:
						totalY = nr;
						for (int row = 0; row < nr; row++) {
							weightY[row] = 1;
						}
						break;
					}
				}
				int[] xc = new int[nc];
				int x = hGap + startX;
				for (int column = 0; column < nc; column++) {
					xc[column] = x;
					if (extraX > 0) {
						int pad = (int) Math.round(extraX * weightX[column] / totalX);
						widths[column] += pad;
						extraX -= pad;
						totalX -= weightX[column];
					}
					x += widths[column] + hGap;
				}
				int[] yc = new int[nr];
				int y = vGap + startY;
				for (int row = 0; row < nr; row++) {
					yc[row] = y;
					if (extraY > 0) {
						int pad = (int) Math.round(extraY * weightY[row] / totalY);
						heights[row] += pad;
						extraY -= pad;
						totalY -= weightY[row];
					}
					y += heights[row] + vGap;
				}
				for (int i = 0; i < nComponents; i++) {
					Component comp = target.getComponent(i);
					TableConstraints tc = (TableConstraints) layoutTable.get(comp);
					int column = tc.gridx;
					int row = tc.gridy;
					int bx = xc[column] + tc.insets.left;
					int by = yc[row] + tc.insets.top;
					int bw = widths[column];
					for (int ix = 1; ix < tc.gridwidth && column + ix < nc; ix++) {
						bw += widths[column + ix] + hGap;
					}
					bw -= tc.insets.left + tc.insets.right;
					int bh = heights[row];
					for (int iy = 1; iy < tc.gridheight && row + iy < nr; iy++) {
						bh += heights[row + iy] + vGap;
					}
					bh -= tc.insets.top + tc.insets.bottom;
					Dimension pSize = (useStrictGridBagModel) ? getMinimumComponentSize(comp) : getPreferredComponentSize(comp);
					Rectangle bounds = computeCellBounds(new Rectangle(bx, by, bw, bh), pSize, tc);
					comp.setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
				}
			} else {
				result = new Dimension(width, height);
			}
			layoutInProgress = false;
		}
		return result;
	}