/*
 * Copyright (c) 2010 Marek Kozieł <develop4lasu[at]gmail.com>
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * 
 * Except as contained in this notice, the name(s) of the above
 * copyright holders shall not be used in advertising or otherwise
 * to promote the sale, use or other dealings in this Software
 * without prior written authorization.
 */

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;

import javax.swing.Box;

/**
 * It's {@link GridBagConstraints} rewritten to a builder form.<br />
 * <p>
 * The main function of this class is building {@link GridBagConstraints} in a form easy to be read.
 * </p>
 * <p>
 * {@link #printJavaCode$(GridBagConstraints)} allows to perform an easy conversion of standard constraint form into this builder
 * </p>
 * Created on 2010-04-18
 * <p>
 * <b>Convention:</b>
 * <ul>
 * <li>Methods with '<b>new</b>' prefix are responsible for creating the proper {@link GridConstraintsBuilder} objects</li>
 * <li>Methods with '<b>create</b>' prefix are responsible for creating/providing related objects</li>
 * <li>'<b>Ver</b>' is used as short form of '<b>Vertical</b>' word</li>
 * <li>'<b>Hor</b>' is used as short form of '<b>Horizontal</b>' word</li>
 * <li>Every <b>set</b> method returns the builder that is called on</li>
 * <li>'<b>X</b>' / '<b>Y</b>' on the end of the methods' names are used to increase the visual localisation and correspondence with '<b>Vertical</b>' / '<b>Horizontal</b>' words.</li>
 * <li><b>$</b> on end of methods' names means that it's not allowed to call them without the knowledge of their documentation.</li>
 * </ul>
 * </p>
 * 
 * @author Marek Kozieł
 * @see GridBagConstraints
 * @see GridBagLayout
 * @see GridConstraintsBuilderToCodeConverter
 * @see ComponentPlacement
 * @see GridConstraintsFill
 * @see PlacementKind
 * @see #build()
 * @see #buildOn(Integer, Integer)
 * @see #buildOnX(Integer)
 * @see #buildOnY(Integer)
 * @see #printJavaCode$(GridBagConstraints)
 */
// TODO ? public Integer getX/YCoordinates( GBC / GBB )
public final class GridConstraintsBuilder implements Cloneable {

	/**
	 * Always available after constructor call
	 * 
	 * @see ComponentPlacement
	 */
	private ComponentPlacement	align;

	/**
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	private GridConstraintsFill	fill		= GridConstraintsFill.None;

	/**
	 * Specifies the number of cells in a column for the component's display area.
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	private Integer				heightY		= null;

	/**
	 * The inset from the bottom. This value is subtracted from the Bottom of the rectangle to yield a new location for the Bottom.
	 * <p>
	 * The default value is <code>new Insets(0, 0, 0, 0)</code>.
	 * </p>
	 */
	private int					insetBottom	= 0;

	/**
	 * The inset from the left. This value is added to the Left of the rectangle to yield a new location for the Left edge.
	 * <p>
	 * The default value is <code>new Insets(0, 0, 0, 0)</code>.
	 * </p>
	 */
	private int					insetLeft	= 0;

	/**
	 * The inset from the right. This value is subtracted from the Right of the rectangle to yield a new location for the Right edge.
	 * <p>
	 * The default value is <code>new Insets(0, 0, 0, 0)</code>.
	 * </p>
	 */
	private int					insetRight	= 0;

	/**
	 * The inset from the top. This value is added to the Top of the rectangle to yield a new location for the Top.
	 * <p>
	 * The default value is <code>new Insets(0, 0, 0, 0)</code>.
	 * </p>
	 */
	private int					insetTop	= 0;

	/**
	 * <p>
	 * This field specifies the <b>horizontal internal padding</b> of the component, how much space to add to the minimum width of the component. The width of the component is at least its minimum width plus {@link #getHorIpadX()} pixels.
	 * </p>
	 * <p>
	 * The default value is <code>0</code>.
	 * </p>
	 * 
	 * @see #getHorIpadX()
	 * @see #setHorIpadX(int)
	 * @see #setHorMarginX(int, int, int)
	 * @see GridBagConstraints#ipadx
	 */
	private int					ipadx;

	/**
	 * <p>
	 * This field specifies the <b>vertical internal padding</b>, that is, how much space to add to the minimum height of the component. The height of the component is at least its minimum height plus {@link #getVerIpadY()} pixels.
	 * </p>
	 * <p>
	 * The default value is <code>0</code>.
	 * </p>
	 * 
	 * @see #getVerIpadY()
	 * @see #setVerIpadY(int)
	 * @see #setVerMarginY(int, int, int)
	 * @see GridBagConstraints#ipady
	 */
	private int					ipady;

	/**
	 * Specifies how to distribute extra horizontal space.
	 * <p>
	 * The grid bag layout manager calculates the weight of a column to be the maximum {@link #getWeightX()} of all the components in a column. If the resulting layout is smaller horizontally than the area it needs to fill, the extra space is distributed to each column in proportion to its weight. A
	 * column that has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the left and right edges.
	 * </p>
	 * <p>
	 * The default value of this field is <code>0</code>. {@link #getWeightX()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getWeightX()
	 * @see #setHorizontals(Integer, Integer, Double)
	 * @see #setHorizontals(Integer, Integer, Integer)
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightX(Double)
	 * @see #setWeightX(Integer)
	 * @see GridBagConstraints#weightx
	 */
	private Double				weightX		= null;

	/**
	 * Specifies how to distribute extra vertical space.
	 * <p>
	 * The grid bag layout manager calculates the weight of a row to be the maximum {@link #getWeightY()} of all the components in a row. If the resulting layout is smaller vertically than the area it needs to fill, the extra space is distributed to each row in proportion to its weight. A row that
	 * has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the top and bottom edges.
	 * </p>
	 * <p>
	 * The default value of this field is <code>0</code>. {@link #getWeightY()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getWeightY()
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightY(Double)
	 * @see #setWeightY(Integer)
	 * @see GridBagConstraints#weightx
	 */
	private Double				weightY		= null;

	/**
	 * <p>
	 * Specifies the number of cells in a row for the component's display area.
	 * </p>
	 * <p>
	 * Default value is 1.
	 * </p>
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	private Integer				widthX		= null;

	/**
	 * <p>
	 * Specifies the cell containing the leading edge of the component's display area, where the first cell in a row has {@link #getX()}<code>=0</code>. The leading edge of a component's display area is its left edge for a horizontal, left-to-right container and its right edge for a horizontal,
	 * right-to-left container.<br />
	 * The value {@link GridBagConstraints#RELATIVE} specifies that the component be placed immediately following the component that was added to the container just before this component was added.<br />
	 * The default value is <code>null</code>. {@link #getX()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getX()
	 * @see #isXRelative()
	 * @see #setX(Integer)
	 * @see #setXAsRelative()
	 * @see #setXY(Integer, Integer)
	 * @see GridBagConstraints#gridx
	 */
	private Integer				x			= null;

	/**
	 * <p>
	 * Specifies the cell at the top of the component's display area, where the topmost cell has {@link #getY()}<code>=0</code>. The value {@link GridBagConstraints#RELATIVE} specifies that the component be placed just below the component that was added to the container just before this component
	 * was added. <br />
	 * The default value is <code>null</code>. {@link #getY()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getY()
	 * @see #isYRelative()
	 * @see #setXY(Integer, Integer)
	 * @see #setY(Integer)
	 * @see #setYAsRelative()
	 * @see GridBagConstraints#gridy
	 */
	private Integer				y			= null;

	/**
	 * @throws NullPointerException when given align is <code>null</code>
	 */
	private GridConstraintsBuilder(ComponentPlacement align) {
		if (align == null) { throw new NullPointerException(ComponentPlacement.class.getSimpleName()); }
		this.align = align;
	}

	/**
	 * @throws NullPointerException when given align is <code>null</code>
	 */
	private GridConstraintsBuilder(ComponentPlacement align, Integer gridX, Integer gridY) {
		if (align == null) { throw new NullPointerException(ComponentPlacement.class.getSimpleName()); }
		this.align = align;
		setX(gridX);
		setY(gridY);
	}

	/**
	 * @throws NullPointerException when given align is <code>null</code>
	 */
	private GridConstraintsBuilder(GridBagConstraints constraint) {
		if (constraint == null) { throw new NullPointerException(GridBagConstraints.class.getSimpleName()); }
		this.align = ComponentPlacement.forConstraintValue(constraint.anchor);
		this.fill = GridConstraintsFill.forConstraintValue(constraint.fill);

		this.setX(constraint.gridx);
		this.setY(constraint.gridy);

		this.setWidthX(constraint.gridwidth);
		this.setHeightY(constraint.gridheight);

		this.setWeightX(constraint.weightx);
		this.setWeightY(constraint.weighty);

		Insets insets = constraint.insets;
		if (insets != null) {
			this.setInsets(insets);
		}
		this.setInternalPadding(constraint.ipadx, constraint.ipady);
	}

	/**
	 * @throws NullPointerException when given builder is <code>null</code>
	 */
	private GridConstraintsBuilder(GridConstraintsBuilder builder) {
		if (builder == null) { throw new NullPointerException(GridConstraintsBuilder.class.getSimpleName()); }
		this.align = builder.align;
		this.fill = builder.fill;

		this.x = builder.x;
		this.y = builder.y;

		this.widthX = builder.widthX;
		this.heightY = builder.heightY;

		this.weightX = builder.weightX;
		this.weightY = builder.weightY;

		this.insetBottom = builder.insetBottom;
		this.insetLeft = builder.insetLeft;
		this.insetRight = builder.insetRight;
		this.insetTop = builder.insetTop;

		this.ipadx = builder.ipadx;
		this.ipady = builder.ipady;
	}

	/**
	 * Will do not succeed until {@link #getX()} and {@link #getY()} will
	 * 
	 * @return not <code>null</code> value<br />
	 * @see #buildOn(Integer, Integer)
	 * @see #buildOnX(Integer)
	 * @see #buildOnY(Integer)
	 */
	public GridBagConstraints build() {
		return buildOn(x, y);
	}

	/**
	 * @return not <code>null</code> value<br />
	 * @throws NullPointerException if given <code>x</code> or <code>y</code> is <code>null</code>
	 * @see #build()
	 * @see #buildOnX(Integer)
	 * @see #buildOnY(Integer)
	 */
	public GridBagConstraints buildOn(Integer x, Integer y) {
		if (x == null) { throw new NullPointerException("X coordinates"); }
		if (y == null) { throw new NullPointerException("Y coordinates"); }
		// if (x==null) {throw new IllegalStateException("");}
		GridBagConstraints ret = new GridBagConstraints();
		// General
		ret.anchor = this.align.getValueForConstraint();
		ret.fill = this.fill.getValueForConstraint();

		ret.gridx = x;
		if (this.widthX != null) {
			ret.gridwidth = this.widthX;
		}
		ret.gridy = y;
		if (this.heightY != null) {
			ret.gridheight = this.heightY;
		}

		ret.weightx = this.getFinalWeightX();
		ret.weighty = this.getFinalWeightY();

		ret.insets = new Insets(insetTop, insetLeft, insetBottom, insetRight);
		ret.ipadx = this.ipadx;
		ret.ipady = this.ipady;

		return ret;
	}

	/**
	 * @return not <code>null</code> value<br />
	 * @throws NullPointerException if given <code>x</code> or {@link #getY()} is <code>null</code>
	 * @see #build()
	 * @see #buildOn(Integer, Integer)
	 * @see #buildOnY(Integer)
	 */
	public GridBagConstraints buildOnX(Integer x) {
		return buildOn(x, y);
	}

	/**
	 * @return not <code>null</code> value<br />
	 * @throws NullPointerException if given {@link #getX()} or <code>y</code> is <code>null</code>
	 * @see #build()
	 * @see #buildOn(Integer, Integer)
	 * @see #buildOnX(Integer)
	 */
	public GridBagConstraints buildOnY(Integer y) {
		return buildOn(x, y);
	}

	@Override
	public GridConstraintsBuilder clone() {
		return new GridConstraintsBuilder(this);
	}

	/**
	 * @return <code>true</code> if after calling {@link #provide()} result will be same as given {@link GridBagConstraints}
	 */
	public boolean equals(GridBagConstraints gcb) {
		if (gcb == null) { return false; }
		if (this.align.getValueForConstraint() != gcb.anchor) { return false; }
		if (this.fill.getValueForConstraint() != gcb.fill) { return false; }
		{
			Insets insets = gcb.insets;
			if (this.insetBottom != (insets != null ? insets.bottom : 0)) { return false; }
			if (this.insetLeft != (insets != null ? insets.left : 0)) { return false; }
			if (this.insetRight != (insets != null ? insets.right : 0)) { return false; }
			if (this.insetTop != (insets != null ? insets.top : 0)) { return false; }
		}

		if (this.getFinalHeightY() != gcb.gridheight) { return false; }
		if (this.getFinalWidthX() != gcb.gridwidth) { return false; }
		if (this.getFinalWeightX() != gcb.weightx) { return false; }
		if (this.getFinalWeightY() != gcb.weighty) { return false; }

		if (this.x == null) { return false; }
		if (this.x != gcb.gridx) { return false; }

		if (this.y == null) { return false; }
		if (this.y != gcb.gridy) { return false; }

		return true;
	}

	/**
	 * @return <code>true</code> if both object have same content
	 */
	public boolean equals(GridConstraintsBuilder gcb) {
		if (gcb == null) { return false; }
		if (this.align != gcb.align) { return false; }
		if (this.fill != gcb.fill) { return false; }

		if (this.insetBottom != gcb.insetBottom) { return false; }
		if (this.insetLeft != gcb.insetLeft) { return false; }
		if (this.insetRight != gcb.insetRight) { return false; }
		if (this.insetTop != gcb.insetTop) { return false; }

		if (this.getFinalHeightY() != gcb.getFinalHeightY()) { return false; }
		if (this.getFinalWidthX() != gcb.getFinalWidthX()) { return false; }
		if (this.getFinalWeightX() != gcb.getFinalWeightX()) { return false; }
		if (this.getFinalWeightY() != gcb.getFinalWeightY()) { return false; }

		if (this.x != gcb.x) {
			if (this.x == null) { return false; }
			if (gcb.x == null) { return false; }
			if (!gcb.x.equals(gcb.x)) { return false; }
		}
		if (this.y != gcb.y) {
			if (this.y == null) { return false; }
			if (gcb.y == null) { return false; }
			if (!gcb.y.equals(gcb.y)) { return false; }
		}
		return true;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof GridConstraintsBuilder) { return equals((GridConstraintsBuilder) obj); }
		if (obj instanceof GridBagConstraints) { return equals((GridBagConstraints) obj); }
		return false;
	}

	/**
	 * <p>
	 * Ensure the component to fill its display area entirely.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder fillBoth() {
		this.fill = GridConstraintsFill.Both;
		return this;
	}

	/**
	 * <p>
	 * Make the component wide enough to fill its display area horizontally. But do not affect vertical fill.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder fillHorizontal() {
		switch (this.fill) {
		case Both:
		case Vertical:
			this.fill = GridConstraintsFill.Both;
			break;
		default:
			this.fill = GridConstraintsFill.Horizontal;
			break;
		}
		return this;
	}

	/**
	 * <p>
	 * Ensures the component to do not resize.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder fillNone() {
		this.fill = GridConstraintsFill.None;
		return this;
	}

	/**
	 * <p>
	 * Make the component wide enough to fill its display area vertically. But do not affect horizontal fill.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder fillVertical() {
		switch (this.fill) {
		case Both:
		case Horizontal:
			this.fill = GridConstraintsFill.Both;
			break;
		default:
			this.fill = GridConstraintsFill.Horizontal;
			break;
		}
		return this;
	}

	/**
	 * @return the align (always not <code>null</code>)
	 * @see #getAlign()
	 * @see #getAlignValue()
	 * @see #setAlign(ComponentPlacement)
	 * @see ComponentPlacement
	 */
	public ComponentPlacement getAlign() {
		return align;
	}

	/**
	 * @return the align same as the one in {@link GridBagConstraints#anchor}
	 * @see #getAlign()
	 * @see #getAlignValue()
	 * @see #setAlign(ComponentPlacement)
	 * @see ComponentPlacement
	 * @see ComponentPlacement#getValueForConstraint()
	 */
	public int getAlignValue() {
		return align.getValueForConstraint();
	}

	/**
	 * <p>
	 * This field is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @return the fill similar with {@link GridBagConstraints#fill}
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #isFilledBoth()
	 * @see #isFilledHorizontal()
	 * @see #isFilledNone()
	 * @see #isFilledVertical()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsFill
	 */
	public GridConstraintsFill getFill() {
		return fill;
	}

	/**
	 * <p>
	 * This field is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @return the fill same as the one in {@link GridBagConstraints#fill}
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsFill
	 * @see GridConstraintsFill#getValueForConstraint()
	 */
	public int getFillValue() {
		return fill.getValueForConstraint();
	}

	/**
	 * @same as {@link #getHeightY()} just for <code>null</code> default value is returned
	 */
	public int getFinalHeightY() {
		if (heightY == null) { return defaultConstraint.gridheight; }
		return heightY;
	}

	/**
	 * <p>
	 * Specifies how to distribute extra horizontal space.
	 * </p>
	 * <p>
	 * The grid bag layout manager calculates the weight of a column to be the maximum {@link #getWeightX()} of all the components in a column. If the resulting layout is smaller horizontally than the area it needs to fill, the extra space is distributed to each column in proportion to its weight. A
	 * column that has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the left and right edges.
	 * </p>
	 * 
	 * @return for <code>null</code> default value is returned
	 * @see #getFinalWeightX()
	 * @see #getWeightX()
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightX(Double)
	 * @see #setWeightX(Integer)
	 * @see GridBagConstraints#weightx
	 */
	public double getFinalWeightX() {
		if (weightX == null) { return defaultConstraint.weightx; }
		return weightX;
	}

	/**
	 * @return for <code>null</code> default value is returned
	 * @see #getFinalWeightY()
	 * @see #getWeightY()
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightY(Double)
	 * @see #setWeightY(Integer)
	 * @see GridBagConstraints#weighty
	 */
	public double getFinalWeightY() {
		if (weightY == null) { return defaultConstraint.weighty; }
		return weightY;
	}

	public int getFinalWidthX() {
		if (widthX == null) { return defaultConstraint.gridwidth; }
		return widthX;
	}

	/**
	 * Specifies the number of cells in a column for the component's display area.
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	public Integer getHeightY() {
		return heightY;
	}

	/**
	 * <p>
	 * Specifies the <b>horizontal internal padding</b> of the component, how much space to add to the minimum width of the component. The width of the component is at least its minimum width plus {@link #getHorIpadX()} pixels.
	 * </p>
	 * <p>
	 * The default value is <code>0</code>.
	 * </p>
	 * 
	 * @see #getHorIpadX()
	 * @see #setHorIpadX(int)
	 * @see #setVerMarginY(int, int, int)
	 * @see GridBagConstraints#ipadx
	 */
	public int getHorIpadX() {
		return ipadx;
	}

	/**
	 * <p>
	 * The inset from the bottom. This value is subtracted from the Bottom of the rectangle to yield a new location for the Bottom.
	 * </p>
	 * 
	 * @see #getInsetBottom()
	 * @see #getInsets()
	 * @see #isAnyInsetWithNotDefalutValue()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsets(Insets)
	 * @see Insets#bottom
	 */
	public int getInsetBottom() {
		return insetBottom;
	}

	/**
	 * <p>
	 * The inset from the left. This value is added to the Left of the rectangle to yield a new location for the Left edge.
	 * </p>
	 * 
	 * @see #getInsetLeft()
	 * @see #getInsets()
	 * @see #isAnyInsetWithNotDefalutValue()
	 * @see #setHorInsetsX(int, int)
	 * @see #setHorMarginX(int, int, int)
	 * @see #setInsetLeft(int)
	 * @see #setInsets(Insets)
	 * @see GridConstraintsBuilder#createInsets(int, int, int, int)
	 * @see Insets#left
	 */
	public int getInsetLeft() {
		return insetLeft;
	}

	/**
	 * <p>
	 * The inset from the right. This value is subtracted from the Right of the rectangle to yield a new location for the Right edge.
	 * </p>
	 * 
	 * @see #getInsetRight()
	 * @see #getInsets()
	 * @see #isAnyInsetWithNotDefalutValue()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see Insets#right
	 */
	public int getInsetRight() {
		return insetRight;
	}

	/**
	 * <p>
	 * Specifies the external padding of the component, the minimum amount of space between the component and the edges of its display area.
	 * </p>
	 * <p>
	 * The default value is <code>new Insets(0, 0, 0, 0)</code>.
	 * </p>
	 * 
	 * @see #getInsetBottom()
	 * @see #getInsetLeft()
	 * @see #getInsetRight()
	 * @see #getInsets()
	 * @see #getInsetTop()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsetLeft(int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see #setInsets(int, int, int, int)
	 * @see #setInsetTop(int)
	 * @see Insets#bottom
	 * @see Insets#left
	 * @see Insets#right
	 * @see Insets#top
	 */
	public Insets getInsets() {
		return new Insets(insetTop, insetLeft, insetBottom, insetRight);
	}

	/**
	 * <p>
	 * The inset from the top. This value is added to the Top of the rectangle to yield a new location for the Top.
	 * </p>
	 * 
	 * @see #getInsets()
	 * @see #getInsetTop()
	 * @see #isAnyInsetWithNotDefalutValue()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsets(Insets)
	 * @see #setInsetTop(int)
	 * @see Insets#top
	 */
	public int getInsetTop() {
		return insetTop;
	}

	/**
	 * <p>
	 * Specifies the <b>vertical internal padding</b>, that is, how much space to add to the minimum height of the component. The height of the component is at least its minimum height plus {@link #getVerIpadY()} pixels.
	 * </p>
	 * <p>
	 * The default value is <code>0</code>.
	 * </p>
	 * 
	 * @see #getVerIpadY()
	 * @see #setVerIpadY(int)
	 * @see #setVerMarginY(int, int, int)
	 * @see GridBagConstraints#ipady
	 */
	public int getVerIpadY() {
		return ipady;
	}

	/**
	 * Specifies how to distribute extra horizontal space.
	 * <p>
	 * The grid bag layout manager calculates the weight of a column to be the maximum {@link #getWeightX()} of all the components in a column. If the resulting layout is smaller horizontally than the area it needs to fill, the extra space is distributed to each column in proportion to its weight. A
	 * column that has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the left and right edges.
	 * </p>
	 * <p>
	 * The default value of this field is <code>0</code>. {@link #getWeightX()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getWeightX()
	 * @see #setHorizontals(Integer, Integer, Double)
	 * @see #setHorizontals(Integer, Integer, Integer)
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightX(Double)
	 * @see #setWeightX(Integer)
	 * @see GridBagConstraints#weightx
	 */
	public Double getWeightX() {
		return weightX;
	}

	/**
	 * @return the weightY
	 */
	public Double getWeightY() {
		return weightY;
	}

	/**
	 * <p>
	 * Specifies the number of cells in a row for the component's display area.
	 * </p>
	 * <p>
	 * Default value is 1.
	 * </p>
	 * 
	 * @see #getWidthX()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridwidth
	 */
	public Integer getWidthX() {
		return widthX;
	}

	/**
	 * <p>
	 * <code>x</code> specifies the cell containing the leading edge of the component's display area, where the first cell in a row has {@link #getX()}<code>=0</code>. The leading edge of a component's display area is its left edge for a horizontal, left-to-right container and its right edge for a
	 * horizontal, right-to-left container.<br />
	 * The value {@link GridBagConstraints#RELATIVE} specifies that the component be placed immediately following the component that was added to the container just before this component was added.<br />
	 * The default value is <code>null</code>. {@link #getX()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getX()
	 * @see #isXRelative()
	 * @see #setX(Integer)
	 * @see #setXAsRelative()
	 * @see #setXY(Integer, Integer)
	 * @see GridBagConstraints#gridx
	 */
	public Integer getX() {
		return x;
	}

	/**
	 * <p>
	 * Specifies the cell at the top of the component's display area, where the topmost cell has {@link #getY()}<code>=0</code>. The value {@link GridBagConstraints#RELATIVE} specifies that the component be placed just below the component that was added to the container just before this component
	 * was added. <br />
	 * The default value is <code>null</code>. {@link #getY()} should be a non-negative value.
	 * </p>
	 * 
	 * @return the gridY
	 * @see #getY()
	 * @see #isYRelative()
	 * @see #setXY(Integer, Integer)
	 * @see #setY(Integer)
	 * @see #setYAsRelative()
	 * @see GridBagConstraints#gridy
	 */
	public Integer getY() {
		return y;
	}

	/**
	 * If any inset have not <code>0</code> value
	 * 
	 * @see #getInsetBottom()
	 * @see #getInsetLeft()
	 * @see #getInsetRight()
	 * @see #getInsetTop()
	 */
	public boolean isAnyInsetWithNotDefalutValue() {
		if (insetBottom != 0) { return true; }
		if (insetLeft != 0) { return true; }
		if (insetRight != 0) { return true; }
		if (insetTop != 0) { return true; }
		return false;
	}

	/**
	 * @return <code>true</code> if {@link #getFill()} return {@link GridConstraintsFill#Both}
	 * @see #getFill()
	 * @see #isFilledBoth()
	 * @see #isFilledHorizontal()
	 * @see #isFilledNone()
	 * @see #isFilledVertical()
	 * @see #setFill(GridConstraintsFill)
	 */
	public boolean isFilledBoth() {
		return this.fill == GridConstraintsFill.Both;
	}

	/**
	 * @return <code>true</code> if {@link #getFill()} return {@link GridConstraintsFill#Both} or {@link GridConstraintsFill#Horizontal}
	 * @see #getFill()
	 * @see #isFilledBoth()
	 * @see #isFilledHorizontal()
	 * @see #isFilledNone()
	 * @see #isFilledVertical()
	 * @see #setFill(GridConstraintsFill)
	 */
	public boolean isFilledHorizontal() {
		return this.fill == GridConstraintsFill.Horizontal//
				|| this.fill == GridConstraintsFill.Both;
	}

	/**
	 * @return <code>true</code> if {@link #getFill()} return {@link GridConstraintsFill#None}
	 * @see #getFill()
	 * @see #isFilledBoth()
	 * @see #isFilledHorizontal()
	 * @see #isFilledNone()
	 * @see #isFilledVertical()
	 * @see #setFill(GridConstraintsFill)
	 */
	public boolean isFilledNone() {
		return this.fill == GridConstraintsFill.None;
	}

	/**
	 * @return <code>true</code> if {@link #getFill()} return {@link GridConstraintsFill#Both} or {@link GridConstraintsFill#Vertical}
	 * @see #getFill()
	 * @see #isFilledBoth()
	 * @see #isFilledHorizontal()
	 * @see #isFilledNone()
	 * @see #isFilledVertical()
	 * @see #setFill(GridConstraintsFill)
	 */
	public boolean isFilledVertical() {
		return this.fill == GridConstraintsFill.Vertical//
				|| this.fill == GridConstraintsFill.Both;
	}

	/**
	 * <p>
	 * Return value specifies if the component will be placed immediately following the component that was added to the container just before this component was added.
	 * </p>
	 * 
	 * @return <code>true</code> if {@link #getX()} is set as {@link GridBagConstraints#RELATIVE}
	 * @see #getX()
	 * @see #setX(Integer)
	 * @see #setXAsRelative()
	 * @see #setXY(Integer, Integer)
	 * @see GridBagConstraints#gridx
	 */
	public boolean isXRelative() {
		if (x == null) { return false; }
		if (x == GridBagConstraints.RELATIVE) { return true; }
		return false;
	}

	public boolean isYRelative() {
		if (y == null) { return false; }
		if (y == GridBagConstraints.RELATIVE) { return true; }
		return false;
	}

	/**
	 * Will do not succeed until {@link #getX()} and {@link #getY()} will return not <code>null</code> value<br />
	 */
	public GridBagConstraints provide() {
		return build();
	}

	/**
	 * @param align the align to set
	 * @see #getAlign()
	 * @see #getAlignValue()
	 * @see #setAlign(ComponentPlacement)
	 * @see ComponentPlacement
	 * @throws NullPointerException when given <code>align</code> is <code>null</code>
	 */
	public GridConstraintsBuilder setAlign(ComponentPlacement align) {
		if (align == null) { throw new NullPointerException(ComponentPlacement.class.getSimpleName()); }
		this.align = align;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnCenter
	 * @see #newOnCenter()
	 * @see #newOnCenter(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnCenter() {
		this.align = ComponentPlacement.OnCenter;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnEast
	 * @see #newOnEast()
	 * @see #newOnEast(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnEast() {
		this.align = ComponentPlacement.OnEast;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnNorth
	 * @see #newOnNorth()
	 * @see #newOnNorth(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnNorth() {
		this.align = ComponentPlacement.OnNorth;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnNorthEast
	 * @see #newOnNorthEast()
	 * @see #newOnNorthEast(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnNorthEast() {
		this.align = ComponentPlacement.OnNorthEast;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnNorthWest
	 * @see #newOnNorthWest()
	 * @see #newOnNorthWest(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnNorthWest() {
		this.align = ComponentPlacement.OnNorthWest;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnPageEnd
	 * @see #newOnPageEnd()
	 * @see #newOnPageEnd(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnPageEnd() {
		this.align = ComponentPlacement.OnPageEnd;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnPageStart
	 * @see #newOnPageStart()
	 * @see #newOnPageStart(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnPageStart() {
		this.align = ComponentPlacement.OnPageStart;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnSouth
	 * @see #newOnSouth()
	 * @see #newOnSouth(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnSouth() {
		this.align = ComponentPlacement.OnSouth;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnSouthEast
	 * @see #newOnSouthEast()
	 * @see #newOnSouthEast(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnSouthEast() {
		this.align = ComponentPlacement.OnSouthEast;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnSouthWest
	 * @see #newOnSouthWest()
	 * @see #newOnSouthWest(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnSouthWest() {
		this.align = ComponentPlacement.OnSouthWest;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnWest
	 * @see #newOnWest()
	 * @see #newOnWest(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsOnWest() {
		this.align = ComponentPlacement.OnWest;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnAboveBaseline
	 * @see #newPinOnAboveBaseline()
	 * @see #newPinOnAboveBaseline(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnAboveBaseline() {
		this.align = ComponentPlacement.OnAboveBaseline;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnAboveBaselineLeading
	 * @see #newPinOnAboveBaselineLeading()
	 * @see #newPinOnAboveBaselineLeading(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnAboveBaselineLeading() {
		this.align = ComponentPlacement.OnAboveBaselineLeading;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnAboveBaselineTrailing
	 * @see #newPinOnAboveBaselineTrailing()
	 * @see #newPinOnAboveBaselineTrailing(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnAboveBaselineTrailing() {
		this.align = ComponentPlacement.OnAboveBaselineTrailing;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnBaseline
	 * @see #newPinOnBaseline()
	 * @see #newPinOnBaseline(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnBaseline() {
		this.align = ComponentPlacement.OnBaseline;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnBaselineLeading
	 * @see #newPinOnBaselineLeading()
	 * @see #newPinOnBaselineLeading(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnBaselineLeading() {
		this.align = ComponentPlacement.OnBaselineLeading;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnBaselineTrailing
	 * @see #newPinOnBaselineTrailing()
	 * @see #newPinOnBaselineTrailing(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnBaselineTrailing() {
		this.align = ComponentPlacement.OnBaselineTrailing;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnBelowBaseline
	 * @see #newPinOnBelowBaseline()
	 * @see #newPinOnBelowBaseline(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnBelowBaseline() {
		this.align = ComponentPlacement.OnBelowBaseline;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnBelowBaselineLeading
	 * @see #newPinOnBelowBaselineLeading()
	 * @see #newPinOnBelowBaselineLeading(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnBelowBaselineLeading() {
		this.align = ComponentPlacement.OnBelowBaselineLeading;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnBelowBaselineTrailing
	 * @see #newPinOnBelowBaselineTrailing()
	 * @see #newPinOnBelowBaselineTrailing(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnBelowBaselineTrailing() {
		this.align = ComponentPlacement.OnBelowBaselineTrailing;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnFirstLineEnd
	 * @see #newPinOnFirstLineEnd()
	 * @see #newPinOnFirstLineEnd(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnFirstLineEnd() {
		this.align = ComponentPlacement.OnFirstLineEnd;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnFirstLineStart
	 * @see #newPinOnFirstLineStart()
	 * @see #newPinOnFirstLineStart(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnFirstLineStart() {
		this.align = ComponentPlacement.OnFirstLineStart;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnLastLineEnd
	 * @see #newPinOnLastLineEnd()
	 * @see #newPinOnLastLineEnd(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnLastLineEnd() {
		this.align = ComponentPlacement.OnLastLineEnd;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnLastLineStart
	 * @see #newPinOnLastLineStart()
	 * @see #newPinOnLastLineStart(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnLastLineStart() {
		this.align = ComponentPlacement.OnLastLineStart;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnLineEnd
	 * @see #newPinOnLineEnd()
	 * @see #newPinOnLineEnd(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnLineEnd() {
		this.align = ComponentPlacement.OnLineEnd;
		return this;
	}

	/**
	 * @see ComponentPlacement#OnLineStart
	 * @see #newPinOnLineStart()
	 * @see #newPinOnLineStart(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsPinOnLineStart() {
		this.align = ComponentPlacement.OnLineStart;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToBottom
	 * @see #newToBottom()
	 * @see #newToBottom(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToBottom() {
		this.align = ComponentPlacement.ToBottom;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToBottomLeft
	 * @see #newToBottomLeft()
	 * @see #newToBottomLeft(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToBottomLeft() {
		this.align = ComponentPlacement.ToBottomLeft;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToBottomRight
	 * @see #newToBottomRight()
	 * @see #newToBottomRight(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToBottomRight() {
		this.align = ComponentPlacement.ToBottomRight;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToLeft
	 * @see #newToLeft()
	 * @see #newToLeft(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToLeft() {
		this.align = ComponentPlacement.ToLeft;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToRight
	 * @see #newToRight()
	 * @see #newToRight(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToRight() {
		this.align = ComponentPlacement.ToRight;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToTop
	 * @see #newToTop()
	 * @see #newToTop(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToTop() {
		this.align = ComponentPlacement.ToTop;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToTopLeft
	 * @see #newToTopLeft()
	 * @see #newToTopLeft(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToTopLeft() {
		this.align = ComponentPlacement.ToTopLeft;
		return this;
	}

	/**
	 * @see ComponentPlacement#ToTopRight
	 * @see #newToTopRight()
	 * @see #newToTopRight(Integer, Integer)
	 */
	final public GridConstraintsBuilder setAlignAsToTopRight() {
		this.align = ComponentPlacement.ToTopRight;
		return this;
	}

	/**
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #isFilledBoth()
	 * @see #isFilledHorizontal()
	 * @see #isFilledNone()
	 * @see #isFilledVertical()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder setFill(GridConstraintsFill fill) {
		if (fill == null) { throw new NullPointerException(GridConstraintsFill.class.getSimpleName()); }
		this.fill = fill;
		return null;
	}

	/**
	 * <p>
	 * Ensure the component to fill its display area entirely.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder setFillAsBoth() {
		this.fill = GridConstraintsFill.Both;
		return this;
	}

	/**
	 * <p>
	 * Make the component wide enough to fill its display area horizontally, but do not change its height.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder setFillAsHorizontal() {
		this.fill = GridConstraintsFill.Horizontal;
		return this;
	}

	/**
	 * <p>
	 * Ensures the component to do not resize.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder setFillAsNone() {
		this.fill = GridConstraintsFill.None;
		return this;
	}

	/**
	 * <p>
	 * Ensure the component to be tall enough to fill its display area vertically, but do not change its width.
	 * </p>
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public GridConstraintsBuilder setFillAsVertical() {
		this.fill = GridConstraintsFill.Vertical;
		return this;
	}

	/**
	 * Set the number of cells in a column for the component's display area.
	 * <p>
	 * Use {@link GridBagConstraints#REMAINDER} / {@link #setHeightYTillLastRow()} to specify that the component's display area will be from {@link #getY()} to the last cell in the column. Use {@link GridBagConstraints#REMAINDER} to specify that the component's display area will be from
	 * {@link #getY()} to the next to the last one in its column.
	 * </p>
	 * <p>
	 * Use {@link GridBagConstraints#RELATIVE} / {@link #setHeightYToBeforeLastRow()} to specify that the component's display area will be from {@link #getY()} to the next to the last one in its column.
	 * </p>
	 * <code>height</code> should be a non-negative value and the default value is 1.
	 * <p>
	 * Specifies the number of cells in a column for the component's display area.
	 * </p>
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 * @throws IllegalArgumentException when given <code>height</code> is negative
	 */
	public GridConstraintsBuilder setHeightY(Integer height) {
		if (height != null) {
			if ((height != GridBagConstraints.REMAINDER) //
					&& (height != GridBagConstraints.RELATIVE) //
					&& (height < 0)) {//
				throw new IllegalArgumentException("Height(" + height + ") should be a non-negative value.");
			}
		}
		this.heightY = height;
		return this;
	}

	/**
	 * <p>
	 * Specify that the component's display area will be from {@link #getY()} to the last cell in the column.
	 * </p>
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	public GridConstraintsBuilder setHeightYTillLastRow() {
		this.heightY = GridBagConstraints.REMAINDER;
		return this;
	}

	/**
	 * <p>
	 * Specify that the component's display area will be from {@link #getX()} to the next to the last one in its column.
	 * </p>
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	public GridConstraintsBuilder setHeightYToBeforeLastRow() {
		this.heightY = GridBagConstraints.RELATIVE;
		return this;
	}

	/**
	 * @param insetLeft {@link #setInsetLeft(int)}
	 * @param insetRight {@link #setInsetRight(int)}
	 * @see #setHorInsetsX(int, int)
	 * @see #setHorMarginX(int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsetLeft(int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see #setInsets(int, int, int, int)
	 * @see #setInsetTop(int)
	 * @see #setVerInsetsY(int, int)
	 * @see #setVerMarginY(int, int, int)
	 */
	public GridConstraintsBuilder setHorInsetsX(int insetLeft, int insetRight) {
		setInsetLeft(insetLeft);
		setInsetRight(insetRight);
		return this;
	}

	/**
	 * <p>
	 * Set the <b>horizontal internal padding</b> of the component, how much space to add to the minimum width of the component. The width of the component is at least its minimum width plus {@link #getHorIpadX()} pixels.
	 * </p>
	 * <p>
	 * The default value is <code>0</code>.
	 * </p>
	 * 
	 * @see #getHorIpadX()
	 * @see #setHorIpadX(int)
	 * @see #setVerMarginY(int, int, int)
	 * @see GridBagConstraints#ipadx
	 */
	public GridConstraintsBuilder setHorIpadX(int internalPaddingX) {
		if (internalPaddingX < 0) { //
			throw new IllegalArgumentException("Internal padding(" + internalPaddingX + ") should be a non-negative value.");
		}
		this.ipadx = internalPaddingX;
		return this;
	}

	/**
	 * @param gridXPosition {@link #setX(Integer)}
	 * @param width {@link #setWidthX(Integer)}
	 */
	public GridConstraintsBuilder setHorizontals(Integer gridXPosition, Integer width) {
		setX(gridXPosition);
		setWidthX(width);
		return this;
	}

	/**
	 * @param gridXPosition {@link #setX(Integer)}
	 * @param width {@link #setWidthX(Integer)}
	 * @param weightX {@link #setWeightX(Double)}
	 */
	public GridConstraintsBuilder setHorizontals(Integer gridXPosition, Integer width, Double weightX) {
		setX(gridXPosition);
		setWidthX(width);
		setWeightX(weightX);
		return this;
	}

	/**
	 * @param gridXPosition {@link #setX(Integer)}
	 * @param width {@link #setWidthX(Integer)}
	 * @param weightX {@link #setWeightX(Integer)}
	 */
	public GridConstraintsBuilder setHorizontals(Integer gridXPosition, Integer width, Integer weightX) {
		setX(gridXPosition);
		setWidthX(width);
		setWeightX(weightX);
		return this;
	}

	/**
	 * @param insetLeft {@link #setInsetLeft(int)}
	 * @param internalPaddingX {@link #setHorIpadX(int)}
	 * @param insetRight {@link #setInsetRight(int)}
	 * @see #setHorInsetsX(int, int)
	 * @see #setHorMarginX(int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsetLeft(int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see #setInsets(int, int, int, int)
	 * @see #setInsetTop(int)
	 * @see #setVerInsetsY(int, int)
	 * @see #setVerMarginY(int, int, int)
	 */
	public GridConstraintsBuilder setHorMarginX(int insetLeft, int internalPaddingX, int insetRight) {
		setInsetLeft(insetLeft);
		setInsetRight(insetRight);
		setHorIpadX(internalPaddingX);
		return this;
	}

	/**
	 * <p>
	 * The inset from the bottom. This value is subtracted from the Bottom of the rectangle to yield a new location for the Bottom.
	 * </p>
	 * 
	 * @see #getInsetBottom()
	 * @see #getInsets()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsets(Insets)
	 * @see Insets#bottom
	 */
	public GridConstraintsBuilder setInsetBottom(int insetBottom) {
		this.insetBottom = insetBottom;
		return this;
	}

	/**
	 * <p>
	 * The inset from the left. This value is added to the Left of the rectangle to yield a new location for the Left edge.
	 * </p>
	 * 
	 * @see #getInsetLeft()
	 * @see #getInsets()
	 * @see #setHorInsetsX(int, int)
	 * @see #setHorMarginX(int, int, int)
	 * @see #setInsetLeft(int)
	 * @see #setInsets(Insets)
	 * @see GridConstraintsBuilder#createInsets(int, int, int, int)
	 * @see Insets#left
	 */
	public GridConstraintsBuilder setInsetLeft(int insetLeft) {
		this.insetLeft = insetLeft;
		return this;
	}

	/**
	 * <p>
	 * The inset from the right. This value is subtracted from the Right of the rectangle to yield a new location for the Right edge.
	 * </p>
	 * 
	 * @see #getInsetRight()
	 * @see #getInsets()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see Insets#right
	 */
	public GridConstraintsBuilder setInsetRight(int insetRight) {
		this.insetRight = insetRight;
		return this;
	}

	/**
	 * <p>
	 * Specifies the external padding of the component, the minimum amount of space between the component and the edges of its display area.
	 * </p>
	 * <p>
	 * The default value is <code>new Insets(0, 0, 0, 0)</code>.
	 * </p>
	 * 
	 * @see #getInsetBottom()
	 * @see #getInsetLeft()
	 * @see #getInsetRight()
	 * @see #getInsets()
	 * @see #getInsetTop()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsetLeft(int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see #setInsets(int, int, int, int)
	 * @see #setInsetTop(int)
	 * @see Insets#bottom
	 * @see Insets#left
	 * @see Insets#right
	 * @see Insets#top
	 */
	public GridConstraintsBuilder setInsets(Insets insets) {
		if (insets == null) { throw new NullPointerException(Insets.class.getSimpleName()); }
		setInsetLeft(insets.left);
		setInsetTop(insets.top);
		setInsetRight(insets.right);
		setInsetBottom(insets.bottom);
		return this;
	}

	/**
	 * <p>
	 * Specifies the external padding of the component, the minimum amount of space between the component and the edges of its display area.
	 * </p>
	 * <p>
	 * The default value is <code>new Insets(0, 0, 0, 0)</code>.
	 * </p>
	 * 
	 * @see #getInsetBottom()
	 * @see #getInsetLeft()
	 * @see #getInsetRight()
	 * @see #getInsets()
	 * @see #getInsetTop()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsetLeft(int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see #setInsets(int, int, int, int)
	 * @see #setInsetTop(int)
	 * @see Insets#bottom
	 * @see Insets#left
	 * @see Insets#right
	 * @see Insets#top
	 */
	public GridConstraintsBuilder setInsets(int left, int top, int right, int bottom) {
		setInsetLeft(left);
		setInsetTop(top);
		setInsetRight(right);
		setInsetBottom(bottom);
		return this;
	}

	/**
	 * <p>
	 * The inset from the top. This value is added to the Top of the rectangle to yield a new location for the Top.
	 * </p>
	 * 
	 * @see #getInsets()
	 * @see #getInsetTop()
	 * @see #createInsets(int, int, int, int)
	 * @see #setInsets(Insets)
	 * @see #setInsetTop(int)
	 * @see Insets#top
	 */
	public GridConstraintsBuilder setInsetTop(int insetTop) {
		this.insetTop = insetTop;
		return this;
	}

	public GridConstraintsBuilder setInternalPadding(int x, int y) {
		if (x < 0) { // 
			throw new IllegalArgumentException("Internal padding horizontal/x(" + ipady + ") should be a non-negative value.");
		}
		if (y < 0) { //
			throw new IllegalArgumentException("Internal padding vertical/y(" + ipady + ") should be a non-negative value.");
		}
		this.ipadx = x;
		this.ipady = y;
		return this;
	}

	/**
	 * Specifies the number of cells in a column for the component's display area.
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	public GridConstraintsBuilder setSize(Integer width, Integer height) {
		setWidthX(width);
		setHeightY(height);
		return this;
	}

	/**
	 * @param insetTop {@link #setInsetTop(int)}
	 * @param insetBottom {@link #setInsetBottom(int)}
	 * @see #setHorInsetsX(int, int)
	 * @see #setHorMarginX(int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsetLeft(int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see #setInsets(int, int, int, int)
	 * @see #setInsetTop(int)
	 * @see #setVerInsetsY(int, int)
	 * @see #setVerMarginY(int, int, int)
	 */
	public GridConstraintsBuilder setVerInsetsY(int insetTop, int insetBottom) {
		setInsetTop(insetTop);
		setInsetBottom(insetBottom);
		return this;
	}

	/**
	 * <p>
	 * Set the <b>vertical internal padding</b>, that is, how much space to add to the minimum height of the component. The height of the component is at least its minimum height plus {@link #getVerIpadY()} pixels.
	 * </p>
	 * <p>
	 * The default value is <code>0</code>.
	 * </p>
	 * 
	 * @see #getVerIpadY()
	 * @see #setVerIpadY(int)
	 * @see #setVerMarginY(int, int, int)
	 * @see GridBagConstraints#ipady
	 */
	public GridConstraintsBuilder setVerIpadY(int internalPaddingY) {
		if (internalPaddingY < 0) { //
			throw new IllegalArgumentException("Internal padding(" + internalPaddingY + ") should be a non-negative value.");
		}
		this.ipady = internalPaddingY;
		return this;
	}

	/**
	 * @param insetTop {@link #setInsetTop(int)}
	 * @param internalPaddingY {@link #setVerIpadY(int)}
	 * @param insetBottom {@link #setInsetBottom(int)}
	 * @see #setHorInsetsX(int, int)
	 * @see #setHorMarginX(int, int, int)
	 * @see #setInsetBottom(int)
	 * @see #setInsetLeft(int)
	 * @see #setInsetRight(int)
	 * @see #setInsets(Insets)
	 * @see #setInsets(int, int, int, int)
	 * @see #setInsetTop(int)
	 * @see #setVerInsetsY(int, int)
	 * @see #setVerMarginY(int, int, int)
	 */
	public GridConstraintsBuilder setVerMarginY(int insetTop, int internalPaddingY, int insetBottom) {
		setInsetTop(insetTop);
		setInsetBottom(insetBottom);
		setVerIpadY(internalPaddingY);
		return this;
	}

	/**
	 * @param gridYPosition {@link #setY(Integer)}
	 * @param height {@link #setHeightY(Integer)}
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 */
	public GridConstraintsBuilder setVerticals(Integer gridYPosition, Integer height) {
		setY(gridYPosition);
		setHeightY(height);
		return this;
	}

	/**
	 * @param gridYPosition {@link #setY(Integer)}
	 * @param height {@link #setHeightY(Integer)}
	 * @param weightY {@link #setWeightY(Double)}
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 */
	public GridConstraintsBuilder setVerticals(Integer gridYPosition, Integer height, Double weightY) {
		setY(gridYPosition);
		setHeightY(height);
		setWeightY(weightY);
		return this;
	}

	/**
	 * @param gridYPosition {@link #setY(Integer)}
	 * @param height {@link #setHeightY(Integer)}
	 * @param weightY {@link #setWeightY(Integer)}
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 */
	public GridConstraintsBuilder setVerticals(Integer gridYPosition, Integer height, Integer weightY) {
		setY(gridYPosition);
		setHeightY(height);
		setWeightY(weightY);
		return this;
	}

	/**
	 * @param x #setWeightX(Double)
	 * @param y #setWeightY(Double)
	 */
	public GridConstraintsBuilder setWeight(Double x, Double y) {
		setWeightX(x);
		setWeightY(y);
		return this;
	}

	/**
	 * @param x #setWeightX(Integer)
	 * @param y #setWeightY(Integer)
	 */
	public GridConstraintsBuilder setWeight(Integer x, Integer y) {
		setWeightX(x);
		setWeightY(y);
		return this;
	}

	/**
	 * Set how to distribute extra horizontal space.
	 * <p>
	 * The grid bag layout manager calculates the weight of a column to be the maximum {@link #getWeightX()} of all the components in a column. If the resulting layout is smaller horizontally than the area it needs to fill, the extra space is distributed to each column in proportion to its weight. A
	 * column that has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the left and right edges.
	 * </p>
	 * <p>
	 * The default value of this field is <code>0</code>. {@link #getWeightX()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getWeightX()
	 * @see #setHorizontals(Integer, Integer, Double)
	 * @see #setHorizontals(Integer, Integer, Integer)
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightX(Double)
	 * @see #setWeightX(Integer)
	 * @see GridBagConstraints#weightx
	 */
	public GridConstraintsBuilder setWeightX(Double weightX) {
		if (weightX != null && weightX < 0) { //
			throw new IllegalArgumentException("Weight(" + weightX + ") should be a non-negative value.");
		}
		this.weightX = weightX;
		return this;
	}

	/**
	 * Set how to distribute extra horizontal space.
	 * <p>
	 * The grid bag layout manager calculates the weight of a column to be the maximum {@link #getWeightX()} of all the components in a column. If the resulting layout is smaller horizontally than the area it needs to fill, the extra space is distributed to each column in proportion to its weight. A
	 * column that has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the left and right edges.
	 * </p>
	 * <p>
	 * The default value of this field is <code>0</code>. {@link #getWeightX()} should be a non-negative value.
	 * </p>
	 * 
	 * @see #getWeightX()
	 * @see #setHorizontals(Integer, Integer, Double)
	 * @see #setHorizontals(Integer, Integer, Integer)
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightX(Double)
	 * @see #setWeightX(Integer)
	 * @see GridBagConstraints#weightx
	 */
	public GridConstraintsBuilder setWeightX(Integer weightX) {
		if (weightX != null && weightX < 0) { //
			throw new IllegalArgumentException("Weight(" + weightX + ") should be a non-negative value.");
		}
		this.weightX = weightX != null ? new Double(weightX) //
				: null;
		return this;
	}

	/**
	 * Specifies how to distribute extra vertical space.
	 * <p>
	 * The grid bag layout manager calculates the weight of a row to be the maximum {@link #getWeightY()} of all the components in a row. If the resulting layout is smaller vertically than the area it needs to fill, the extra space is distributed to each row in proportion to its weight. A row that
	 * has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the top and bottom edges.
	 * </p>
	 * <p>
	 * The default value of this field is <code>0</code>. {@link #getWeightY()} should be a non-negative value.
	 * </p>
	 * 
	 * @param weightY the weightY to set
	 * @see #getWeightY()
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightY(Double)
	 * @see #setWeightY(Integer)
	 * @see GridBagConstraints#weightx
	 */
	public GridConstraintsBuilder setWeightY(Double weightY) {
		if (weightY != null && weightY < 0) { //
			throw new IllegalArgumentException("Weight(" + weightY + ") should be a non-negative value.");
		}
		this.weightY = weightY;
		return this;
	}

	/**
	 * Specifies how to distribute extra vertical space.
	 * <p>
	 * The grid bag layout manager calculates the weight of a row to be the maximum {@link #getWeightY()} of all the components in a row. If the resulting layout is smaller vertically than the area it needs to fill, the extra space is distributed to each row in proportion to its weight. A row that
	 * has a weight of zero receives no extra space.
	 * </p>
	 * <p>
	 * If all the weights are zero, all the extra space appears between the grids of the cell and the top and bottom edges.
	 * </p>
	 * <p>
	 * The default value of this field is <code>0</code>. {@link #getWeightY()} should be a non-negative value.
	 * </p>
	 * 
	 * @param weightY the weightY to set
	 * @see #getWeightY()
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 * @see #setWeight(Double, Double)
	 * @see #setWeight(Integer, Integer)
	 * @see #setWeightY(Double)
	 * @see #setWeightY(Integer)
	 * @see GridBagConstraints#weightx
	 */
	public GridConstraintsBuilder setWeightY(Integer weightY) {
		if (weightY != null && weightY < 0) { //
			throw new IllegalArgumentException("Weight(" + weightY + ") should be a non-negative value.");
		}
		this.weightY = weightY != null ? new Double(weightY) //
				: null;
		return this;
	}

	/**
	 * Set the number of cells in a column for the component's display area.
	 * <p>
	 * Use {@link GridBagConstraints#REMAINDER} / {@link #setWidthXTillLastCell()} to specify that the component's display area will be from {@link #getX()} to the last cell in the row.
	 * </p>
	 * <p>
	 * Use {@link GridBagConstraints#RELATIVE} / {@link #setWidthXToBeforeLastCell()} to specify that the component's display area will be from {@link #getX()} to the next to the last one in its row.
	 * </p>
	 * <code>height</code> should be a non-negative value and the default value is 1.
	 * <p>
	 * Specifies the number of cells in a row for the component's display area.
	 * </p>
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 * @throws IllegalArgumentException when given <code>width</code> is negative
	 */
	public GridConstraintsBuilder setWidthX(Integer width) {
		if (width != null) {
			if ((width != GridBagConstraints.REMAINDER) //
					&& (width != GridBagConstraints.RELATIVE) //
					&& (width < 0)) { //
				throw new IllegalArgumentException("Width(" + width + ") should be a non-negative value.");
			}
		}
		this.widthX = width;
		return this;
	}

	/**
	 * <p>
	 * Specify that the component's display area will be from {@link #getX()} to the last cell in the row.
	 * </p>
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	public GridConstraintsBuilder setWidthXTillLastCell() {
		this.widthX = GridBagConstraints.REMAINDER;
		return this;
	}

	/**
	 * <p>
	 * Specify that the component's display area will be from {@link #getX()} to the next to the last one in its row.
	 * </p>
	 * 
	 * @see #getFinalHeightY()
	 * @see #getFinalWidthX()
	 * @see #getHeightY()
	 * @see #getWidthX()
	 * @see #heightY
	 * @see #setHeightY(Integer)
	 * @see #setHeightYTillLastRow()
	 * @see #setHeightYToBeforeLastRow()
	 * @see #setSize(Integer, Integer)
	 * @see #setWidthX(Integer)
	 * @see #setWidthXTillLastCell()
	 * @see #setWidthXToBeforeLastCell()
	 * @see #widthX
	 * @see GridBagConstraints#gridheight
	 * @see GridBagConstraints#gridwidth
	 */
	public GridConstraintsBuilder setWidthXToBeforeLastCell() {
		this.widthX = GridBagConstraints.RELATIVE;
		return this;
	}

	/**
	 * <p>
	 * Specifies the cell containing the leading edge of the component's display area, where the first cell in a row has {@link #getX()}<code>=0</code>. The leading edge of a component's display area is its left edge for a horizontal, left-to-right container and its right edge for a horizontal,
	 * right-to-left container.<br />
	 * The value {@link GridBagConstraints#RELATIVE} specifies that the component be placed immediately following the component that was added to the container just before this component was added.<br />
	 * The default value is <code>null</code>. {@link #getX()} should be a non-negative value.
	 * </p>
	 * 
	 * @param gridXPosition the grid X coordinate to set
	 * @see #getX()
	 * @see #isXRelative()
	 * @see #setX(Integer)
	 * @see #setXAsRelative()
	 * @see #setXY(Integer, Integer)
	 * @see GridBagConstraints#gridx
	 */
	public GridConstraintsBuilder setX(Integer gridXPosition) {
		if (gridXPosition == GridBagConstraints.RELATIVE) {
			this.x = GridBagConstraints.RELATIVE;
			return this;
		}
		if (gridXPosition != null && gridXPosition < 0) { //
			throw new IllegalArgumentException("Grid X coordinate is negative(" + gridXPosition + ")");
		}
		this.x = gridXPosition;
		return this;
	}

	/**
	 * <p>
	 * Specifies that the component be placed immediately following the component that was added to the container just before this component was added.
	 * </p>
	 * 
	 * @see #getX()
	 * @see #isXRelative()
	 * @see #setX(Integer)
	 * @see #setXAsRelative()
	 * @see #setXY(Integer, Integer)
	 * @see GridBagConstraints#gridx
	 */
	public GridConstraintsBuilder setXAsRelative() {
		this.x = GridBagConstraints.RELATIVE;
		return this;
	}

	/**
	 * @param gridXPosition {@link #setX(Integer)}
	 * @param gridYPosition {@link #setY(Integer)}
	 * @see #setX(Integer)
	 * @see #setXAsRelative()
	 * @see #setY(Integer)
	 * @see #setYAsRelative()
	 */
	public GridConstraintsBuilder setXY(Integer gridXPosition, Integer gridYPosition) {
		setX(gridXPosition);
		setY(gridYPosition);
		return this;
	}

	/**
	 * @param gridYPosition the grid Y coordinate to set
	 * @see #setVerticals(Integer, Integer)
	 * @see #setVerticals(Integer, Integer, Double)
	 * @see #setVerticals(Integer, Integer, Integer)
	 */
	public GridConstraintsBuilder setY(Integer gridYPosition) {
		if (gridYPosition == GridBagConstraints.RELATIVE) {
			this.y = GridBagConstraints.RELATIVE;
			return this;
		}
		if (gridYPosition != null && gridYPosition < 0) { //
			throw new IllegalArgumentException("Grid Y coordinate is negative(" + gridYPosition + ")");
		}
		this.y = gridYPosition;
		return this;
	}

	/**
	 * <p>
	 * Specifies that the component be placed just below the component that was added to the container just before this component was added.
	 * </p>
	 * 
	 * @see #getY()
	 * @see #isYRelative()
	 * @see #setXY(Integer, Integer)
	 * @see #setY(Integer)
	 * @see #setYAsRelative()
	 * @see GridBagConstraints#gridy
	 */
	public GridConstraintsBuilder setYAsRelative() {
		this.y = GridBagConstraints.RELATIVE;
		return this;
	}

	@Override
	public String toString() {
		return GridConstraintsBuilderToCodeConverter.Default.toJaveCode$(null, this).toString();
	}

	private final static String				alignSetName		= "setAlignAs";

	/**
	 * Holds default values, while so should not be modified
	 */
	private static final GridBagConstraints	defaultConstraint	= new GridBagConstraints();

	/**
	 * @param size used for minimum & preferred & maximum size
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createFiller(Dimension size) {
		if (size == null) { throw new NullPointerException(Dimension.class.getSimpleName()); }
		return new Box.Filler(new Dimension(size)//
				, new Dimension(size)//
				, new Dimension(size));
	}

	/**
	 * @param component source of sizes to create filler
	 * @return invisible component with sizes identical as given {@link Component}
	 * @see Component#setMinimumSize(Dimension)
	 * @see Component#setPreferredSize(Dimension)
	 * @see Component#setMaximumSize(Dimension)
	 * @see #syncSizes(Component, Component)
	 */
	// TODO tests
	final public static Box.Filler createFiller(Component component) {
		if (component == null) { throw new NullPointerException(Component.class.getSimpleName()); }
		return new Box.Filler(component.getMinimumSize()//
				, component.getPreferredSize()//
				, component.getMaximumSize());
	}

	/**
	 * Apply one {@link Component} sizes to another
	 * 
	 * @param component {@link Component} to work on
	 * @param with source of sizes
	 * @return back given {@link Component} (as first parameter) after fixing sizes
	 * @see #createFiller(Component)
	 */
	// TODO tests
	final public static <C extends Component> C syncSizes(final C component, Component with) {
		if (component == null) { throw new NullPointerException(Component.class.getSimpleName()); }
		if (with == null) { throw new NullPointerException(Component.class.getSimpleName() + " of sizes source"); }
		component.setMinimumSize(with.getMinimumSize());
		component.setPreferredSize(with.getPreferredSize());
		component.setMaximumSize(with.getMaximumSize());
		return component;
	}

	/**
	 * @param width used for minimum & preferred & maximum width
	 * @param height used for minimum & preferred & maximum height
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createFiller(int width, int height) {
		Dimension size = new Dimension(width, height);
		return new Box.Filler(new Dimension(size)//
				, new Dimension(size)//
				, new Dimension(size));
	}

	/**
	 * @param minX minimum width
	 * @param preferredX preferred width
	 * @param maxX maximum width
	 * @param minY minimum height
	 * @param preferredY preferred height
	 * @param maxY maximum height
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createFiller(int minX, int preferredX, int maxX//
			, int minY, int preferredY, int maxY) {
		return new Box.Filler(new Dimension(minX, minY)//
				, new Dimension(preferredX, preferredY)//
				, new Dimension(maxX, maxY));
	}

	/**
	 * @param minX minimum width
	 * @param preferredX preferred width
	 * @param maxX maximum width
	 * @return invisible component with given size
	 * @see Box.Filler
	 * @see #createFiller(Dimension)
	 * @see #createFiller(int, int)
	 * @see #createFiller(int, int, int, int, int, int)
	 * @see #createHorizontalFillerX(int)
	 * @see #createHorizontalFillerX(int, int)
	 * @see #createHorizontalFillerX(int, int, int)
	 * @see #createHorizontalFillerX(Component, int, int, int)
	 * @see #createVerticalFillerY(int)
	 * @see #createVerticalFillerY(int, int)
	 * @see #createVerticalFillerY(int, int, int)
	 * @see #createVerticalFillerY(Component, int, int, int)
	 */
	final public static Component createHorizontalFillerX(Component verticals, int minX, int preferredX, int maxX) {
		if (verticals == null) { throw new NullPointerException(Component.class.getSimpleName()); }
		if (minX > preferredX || preferredX > maxX) {//
			throw new IllegalArgumentException("parameters do not keep proper bounds min (" + minX + ") <= preferred(" + preferredX + ") <= max(" + maxX + ")");
		}
		return new Box.Filler(new Dimension(minX, (int) verticals.getMinimumSize().getHeight())//
				, new Dimension(preferredX, (int) verticals.getPreferredSize().getHeight())//
				, new Dimension(maxX, (int) verticals.getMaximumSize().getHeight()));
	}

	/**
	 * @param sizeX used for minimum & preferred & maximum width
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createHorizontalFillerX(int sizeX) {
		return createHorizontalFillerX(sizeX, sizeX, sizeX);
	}

	/**
	 * @param minX minimum width
	 * @param preferredX preferred width
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createHorizontalFillerX(int minX, int preferredX) {
		return createHorizontalFillerX(minX, preferredX, Short.MAX_VALUE);
	}

	/**
	 * @param minX minimum width
	 * @param preferredX preferred width
	 * @param maxX maximum width
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createHorizontalFillerX(int minX, int preferredX, int maxX) {
		if (minX > preferredX || preferredX > maxX) {//
			throw new IllegalArgumentException("parameters do not keep proper bounds min(" + minX + ") <= preferred(" + preferredX + ") <= max(" + maxX + ")");
		}
		return new Box.Filler(new Dimension(minX, 0)//
				, new Dimension(preferredX, 0)//
				, new Dimension(maxX, 0));
	}

	/**
	 * @return {@link Insets} created with 'easier' order
	 */
	final public static Insets createInsets(int left, int top, int right, int bottom) {
		return new Insets(top, left, bottom, right);
	}

	/**
	 * @param minY minimum height
	 * @param preferredY preferred height
	 * @param maxY maximum height
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createVerticalFillerY(Component horizontals, int minY, int preferredY, int maxY) {
		if (horizontals == null) { throw new NullPointerException(Component.class.getSimpleName()); }
		if (minY > preferredY || preferredY > maxY) {//
			throw new IllegalArgumentException("parameters do not keep proper bounds min(" + minY + ") <= preferred(" + preferredY + ") <= max(" + maxY + ")");
		}
		return new Box.Filler(new Dimension((int) horizontals.getMinimumSize().getHeight(), minY)//
				, new Dimension((int) horizontals.getPreferredSize().getHeight(), preferredY)//
				, new Dimension((int) horizontals.getMaximumSize().getHeight(), maxY));
	}

	/**
	 * @param sizeY used for minimum & preferred & maximum height
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createVerticalFillerY(int sizeY) {
		return createVerticalFillerY(sizeY, sizeY, sizeY);
	}

	/**
	 * @param minY minimum height
	 * @param preferredY preferred height
	 * @return invisible component with given size
	 * @see Box.Filler
	 */
	final public static Component createVerticalFillerY(int minY, int preferredY) {
		return createVerticalFillerY(minY, preferredY, Short.MAX_VALUE);
	}

	/**
	 * @param minY minimum height
	 * @param preferredY preferred height
	 * @param maxY maximum height
	 * @return invisible component with given size
	 * @see Box.Filler
	 * @throws IllegalArgumentException if given parameters do not keep bounds min <= preferred <= max
	 */
	final public static Component createVerticalFillerY(int minY, int preferredY, int maxY) {
		if (minY > preferredY || preferredY > maxY) {//
			throw new IllegalArgumentException("parameters do not keep proper bounds min(" + minY + ") <= preferred(" + preferredY + ") <= max(" + maxY + ")");
		}
		return new Box.Filler(new Dimension(0, minY)//
				, new Dimension(0, preferredY)//
				, new Dimension(0, maxY));
	}

	/**
	 * @return back given {@link GridBagConstraints} as {@link GridConstraintsBuilder}, <code>null</code> is not affected here
	 */
	final public static GridConstraintsBuilder newFromConstraints(GridBagConstraints constraint) {
		if (constraint == null) { return null; }
		return new GridConstraintsBuilder(constraint);
	}

	/**
	 * @param cp {@link ComponentPlacement}
	 * @throws NullPointerException if {@link ComponentPlacement} is <code>null</code>
	 */
	final public static GridConstraintsBuilder newOn(ComponentPlacement cp) {
		if (cp == null) { throw new NullPointerException(ComponentPlacement.class.getSimpleName()); }
		return new GridConstraintsBuilder(cp);
	}

	/**
	 * @see ComponentPlacement#OnCenter
	 * @see #setAlignAsOnCenter()
	 */
	final public static GridConstraintsBuilder newOnCenter() {
		return new GridConstraintsBuilder(ComponentPlacement.OnCenter);
	}

	/**
	 * @see ComponentPlacement#OnCenter
	 * @see #setAlignAsOnCenter()
	 */
	final public static GridConstraintsBuilder newOnCenter(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnCenter, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnEast
	 * @see #setAlignAsOnEast()
	 */
	final public static GridConstraintsBuilder newOnEast() {
		return new GridConstraintsBuilder(ComponentPlacement.OnEast);
	}

	/**
	 * @see ComponentPlacement#OnEast
	 * @see #setAlignAsOnEast()
	 */
	final public static GridConstraintsBuilder newOnEast(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnEast, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnNorth
	 * @see #setAlignAsOnNorth()
	 */
	final public static GridConstraintsBuilder newOnNorth() {
		return new GridConstraintsBuilder(ComponentPlacement.OnNorth);
	}

	/**
	 * @see ComponentPlacement#OnNorth
	 * @see #setAlignAsOnNorth()
	 */
	final public static GridConstraintsBuilder newOnNorth(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnNorth, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnNorthEast
	 * @see #setAlignAsOnNorthEast()
	 */
	final public static GridConstraintsBuilder newOnNorthEast() {
		return new GridConstraintsBuilder(ComponentPlacement.OnNorthEast);
	}

	/**
	 * @see ComponentPlacement#OnNorthEast
	 * @see #setAlignAsOnNorthEast()
	 */
	final public static GridConstraintsBuilder newOnNorthEast(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnNorthEast, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnNorthWest
	 * @see #setAlignAsOnNorthWest()
	 */
	final public static GridConstraintsBuilder newOnNorthWest() {
		return new GridConstraintsBuilder(ComponentPlacement.OnNorthWest);
	}

	/**
	 * @see ComponentPlacement#OnNorthWest
	 * @see #setAlignAsOnNorthWest()
	 */
	final public static GridConstraintsBuilder newOnNorthWest(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnNorthWest, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnPageEnd
	 * @see #setAlignAsOnPageEnd()
	 */
	final public static GridConstraintsBuilder newOnPageEnd() {
		return new GridConstraintsBuilder(ComponentPlacement.OnPageEnd);
	}

	/**
	 * @see ComponentPlacement#OnPageEnd
	 * @see #setAlignAsOnPageEnd()
	 */
	final public static GridConstraintsBuilder newOnPageEnd(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnPageEnd, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnPageStart
	 * @see #setAlignAsOnPageStart()
	 */
	final public static GridConstraintsBuilder newOnPageStart() {
		return new GridConstraintsBuilder(ComponentPlacement.OnPageStart);
	}

	/**
	 * @see ComponentPlacement#OnPageStart
	 * @see #setAlignAsOnPageStart()
	 */
	final public static GridConstraintsBuilder newOnPageStart(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnPageStart, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnSouth
	 * @see #setAlignAsOnSouth()
	 */
	final public static GridConstraintsBuilder newOnSouth() {
		return new GridConstraintsBuilder(ComponentPlacement.OnSouth);
	}

	/**
	 * @see ComponentPlacement#OnSouth
	 * @see #setAlignAsOnSouth()
	 */
	final public static GridConstraintsBuilder newOnSouth(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnSouth, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnSouthEast
	 * @see #setAlignAsOnSouthEast()
	 */
	final public static GridConstraintsBuilder newOnSouthEast() {
		return new GridConstraintsBuilder(ComponentPlacement.OnSouthEast);
	}

	/**
	 * @see ComponentPlacement#OnSouthEast
	 * @see #setAlignAsOnSouthEast()
	 */
	final public static GridConstraintsBuilder newOnSouthEast(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnSouthEast, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnSouthWest
	 * @see #setAlignAsOnSouthWest()
	 */
	final public static GridConstraintsBuilder newOnSouthWest() {
		return new GridConstraintsBuilder(ComponentPlacement.OnSouthWest);
	}

	/**
	 * @see ComponentPlacement#OnSouthWest
	 * @see #setAlignAsOnSouthWest()
	 */
	final public static GridConstraintsBuilder newOnSouthWest(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnSouthWest, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnWest
	 * @see #setAlignAsOnWest()
	 */
	final public static GridConstraintsBuilder newOnWest() {
		return new GridConstraintsBuilder(ComponentPlacement.OnWest);
	}

	/**
	 * @see ComponentPlacement#OnWest
	 * @see #setAlignAsOnWest()
	 */
	final public static GridConstraintsBuilder newOnWest(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnWest, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnAboveBaseline
	 * @see #setAlignAsPinOnAboveBaseline()
	 */
	final public static GridConstraintsBuilder newPinOnAboveBaseline() {
		return new GridConstraintsBuilder(ComponentPlacement.OnAboveBaseline);
	}

	/**
	 * @see ComponentPlacement#OnAboveBaseline
	 * @see #setAlignAsPinOnAboveBaseline()
	 */
	final public static GridConstraintsBuilder newPinOnAboveBaseline(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnAboveBaseline, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnAboveBaselineLeading
	 * @see #setAlignAsPinOnAboveBaselineLeading()
	 */
	final public static GridConstraintsBuilder newPinOnAboveBaselineLeading() {
		return new GridConstraintsBuilder(ComponentPlacement.OnAboveBaselineLeading);
	}

	/**
	 * @see ComponentPlacement#OnAboveBaselineLeading
	 * @see #setAlignAsPinOnAboveBaselineLeading()
	 */
	final public static GridConstraintsBuilder newPinOnAboveBaselineLeading(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnAboveBaselineLeading, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnAboveBaselineTrailing
	 * @see #setAlignAsPinOnAboveBaselineTrailing()
	 */
	final public static GridConstraintsBuilder newPinOnAboveBaselineTrailing() {
		return new GridConstraintsBuilder(ComponentPlacement.OnAboveBaselineTrailing);
	}

	/**
	 * @see ComponentPlacement#OnAboveBaselineTrailing
	 * @see #setAlignAsPinOnAboveBaselineTrailing()
	 */
	final public static GridConstraintsBuilder newPinOnAboveBaselineTrailing(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnAboveBaselineTrailing, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnBaseline
	 * @see #setAlignAsPinOnBaseline()
	 */
	final public static GridConstraintsBuilder newPinOnBaseline() {
		return new GridConstraintsBuilder(ComponentPlacement.OnBaseline);
	}

	/**
	 * @see ComponentPlacement#OnBaseline
	 * @see #setAlignAsPinOnBaseline()
	 */
	final public static GridConstraintsBuilder newPinOnBaseline(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnBaseline, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnBaselineLeading
	 * @see #setAlignAsPinOnBaselineLeading()
	 */
	final public static GridConstraintsBuilder newPinOnBaselineLeading() {
		return new GridConstraintsBuilder(ComponentPlacement.OnBaselineLeading);
	}

	/**
	 * @see ComponentPlacement#OnBaselineLeading
	 * @see #setAlignAsPinOnBaselineLeading()
	 */
	final public static GridConstraintsBuilder newPinOnBaselineLeading(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnBaselineLeading, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnBaselineTrailing
	 * @see #setAlignAsPinOnBaselineTrailing()
	 */
	final public static GridConstraintsBuilder newPinOnBaselineTrailing() {
		return new GridConstraintsBuilder(ComponentPlacement.OnBaselineTrailing);
	}

	/**
	 * @see ComponentPlacement#OnBaselineTrailing
	 * @see #setAlignAsPinOnBaselineTrailing()
	 */
	final public static GridConstraintsBuilder newPinOnBaselineTrailing(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnBaselineTrailing, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnBelowBaseline
	 * @see #setAlignAsPinOnBelowBaseline()
	 */
	final public static GridConstraintsBuilder newPinOnBelowBaseline() {
		return new GridConstraintsBuilder(ComponentPlacement.OnBelowBaseline);
	}

	/**
	 * @see ComponentPlacement#OnBelowBaseline
	 * @see #setAlignAsPinOnBelowBaseline()
	 */
	final public static GridConstraintsBuilder newPinOnBelowBaseline(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnBelowBaseline, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnBelowBaselineLeading
	 * @see #setAlignAsPinOnBelowBaselineLeading()
	 */
	final public static GridConstraintsBuilder newPinOnBelowBaselineLeading() {
		return new GridConstraintsBuilder(ComponentPlacement.OnBelowBaselineLeading);
	}

	/**
	 * @see ComponentPlacement#OnBelowBaselineLeading
	 * @see #setAlignAsPinOnBelowBaselineLeading()
	 */
	final public static GridConstraintsBuilder newPinOnBelowBaselineLeading(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnBelowBaselineLeading, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnBelowBaselineTrailing
	 * @see #setAlignAsPinOnBelowBaselineTrailing()
	 */
	final public static GridConstraintsBuilder newPinOnBelowBaselineTrailing() {
		return new GridConstraintsBuilder(ComponentPlacement.OnBelowBaselineTrailing);
	}

	/**
	 * @see ComponentPlacement#OnBelowBaselineTrailing
	 * @see #setAlignAsPinOnBelowBaselineTrailing()
	 */
	final public static GridConstraintsBuilder newPinOnBelowBaselineTrailing(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnBelowBaselineTrailing, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnFirstLineEnd
	 * @see #setAlignAsPinOnFirstLineEnd()
	 */
	final public static GridConstraintsBuilder newPinOnFirstLineEnd() {
		return new GridConstraintsBuilder(ComponentPlacement.OnFirstLineEnd);
	}

	/**
	 * @see ComponentPlacement#OnFirstLineEnd
	 * @see #setAlignAsPinOnFirstLineEnd()
	 */
	final public static GridConstraintsBuilder newPinOnFirstLineEnd(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnFirstLineEnd, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnFirstLineStart
	 * @see #setAlignAsPinOnFirstLineStart()
	 */
	final public static GridConstraintsBuilder newPinOnFirstLineStart() {
		return new GridConstraintsBuilder(ComponentPlacement.OnFirstLineStart);
	}

	/**
	 * @see ComponentPlacement#OnFirstLineStart
	 * @see #setAlignAsPinOnFirstLineStart()
	 */
	final public static GridConstraintsBuilder newPinOnFirstLineStart(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnFirstLineStart, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnLastLineEnd
	 * @see #setAlignAsPinOnLastLineEnd()
	 */
	final public static GridConstraintsBuilder newPinOnLastLineEnd() {
		return new GridConstraintsBuilder(ComponentPlacement.OnLastLineEnd);
	}

	/**
	 * @see ComponentPlacement#OnLastLineEnd
	 * @see #setAlignAsPinOnLastLineEnd()
	 */
	final public static GridConstraintsBuilder newPinOnLastLineEnd(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnLastLineEnd, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnLastLineStart
	 * @see #setAlignAsPinOnLastLineStart()
	 */
	final public static GridConstraintsBuilder newPinOnLastLineStart() {
		return new GridConstraintsBuilder(ComponentPlacement.OnLastLineStart);
	}

	/**
	 * @see ComponentPlacement#OnLastLineStart
	 * @see #setAlignAsPinOnLastLineStart()
	 */
	final public static GridConstraintsBuilder newPinOnLastLineStart(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnLastLineStart, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnLineEnd
	 * @see #setAlignAsPinOnLineEnd()
	 */
	final public static GridConstraintsBuilder newPinOnLineEnd() {
		return new GridConstraintsBuilder(ComponentPlacement.OnLineEnd);
	}

	/**
	 * @see ComponentPlacement#OnLineEnd
	 * @see #setAlignAsPinOnLineEnd()
	 */
	final public static GridConstraintsBuilder newPinOnLineEnd(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnLineEnd, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#OnLineStart
	 * @see #setAlignAsPinOnLineStart()
	 */
	final public static GridConstraintsBuilder newPinOnLineStart() {
		return new GridConstraintsBuilder(ComponentPlacement.OnLineStart);
	}

	/**
	 * @see ComponentPlacement#OnLineStart
	 * @see #setAlignAsPinOnLineStart()
	 */
	final public static GridConstraintsBuilder newPinOnLineStart(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.OnLineStart, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToBottom
	 * @see #setAlignAsToBottom()
	 */
	final public static GridConstraintsBuilder newToBottom() {
		return new GridConstraintsBuilder(ComponentPlacement.ToBottom);
	}

	/**
	 * @see ComponentPlacement#ToBottom
	 * @see #setAlignAsToBottom()
	 */
	final public static GridConstraintsBuilder newToBottom(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToBottom, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToBottomLeft
	 * @see #setAlignAsToBottomLeft()
	 */
	final public static GridConstraintsBuilder newToBottomLeft() {
		return new GridConstraintsBuilder(ComponentPlacement.ToBottomLeft);
	}

	/**
	 * @see ComponentPlacement#ToBottomLeft
	 * @see #setAlignAsToBottomLeft()
	 */
	final public static GridConstraintsBuilder newToBottomLeft(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToBottomLeft, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToBottomRight
	 * @see #setAlignAsToBottomRight()
	 */
	final public static GridConstraintsBuilder newToBottomRight() {
		return new GridConstraintsBuilder(ComponentPlacement.ToBottomRight);
	}

	/**
	 * @see ComponentPlacement#ToBottomRight
	 * @see #setAlignAsToBottomRight()
	 */
	final public static GridConstraintsBuilder newToBottomRight(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToBottomRight, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToLeft
	 * @see #setAlignAsToLeft()
	 */
	final public static GridConstraintsBuilder newToLeft() {
		return new GridConstraintsBuilder(ComponentPlacement.ToLeft);
	}

	/**
	 * @see ComponentPlacement#ToLeft
	 * @see #setAlignAsToLeft()
	 */
	final public static GridConstraintsBuilder newToLeft(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToLeft, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToRight
	 * @see #setAlignAsToRight()
	 */
	final public static GridConstraintsBuilder newToRight() {
		return new GridConstraintsBuilder(ComponentPlacement.ToRight);
	}

	/**
	 * @see ComponentPlacement#ToRight
	 * @see #setAlignAsToRight()
	 */
	final public static GridConstraintsBuilder newToRight(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToRight, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToTop
	 * @see #setAlignAsToTop()
	 */
	final public static GridConstraintsBuilder newToTop() {
		return new GridConstraintsBuilder(ComponentPlacement.ToTop);
	}

	/**
	 * @see ComponentPlacement#ToTop
	 * @see #setAlignAsToTop()
	 */
	final public static GridConstraintsBuilder newToTop(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToTop, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToTopLeft
	 * @see #setAlignAsToTopLeft()
	 */
	final public static GridConstraintsBuilder newToTopLeft() {
		return new GridConstraintsBuilder(ComponentPlacement.ToTopLeft);
	}

	/**
	 * @see ComponentPlacement#ToTopLeft
	 * @see #setAlignAsToTopLeft()
	 */
	final public static GridConstraintsBuilder newToTopLeft(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToTopLeft, gridX, gridY);
	}

	/**
	 * @see ComponentPlacement#ToTopRight
	 * @see #setAlignAsToTopRight()
	 */
	final public static GridConstraintsBuilder newToTopRight() {
		return new GridConstraintsBuilder(ComponentPlacement.ToTopRight);
	}

	/**
	 * @see ComponentPlacement#ToTopRight
	 * @see #setAlignAsToTopRight()
	 */
	final public static GridConstraintsBuilder newToTopRight(Integer gridX, Integer gridY) {
		return new GridConstraintsBuilder(ComponentPlacement.ToTopRight, gridX, gridY);
	}

	/**
	 * Prints given {@link GridBagConstraints} to standard output as {@link GridConstraintsBuilder} code.<br />
	 * <p>
	 * <b>Important :</b>
	 * <ul>
	 * <li><b>This method is not able to recognise if value is provided as constant or as variable.</b></li>
	 * </ul>
	 * </p>
	 * 
	 * @return back given {@link GridBagConstraints}
	 * @see #toString()
	 * @see GridConstraintsBuilderToCodeConverter
	 */
	public static GridBagConstraints printJavaCode$(GridBagConstraints gbc) {
		GridConstraintsBuilder newFromConstraints = newFromConstraints(gbc);
		System.out.println(GridConstraintsBuilderToCodeConverter.Default.toJaveCode$(null, newFromConstraints).toString());
		return gbc;
	}

	/**
	 *  
	 */
	@SuppressWarnings("unused")
	final private static StringBuilder writeAlignForGCB() {
		StringBuilder ret = new StringBuilder(1024);
		for (ComponentPlacement p : ComponentPlacement.values()) {
			ret.append("\t /**").append("\n");
			ret.append("\t * @see ").append(ComponentPlacement.class.getSimpleName() + "#" + p.name()).append("\n");
			ret.append("\t * @see ").append("#").append(p.getConstructorName()).append("()\n");
			ret.append("\t * @see ").append("#").append(p.getConstructorName()).append("(Integer, Integer)\n");
			ret.append("\t */").append("\n");
			ret.append("final public " //
					+ GridConstraintsBuilder.class.getSimpleName() + " " // 
					+ alignSetName + p.getPlacementKind().getConstructorName() + p.name()//
					+ "( ) {").append("\n");
			ret.append("\t this.align = " + ComponentPlacement.class.getSimpleName() + "." + p.name()).append("; \n");
			ret.append("\t return this; \n");
			ret.append("\t }").append("\n").append("\n");
		}
		return ret;
	}

	/**
	 * @param parameters2Forward can be: "Integer gridX, Integer gridY"
	 * @param forwardedParameters can be: "gridX, gridY"
	 */
	@SuppressWarnings("unused")
	final private static StringBuilder writeConstructorsForGCB(String parameters2Forward, String forwardedParameters) {
		StringBuilder ret = new StringBuilder(1024);
		for (ComponentPlacement p : ComponentPlacement.values()) {
			ret.append("\t /**").append("\n");
			ret.append("\t * @see " + ComponentPlacement.class.getSimpleName() + "#" + p.name()).append("\n");
			ret.append("\t * @see " + "#" + alignSetName + p.getNamePart()).append("()\n");
			ret.append("\t */").append("\n");
			ret.append("final public static " //
					+ GridConstraintsBuilder.class.getSimpleName() + " " // 
					+ "new" + p.getPlacementKind().getConstructorName() + p.name()//
					+ "(" + (parameters2Forward != null ? parameters2Forward : "") + ") {").append("\n");
			ret.append("\t return new " + GridConstraintsBuilder.class.getSimpleName() + "(" + ComponentPlacement.class.getSimpleName() + "." + p.name() + (forwardedParameters != null ? "," + forwardedParameters : "") + ");").append("\n");
			ret.append("\t }").append("\n").append("\n");
		}
		return ret;
	}

	/**
	 * Component align
	 */
	public enum ComponentPlacement {
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally centered. Vertically the component is positioned so that its bottom edge touches the baseline of the starting row. If the starting row does not have a baseline it will be vertically
		 * centered.
		 * 
		 * @since 1.6
		 */
		OnAboveBaseline(PlacementKind.Relative, GridBagConstraints.ABOVE_BASELINE), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally placed along the leading edge. For components with a left-to-right orientation, the leading edge is the left edge. Vertically the component is positioned so that its bottom edge touches
		 * the baseline of the starting row. If the starting row does not have a baseline it will be vertically centered.
		 * 
		 * @since 1.6
		 */
		OnAboveBaselineLeading(PlacementKind.Relative, GridBagConstraints.ABOVE_BASELINE_LEADING), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally placed along the trailing edge. For components with a left-to-right orientation, the trailing edge is the right edge. Vertically the component is positioned so that its bottom edge
		 * touches the baseline of the starting row. If the starting row does not have a baseline it will be vertically centered.
		 * 
		 * @since 1.6
		 */
		OnAboveBaselineTrailing(PlacementKind.Relative, GridBagConstraints.ABOVE_BASELINE_TRAILING), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally centered and vertically aligned along the baseline of the prevailing row. If the component does not have a baseline it will be vertically centered.
		 * 
		 * @see GridBagConstraints#BASELINE
		 * @since 1.6
		 */
		OnBaseline(PlacementKind.Relative, GridBagConstraints.BASELINE), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally placed along the leading edge. For components with a left-to-right orientation, the leading edge is the left edge. Vertically the component is aligned along the baseline of the prevailing
		 * row. If the component does not have a baseline it will be vertically centered.
		 * 
		 * @since 1.6
		 */
		OnBaselineLeading(PlacementKind.Relative, GridBagConstraints.BASELINE_LEADING), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally placed along the trailing edge. For components with a left-to-right orientation, the trailing edge is the right edge. Vertically the component is aligned along the baseline of the
		 * prevailing row. If the component does not have a baseline it will be vertically centered.
		 * 
		 * @since 1.6
		 */
		OnBaselineTrailing(PlacementKind.Relative, GridBagConstraints.BASELINE_TRAILING), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally centered. Vertically the component is positioned so that its top edge touches the baseline of the starting row. If the starting row does not have a baseline it will be vertically
		 * centered.
		 * 
		 * @since 1.6
		 */
		OnBelowBaseline(PlacementKind.Relative, GridBagConstraints.BELOW_BASELINE), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally placed along the leading edge. For components with a left-to-right orientation, the leading edge is the left edge. Vertically the component is positioned so that its top edge touches the
		 * baseline of the starting row. If the starting row does not have a baseline it will be vertically centered.
		 * 
		 * @since 1.6
		 */
		OnBelowBaselineLeading(PlacementKind.Relative, GridBagConstraints.BELOW_BASELINE_LEADING), //
		/**
		 * Possible value for the <code>anchor</code> field. Specifies that the component should be horizontally placed along the trailing edge. For components with a left-to-right orientation, the trailing edge is the right edge. Vertically the component is positioned so that its top edge touches
		 * the baseline of the starting row. If the starting row does not have a baseline it will be vertically centered.
		 * 
		 * @since 1.6
		 */
		OnBelowBaselineTrailing(PlacementKind.Relative, GridBagConstraints.BELOW_BASELINE_TRAILING), //
		/**
		 * Put the component in the center of its display area.
		 * 
		 * @see GridBagConstraints#CENTER
		 */
		OnCenter(GridBagConstraints.CENTER), //
		/**
		 * Put the component on the right side of its display area, centered vertically.
		 * 
		 * @see GridBagConstraints#EAST
		 */
		OnEast(GridBagConstraints.EAST), //
		/**
		 * Place the component in the corner of its display area where the first line of text on a page would normally end for the current <code>ComponentOrienation</code>. Equal to {@link #OnNorthEast} for horizontal, left-to-right orientations and {@link #OnNorthWest} for horizontal, right-to-left
		 * orientations.
		 * 
		 * @see GridBagConstraints#FIRST_LINE_END
		 */
		OnFirstLineEnd(PlacementKind.Relative, GridBagConstraints.FIRST_LINE_END), //
		/**
		 * Place the component in the corner of its display area where the first line of text on a page would normally begin for the current <code>ComponentOrienation</code>. Equal to {@link #OnNorthWest} for horizontal, left-to-right orientations and {@link #OnNorthEast} for horizontal,
		 * right-to-left orientations.
		 * 
		 * @see GridBagConstraints#FIRST_LINE_START
		 */
		OnFirstLineStart(PlacementKind.Relative, GridBagConstraints.FIRST_LINE_START), //
		/**
		 * Place the component in the corner of its display area where the last line of text on a page would normally end for the current <code>ComponentOrienation</code>. Equal to {@link #OnSouthEast} for horizontal, left-to-right orientations and {@link #OnSouthWest} for horizontal, right-to-left
		 * orientations.
		 * 
		 * @see GridBagConstraints#LAST_LINE_END
		 */
		OnLastLineEnd(PlacementKind.Relative, GridBagConstraints.LAST_LINE_END), //
		/**
		 * Place the component in the corner of its display area where the last line of text on a page would normally start for the current <code>ComponentOrienation</code>. Equal to {@link #OnSouthWest} for horizontal, left-to-right orientations and {@link #OnSouthEast} for horizontal,
		 * right-to-left orientations.
		 * 
		 * @see GridBagConstraints#LAST_LINE_START
		 */
		OnLastLineStart(PlacementKind.Relative, GridBagConstraints.LAST_LINE_START), //
		/**
		 * Place the component centered along the edge of its display area where lines of text would normally end for the current <code>ComponentOrienation</code>. Equal to EAST for horizontal, left-to-right orientations and {@link #OnWest} for horizontal, right-to-left orientations.
		 * 
		 * @see GridBagConstraints#LINE_END
		 */
		OnLineEnd(PlacementKind.Relative, GridBagConstraints.LINE_END), //
		/**
		 * Place the component centered along the edge of its display area where lines of text would normally begin for the current <code>ComponentOrienation</code>. Equal to WEST for horizontal, left-to-right orientations and {@link #OnEast} for horizontal, right-to-left orientations.
		 * 
		 * @see GridBagConstraints#LINE_START
		 */
		OnLineStart(PlacementKind.Relative, GridBagConstraints.LINE_START), //
		/**
		 * Put the component at the top of its display area, centered horizontally.
		 * 
		 * @see GridBagConstraints#NORTH
		 */
		OnNorth(GridBagConstraints.NORTH), //
		/**
		 * Put the component at the top-right corner of its display area.
		 * 
		 * @see GridBagConstraints#NORTHEAST
		 */
		OnNorthEast(GridBagConstraints.NORTHEAST), //
		/**
		 * Put the component at the top-left corner of its display area.
		 * 
		 * @see GridBagConstraints#NORTHWEST
		 */
		OnNorthWest(GridBagConstraints.NORTHWEST), //
		/**
		 * Place the component centered along the edge of its display area associated with the end of a page for the current <code>ComponentOrienation</code>. Equal to SOUTH for horizontal orientations.
		 * 
		 * @see GridBagConstraints#PAGE_END
		 */
		OnPageEnd(GridBagConstraints.PAGE_END), //
		/**
		 * Place the component centered along the edge of its display area associated with the start of a page for the current <code>ComponentOrienation</code>. Equal to NORTH for horizontal orientations.
		 * 
		 * @see GridBagConstraints#PAGE_START
		 */
		OnPageStart(GridBagConstraints.PAGE_START), //
		/**
		 * Put the component at the bottom of its display area, centered horizontally.
		 * 
		 * @see GridBagConstraints#SOUTH
		 */
		OnSouth(GridBagConstraints.SOUTH), //
		/**
		 * Put the component at the bottom-right corner of its display area.
		 * 
		 * @see GridBagConstraints#SOUTHEAST
		 */
		OnSouthEast(GridBagConstraints.SOUTHEAST), //
		/**
		 * Put the component at the bottom-left corner of its display area.
		 * 
		 * @see GridBagConstraints#SOUTHWEST
		 */
		OnSouthWest(GridBagConstraints.SOUTHWEST), //
		/**
		 * Put the component on the left side of its display area, centered vertically.
		 * 
		 * @see GridBagConstraints#WEST
		 */
		OnWest(GridBagConstraints.WEST), //

		/**
		 * Put the component at the bottom of its display area, centered horizontally.
		 * 
		 * @see GridBagConstraints#SOUTH
		 */
		ToBottom(PlacementKind.Way, GridBagConstraints.SOUTH), //

		/**
		 * Put the component at the bottom-left corner of its display area.
		 * 
		 * @see GridBagConstraints#SOUTHWEST
		 */
		ToBottomLeft(PlacementKind.Way, GridBagConstraints.SOUTHWEST), //

		/**
		 * Put the component at the bottom-right corner of its display area.
		 * 
		 * @see GridBagConstraints#SOUTHEAST
		 */
		ToBottomRight(PlacementKind.Way, GridBagConstraints.SOUTHEAST), //

		/**
		 * Put the component on the left side of its display area, centered vertically.
		 * 
		 * @see GridBagConstraints#WEST
		 */
		ToLeft(PlacementKind.Way, GridBagConstraints.WEST), //

		/**
		 * Put the component on the right side of its display area, centered vertically.
		 * 
		 * @see GridBagConstraints#EAST
		 */
		ToRight(PlacementKind.Way, GridBagConstraints.EAST), //

		/**
		 * Put the component at the top of its display area, centered horizontally.
		 * 
		 * @see GridBagConstraints#NORTH
		 */
		ToTop(PlacementKind.Way, GridBagConstraints.NORTH), //

		/**
		 * Put the component at the top-left corner of its display area.
		 * 
		 * @see GridBagConstraints#NORTHWEST
		 */
		ToTopLeft(PlacementKind.Way, GridBagConstraints.NORTHWEST), //

		/**
		 * Put the component at the top-right corner of its display area.
		 * 
		 * @see GridBagConstraints#NORTHEAST
		 */
		ToTopRight(PlacementKind.Way, GridBagConstraints.NORTHEAST), //

		;

		private final PlacementKind	placementKind;

		/**
		 * @see GridBagConstraints
		 */
		private final int			valueForConstraint;

		private ComponentPlacement(final int valueForConstraint) {
			this.placementKind = PlacementKind.Direction;
			this.valueForConstraint = valueForConstraint;
			// register
			this.placementKind.register(this);
		}

		private ComponentPlacement(PlacementKind placementKind, final int valueForConstraint) {
			if (placementKind == null) { throw new NullPointerException(PlacementKind.class.getSimpleName()); }
			this.placementKind = placementKind;
			this.valueForConstraint = valueForConstraint;
			// register
			this.placementKind.register(this);
		}

		public String getConstructorName() {
			return "new" + placementKind.getConstructorName() + name();
		}

		public String getNamePart() {
			return placementKind.getConstructorName() + name();
		}

		/**
		 * @return the placementKind
		 */
		public PlacementKind getPlacementKind() {
			return placementKind;
		}

		/**
		 * @return the value representing {@link GridBagConstraints#anchor}
		 */
		public int getValueForConstraint() {
			return valueForConstraint;
		}

		/**
		 * @param anchor
		 */
		public static ComponentPlacement forConstraintValue(int anchor) {
			for (ComponentPlacement placement : ComponentPlacement.values()) {
				if (placement.valueForConstraint == anchor) { return placement; }
			}
			return null;
		}
	}

	/**
	 * There will be tabulator before semicolon, so it will help while copy-paste and do not affect code formatter.
	 * 
	 * @see #printJavaCode$(GridBagConstraints)
	 * @see GridConstraintsBuilder#printJavaCode$(GridBagConstraints)
	 */
	public enum GridConstraintsBuilderToCodeConverter {

		Classic {
			@Override
			public StringBuilder toJaveCode$(StringBuilder dest, GridConstraintsBuilder element) {
				if (dest == null) {
					dest = new StringBuilder(200);
				}
				if (element == null) {//
					dest.append((String) null).append("\t;");
					return dest;
				}

				appendNewXYAsCode(dest, element);
				appendSetSizeAsCode(dest, element);
				appendSetWeightAsCode(dest, element);

				{
					StringBuilder secondLine = new StringBuilder(32);
					appendFillAsCode(secondLine, element);
					appendSetInsetsAsCode(secondLine, element);
					appendSetInternalPaddingAsCode(secondLine, element);
					if (secondLine.length() > 0) {
						dest.append(newLineSeparator)//
								.append(secondLine);
					}
				}

				return dest.append(".").append(methods.build).append("()").append("\t;");
			}

		},

		Default {
			@Override
			public StringBuilder toJaveCode$(StringBuilder dest, GridConstraintsBuilder element) {
				return def.toJaveCode$(dest, element);
			}
		},

		SeparationOnDirections {

			@Override
			public StringBuilder toJaveCode$(StringBuilder dest, GridConstraintsBuilder element) {
				if (dest == null) {
					dest = new StringBuilder(200);
				}
				if (element == null) {//
					dest.append((String) null).append("\t;");
					return dest;
				}

				appendNewAsCode(dest, element);

				dest.append(newLineSeparator);
				appendSetHorizontalsAsCode(dest, element);

				dest.append(newLineSeparator);
				appendSetVerticalsAsCode(dest, element);

				return dest.append(".").append(methods.build).append("()").append("\t;");
			}

		},

		XYLaterSplit {
			@Override
			public StringBuilder toJaveCode$(StringBuilder dest, GridConstraintsBuilder element) {
				if (element == null) { throw new NullPointerException(GridConstraintsBuilder.class.getSimpleName()); }
				if (dest == null) {
					dest = new StringBuilder(200);
				}

				appendNewXYAsCode(dest, element);
				appendSetSizeAsCode(dest, element);
				appendSetWeightAsCode(dest, element);
				{
					StringBuilder secondLine = new StringBuilder(50);
					appendFillAsCode(secondLine, element);
					appendSetXYMarginAsCode(secondLine, element);
					if (secondLine.length() > 0) {
						dest.append(newLineSeparator).append(secondLine);
					}
				}

				return dest.append(".").append(methods.build).append("()").append("\t;");
			}

		},
		;

		/**
		 * <p>
		 * <b>Important :</b>
		 * <ul>
		 * <li><b>This method is not able to recognise if value is provided as constant or as variable.</b></li>
		 * </ul>
		 * </p>
		 */
		public GridBagConstraints printJavaCode$(GridBagConstraints gbc) {
			GridConstraintsBuilder newFromConstraints = newFromConstraints(gbc);
			System.out.println(toJaveCode$(null, newFromConstraints).toString());
			return gbc;
		}

		/**
		 * <p>
		 * <b>Important :</b>
		 * <ul>
		 * <li><b>This method is not able to recognise if value is provided as constant or as variable.</b></li>
		 * </ul>
		 * </p>
		 */
		public GridConstraintsBuilder printJavaCode$(GridConstraintsBuilder gcb) {
			System.out.println(toJaveCode$(null, gcb).toString());
			return gcb;
		}

		abstract public StringBuilder toJaveCode$(StringBuilder appendTo, GridConstraintsBuilder element);

		/**
		 * Make called converter to be used as {@link #Default}
		 * 
		 * @throws IllegalArgumentException when called from {@link #Default}
		 */
		public void useAsDefault() {
			setDefault(this);
		}

		private static GridConstraintsBuilderToCodeConverter	def					= Classic;

		private static final String								newLineSeparator	= "//\n\t";

		private static void appendFillAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			if (element.getFill() == GridConstraintsFill.None) { return; }
			appendTo.append('.').append("fill").append(element.getFill().name()).append("()");
		}

		/**
		 */
		private static void appendNewAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			appendTo.append(GridConstraintsBuilder.class.getSimpleName())//
					.append('.').append(element.getAlign().getConstructorName()).append("()");
		}

		/**
		 */
		private static void appendNewXYAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			appendTo.append(GridConstraintsBuilder.class.getSimpleName());
			appendTo.append('.').append(element.getAlign().getConstructorName())//
					.append('(').append(element.getX()).append(',').append(element.getY()).append(")");
		}

		/**
		 * @return <code>true</code> if proper code was appended
		 * @see #appendSetVerticalsAsCode(StringBuilder, GridConstraintsBuilder)
		 */
		private static boolean appendSetHorizontalsAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			// gridXPosition, Integer width, Integer weight
			Double weightX = element.getWeightX();
			appendTo.append(".").append(methods.setHorizontals)//
					.append("(").append(element.getX())//
					.append(", ").append(element.getWidthX());//
			if (weightX != null) {
				appendTo.append(", ").append(weightX);//
			}
			appendTo.append(")");//

			if (element.isFilledHorizontal()) {
				appendTo.append(".").append("fill").append(GridConstraintsFill.Horizontal.name()).append("()");
			}

			if (element.insetLeft != 0 || element.insetRight != 0 || element.ipadx != 0) {
				appendTo.append(".").append(methods.setHorMarginX).append("(").append(element.insetLeft).append(",").append(element.ipadx).append(",").append(element.insetRight).append(")");
			}
			return true;

		}

		private static void appendSetInsetsAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			if (element.isAnyInsetWithNotDefalutValue()) { //
				// /setInset(int left, int top, int right, int bottom)
				appendTo.append(".").append(methods.setInsets)//
						.append("(")//
						.append(element.getInsetLeft()).append(",")//
						.append(element.getInsetTop()).append(",")//
						.append(element.getInsetRight()).append(",")//
						.append(element.getInsetBottom()).append(")");//
			}
		}

		private static void appendSetInternalPaddingAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			if ((element.getHorIpadX() != defaultConstraint.ipadx)//
					|| (element.getVerIpadY() != defaultConstraint.weighty)) {
				appendTo.append(".").append(methods.setInternalPadding)//
						.append("(").append(element.getHorIpadX()).append(",").append(element.getVerIpadY()).append(")");
			}
		}

		private static void appendSetSizeAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			if ((element.widthX != null && element.widthX != defaultConstraint.gridwidth)//
					|| (element.heightY != null && element.heightY != defaultConstraint.gridheight)) { //
				appendTo.append(".").append(methods.setSize)//
						.append("(").append(element.getWidthX()).append(",").append(element.getHeightY()).append(")");//
			}
		}

		private static void appendSetVerticalsAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			Double weightY = element.getWeightY();
			// gridXPosition, Integer width, Integer weight
			appendTo.append(".").append(methods.setVerticals)//
					.append("(").append(element.getY())//
					.append(", ").append(element.getHeightY());//
			if (weightY != null) {
				appendTo.append(", ").append(weightY);//
			}
			appendTo.append(")");//

			if (element.isFilledVertical()) {
				appendTo.append(".").append("fill").append(GridConstraintsFill.Vertical.name()).append("()");
			}

			if (element.insetTop != 0 || element.insetBottom != 0 || element.ipady != 0) {
				appendTo.append(".").append(methods.setVerMarginY).append("(").append(element.insetTop).append(",").append(element.ipady).append(",").append(element.insetBottom).append(")");
			}

		}

		/**
		 * 
		 */
		private static void appendSetWeightAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			if ((element.weightX != null && element.weightX != defaultConstraint.weightx)//
					|| (element.weightY != null && element.weightY != defaultConstraint.weighty)) {
				appendTo.append(".").append(methods.setWeight)//
						.append("(").append(element.getFinalWeightX()).append(",").append(element.getFinalWeightY()).append(")");
			}
		}

		private static void appendSetXYMarginAsCode(StringBuilder appendTo, GridConstraintsBuilder element) {
			boolean isX = element.insetLeft != 0 || element.insetRight != 0 || element.ipadx != 0;
			boolean isY = element.insetTop != 0 || element.insetBottom != 0 || element.ipady != 0;

			if (isX) {
				appendTo.append(".").append(methods.setHorMarginX).append("(").append(element.insetLeft).append(",").append(element.ipadx).append(",").append(element.insetRight).append(")");
			}
			if (isY) {
				appendTo.append(".").append(methods.setVerMarginY).append("(").append(element.insetTop).append(",").append(element.ipady).append(",").append(element.insetBottom).append(")");
			}
		}

		/**
		 * @param def the default {@link GridConstraintsBuilderToCodeConverter} to use
		 */
		private static void setDefault(GridConstraintsBuilderToCodeConverter def) {
			if (def == null) { throw new NullPointerException(GridConstraintsBuilderToCodeConverter.class.getSimpleName() + " default value"); }
			if (def == Default) { throw new IllegalArgumentException("Cannot use '" + Default + "' as default value"); }
			GridConstraintsBuilderToCodeConverter.def = def;
		}

	}

	/**
	 * <p>
	 * Fill is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.
	 * </p>
	 * 
	 * @see #fillBoth()
	 * @see #fillHorizontal()
	 * @see #fillNone()
	 * @see #fillVertical()
	 * @see #getFill()
	 * @see #getFillValue()
	 * @see #setFill(GridConstraintsFill)
	 * @see #setFillAsBoth()
	 * @see #setFillAsHorizontal()
	 * @see #setFillAsNone()
	 * @see #setFillAsVertical()
	 * @see GridBagConstraints#fill
	 * @see GridConstraintsBuilder.GridConstraintsFill
	 */
	public enum GridConstraintsFill {
		/**
		 * Resize the component both horizontally and vertically.
		 */
		Both(GridBagConstraints.BOTH), //
		/**
		 * Resize the component horizontally but not vertically.
		 */
		Horizontal(GridBagConstraints.HORIZONTAL), //
		/**
		 * Do not resize the component.
		 */
		None(GridBagConstraints.NONE), //
		/**
		 * Resize the component vertically but not horizontally.
		 */
		Vertical(GridBagConstraints.VERTICAL), //
		;
		public final int	valueForConstraint;

		private GridConstraintsFill(int valueForConstraint) {
			this.valueForConstraint = valueForConstraint;
		}

		/**
		 * @return the valueForConstraint
		 */
		public int getValueForConstraint() {
			return valueForConstraint;
		}

		public static GridConstraintsFill forConstraintValue(int valueForConstraint) {
			GridConstraintsFill fill = forConstraintValueTry(valueForConstraint);
			if (fill != null) { return fill; }
			throw new IllegalArgumentException("There is no " + GridConstraintsFill.class.getSimpleName() + "connected wit given constraint value(" + valueForConstraint + ") ");
		}

		public static GridConstraintsFill forConstraintValueTry(int valueForConstraint) {
			for (GridConstraintsFill fill : GridConstraintsFill.values()) {
				if (fill.valueForConstraint == valueForConstraint) { return fill; }
			}
			throw new IllegalArgumentException("There is no " + GridConstraintsFill.class.getSimpleName() + "connected wit given constraint value(" + valueForConstraint + ") ");
		}
	}

	public final class methods {

		/**
		 * @see GridConstraintsBuilder#build()
		 */
		final static public String	build							= "build";

		/**
		 * @see GridConstraintsBuilder#buildOn(Integer, Integer)
		 */
		final static public String	buildOn							= "buildOn";

		/**
		 * @see GridConstraintsBuilder#buildOnX(Integer)
		 */
		final static public String	buildOnX						= "buildOnX";

		/**
		 * @see GridConstraintsBuilder#buildOnY(Integer)
		 */
		final static public String	buildOnY						= "buildOnY";

		/**
		 * @see GridConstraintsBuilder#clone()
		 * @see GridConstraintsBuilder#clone()
		 */
		final static public String	clone							= "clone";

		/**
		 * @see GridConstraintsBuilder#equals(Object)
		 * @see GridConstraintsBuilder#equals(GridBagConstraints)
		 * @see GridConstraintsBuilder#equals(GridConstraintsBuilder)
		 */
		final static public String	equals							= "equals";

		/**
		 * @see GridConstraintsBuilder#fillBoth()
		 */
		final static public String	fillBoth						= "fillBoth";

		/**
		 * @see GridConstraintsBuilder#fillHorizontal()
		 */
		final static public String	fillHorizontal					= "fillHorizontal";

		/**
		 * @see GridConstraintsBuilder#fillNone()
		 */
		final static public String	fillNone						= "fillNone";

		/**
		 * @see GridConstraintsBuilder#fillVertical()
		 */
		final static public String	fillVertical					= "fillVertical";

		/**
		 * @see GridConstraintsBuilder#getAlign()
		 */
		final static public String	getAlign						= "getAlign";

		/**
		 * @see GridConstraintsBuilder#getAlignValue()
		 */
		final static public String	getAlignValue					= "getAlignValue";

		/**
		 * @see GridConstraintsBuilder#getFill()
		 */
		final static public String	getFill							= "getFill";

		/**
		 * @see GridConstraintsBuilder#getFillValue()
		 */
		final static public String	getFillValue					= "getFillValue";

		/**
		 * @see GridConstraintsBuilder#getFinalHeightY()
		 */
		final static public String	getFinalHeightY					= "getFinalHeightY";

		/**
		 * @see GridConstraintsBuilder#getFinalWeightX()
		 */
		final static public String	getFinalWeightX					= "getFinalWeightX";

		/**
		 * @see GridConstraintsBuilder#getFinalWeightY()
		 */
		final static public String	getFinalWeightY					= "getFinalWeightY";

		/**
		 * @see GridConstraintsBuilder#getFinalWidthX()
		 */
		final static public String	getFinalWidthX					= "getFinalWidthX";

		/**
		 * @see GridConstraintsBuilder#getHeightY()
		 */
		final static public String	getHeightY						= "getHeightY";

		/**
		 * @see GridConstraintsBuilder#getHorIpadX()
		 */
		final static public String	getHorIpadX						= "getHorIpadX";

		/**
		 * @see GridConstraintsBuilder#getInsetBottom()
		 */
		final static public String	getInsetBottom					= "getInsetBottom";

		/**
		 * @see GridConstraintsBuilder#getInsetLeft()
		 */
		final static public String	getInsetLeft					= "getInsetLeft";

		/**
		 * @see GridConstraintsBuilder#getInsetRight()
		 */
		final static public String	getInsetRight					= "getInsetRight";

		/**
		 * @see GridConstraintsBuilder#getInsets()
		 */
		final static public String	getInsets						= "getInsets";

		/**
		 * @see GridConstraintsBuilder#getInsetTop()
		 */
		final static public String	getInsetTop						= "getInsetTop";

		/**
		 * @see GridConstraintsBuilder#getVerIpadY()
		 */
		final static public String	getVerIpadY						= "getVerIpadY";

		/**
		 * @see GridConstraintsBuilder#getWeightX()
		 */
		final static public String	getWeightX						= "getWeightX";

		/**
		 * @see GridConstraintsBuilder#getWeightY()
		 */
		final static public String	getWeightY						= "getWeightY";

		/**
		 * @see GridConstraintsBuilder#getWidthX()
		 */
		final static public String	getWidthX						= "getWidthX";

		/**
		 * @see GridConstraintsBuilder#getX()
		 */
		final static public String	getX							= "getX";

		/**
		 * @see GridConstraintsBuilder#getY()
		 */
		final static public String	getY							= "getY";

		/**
		 * @see GridConstraintsBuilder#isAnyInsetWithNotDefalutValue()
		 */
		final static public String	isAnyInsetWithNotDefalutValue	= "isAnyInsetWithNotDefalutValue";

		/**
		 * @see GridConstraintsBuilder#isFilledBoth()
		 */
		final static public String	isFilledBoth					= "isFilledBoth";

		/**
		 * @see GridConstraintsBuilder#isFilledHorizontal()
		 */
		final static public String	isFilledHorizontal				= "isFilledHorizontal";

		/**
		 * @see GridConstraintsBuilder#isFilledNone()
		 */
		final static public String	isFilledNone					= "isFilledNone";

		/**
		 * @see GridConstraintsBuilder#isFilledVertical()
		 */
		final static public String	isFilledVertical				= "isFilledVertical";

		/**
		 * @see GridConstraintsBuilder#isXRelative()
		 */
		final static public String	isXRelative						= "isXRelative";

		/**
		 * @see GridConstraintsBuilder#isYRelative()
		 */
		final static public String	isYRelative						= "isYRelative";

		/**
		 * @see GridConstraintsBuilder#provide()
		 * @see GridConstraintsBuilder#provide()
		 */
		final static public String	provide							= "provide";

		/**
		 * @see GridConstraintsBuilder#setAlign(ComponentPlacement)
		 */
		final static public String	setAlign						= "setAlign";

		/**
		 * @see GridConstraintsBuilder#setFill(GridConstraintsFill)
		 */
		final static public String	setFill							= "setFill";

		/**
		 * @see GridConstraintsBuilder#setFillAsBoth()
		 */
		final static public String	setFillAsBoth					= "setFillAsBoth";

		/**
		 * @see GridConstraintsBuilder#setFillAsHorizontal()
		 */
		final static public String	setFillAsHorizontal				= "setFillAsHorizontal";

		/**
		 * @see GridConstraintsBuilder#setFillAsNone()
		 */
		final static public String	setFillAsNone					= "setFillAsNone";

		/**
		 * @see GridConstraintsBuilder#setFillAsVertical()
		 */
		final static public String	setFillAsVertical				= "setFillAsVertical";

		/**
		 * @see GridConstraintsBuilder#setHeightY(Integer)
		 */
		final static public String	setHeightY						= "setHeightY";

		/**
		 * @see GridConstraintsBuilder#setHeightYTillLastRow()
		 */
		final static public String	setHeightYTillLastRow			= "setHeightYTillLastRow";

		/**
		 * @see GridConstraintsBuilder#setHeightYToBeforeLastRow()
		 */
		final static public String	setHeightYToBeforeLastRow		= "setHeightYToBeforeLastRow";

		/**
		 * @see GridConstraintsBuilder#setHorInsetsX(int, int)
		 */
		final static public String	setHorInsetsX					= "setHorInsetsX";

		/**
		 * @see GridConstraintsBuilder#setHorIpadX(int)
		 */
		final static public String	setHorIpadX						= "setHorIpadX";

		/**
		 * @see GridConstraintsBuilder#setHorizontals(Integer, Integer, Integer)
		 * @see GridConstraintsBuilder#setHorizontals(Integer, Integer, Double)
		 * @see GridConstraintsBuilder#setHorizontals(Integer, Integer)
		 */
		final static public String	setHorizontals					= "setHorizontals";

		/**
		 * @see GridConstraintsBuilder#setHorMarginX(int, int, int)
		 */
		final static public String	setHorMarginX					= "setHorMarginX";

		/**
		 * @see GridConstraintsBuilder#setInsetBottom(int)
		 */
		final static public String	setInsetBottom					= "setInsetBottom";

		/**
		 * @see GridConstraintsBuilder#setInsetLeft(int)
		 */
		final static public String	setInsetLeft					= "setInsetLeft";

		/**
		 * @see GridConstraintsBuilder#setInsetRight(int)
		 */
		final static public String	setInsetRight					= "setInsetRight";

		/**
		 * @see GridConstraintsBuilder#setInsets(Insets)
		 * @see GridConstraintsBuilder#setInsets(int, int, int, int)
		 */
		final static public String	setInsets						= "setInsets";

		/**
		 * @see GridConstraintsBuilder#setInsetTop(int)
		 */
		final static public String	setInsetTop						= "setInsetTop";

		/**
		 * @see GridConstraintsBuilder#setInternalPadding(int, int)
		 */
		final static public String	setInternalPadding				= "setInternalPadding";

		/**
		 * @see GridConstraintsBuilder#setSize(Integer, Integer)
		 */
		final static public String	setSize							= "setSize";

		/**
		 * @see GridConstraintsBuilder#setVerInsetsY(int, int)
		 */
		final static public String	setVerInsetsY					= "setVerInsetsY";

		/**
		 * @see GridConstraintsBuilder#setVerIpadY(int)
		 */
		final static public String	setVerIpadY						= "setVerIpadY";

		/**
		 * @see GridConstraintsBuilder#setVerMarginY(int, int, int)
		 */
		final static public String	setVerMarginY					= "setVerMarginY";

		/**
		 * @see GridConstraintsBuilder#setVerticals(Integer, Integer, Integer)
		 * @see GridConstraintsBuilder#setVerticals(Integer, Integer, Double)
		 * @see GridConstraintsBuilder#setVerticals(Integer, Integer)
		 */
		final static public String	setVerticals					= "setVerticals";

		/**
		 * @see GridConstraintsBuilder#setWeight(Double, Double)
		 * @see GridConstraintsBuilder#setWeight(Integer, Integer)
		 */
		final static public String	setWeight						= "setWeight";

		/**
		 * @see GridConstraintsBuilder#setWeightX(Double)
		 * @see GridConstraintsBuilder#setWeightX(Integer)
		 */
		final static public String	setWeightX						= "setWeightX";

		/**
		 * @see GridConstraintsBuilder#setWeightY(Double)
		 * @see GridConstraintsBuilder#setWeightY(Integer)
		 */
		final static public String	setWeightY						= "setWeightY";

		/**
		 * @see GridConstraintsBuilder#setWidthX(Integer)
		 */
		final static public String	setWidthX						= "setWidthX";

		/**
		 * @see GridConstraintsBuilder#setWidthXTillLastCell()
		 */
		final static public String	setWidthXTillLastCell			= "setWidthXTillLastCell";

		/**
		 * @see GridConstraintsBuilder#setWidthXToBeforeLastCell()
		 */
		final static public String	setWidthXToBeforeLastCell		= "setWidthXToBeforeLastCell";

		/**
		 * @see GridConstraintsBuilder#setX(Integer)
		 */
		final static public String	setX							= "setX";

		/**
		 * @see GridConstraintsBuilder#setXAsRelative()
		 */
		final static public String	setXAsRelative					= "setXAsRelative";

		/**
		 * @see GridConstraintsBuilder#setXY(Integer, Integer)
		 */
		final static public String	setXY							= "setXY";

		/**
		 * @see GridConstraintsBuilder#setY(Integer)
		 */
		final static public String	setY							= "setY";

		/**
		 * @see GridConstraintsBuilder#setYAsRelative()
		 */
		final static public String	setYAsRelative					= "setYAsRelative";

		/**
		 * @see GridConstraintsBuilder#toString()
		 */
		final static public String	toString						= "toString";
	}

	private enum PlacementKind {
		/**
		 * Like geografical
		 */
		Direction(""), // Anchor
		Relative("Pin"), //
		/**
		 * Left ...
		 */
		Way(""), // Align
		;

		private final ArrayList<ComponentPlacement>	cache	= new ArrayList<ComponentPlacement>();

		private final String						constructorName;

		private PlacementKind(String constructorName) {
			this.constructorName = constructorName.intern();
		}

		public ComponentPlacement forConstraintValueTry(int anchor) {
			for (ComponentPlacement placement : cache) {
				if (placement.valueForConstraint == anchor) { return placement; }
			}
			return null;
		}

		/**
		 * @return the constructorName
		 */
		public String getConstructorName() {
			return constructorName;
		}

		protected void register(ComponentPlacement componentPlacement) {
			if (componentPlacement == null) { throw new NullPointerException(ComponentPlacement.class.getSimpleName()); }
			if (componentPlacement.placementKind != this) { throw new IllegalArgumentException(PlacementKind.class.getSimpleName() + " do not match"); }
			if (forConstraintValueTry(componentPlacement.valueForConstraint) != null) { throw new IllegalArgumentException("Duplicated " + ComponentPlacement.class.getSimpleName() + "(" + componentPlacement + ")"); }
			cache.add(componentPlacement);
		}
	}

}

