public void setFloating(final Dockable dockable, boolean floating,
			Point screenPosition) {
		if (dockable == null)
			throw new NullPointerException("dockable");

		DockableState currentState = getDockableState(dockable);
		DockableState.Location currentLocation = getLocation(currentState);
		SingleDockableContainer dockableContainer = DockingUtilities
				.findSingleDockableContainer(dockable);

		if (floating) {
			DockableState.Location location = dockable.getDockKey()
					.getLocation();
			RelativeDockablePosition position = null;
			switch (location) {
			case DOCKED:
				position = new RelativeDockablePosition(
						getRelativeAncestorContainer(dockable), dockable);
				break;
			case HIDDEN:
				position = currentState.getPosition(); // get the position that
														// was stored before
				break;
			case FLOATING:
				// from floating..to floating. It's still possible, if the
				// component was previously tabbed (now it will have its
				// own window
				if (DockingUtilities.findTabbedDockableContainer(dockable) != null) {
					// ok, it was tabbed and floating
				} else {
					throw new IllegalArgumentException("floating not tabbed");
				}
				break;
			case CLOSED:
				break;
			default:
				throw new IllegalArgumentException("not docked " + location);
			}

			DockableState newState = new DockableState(this, dockable,
					DockableState.Location.FLOATING, position);
			DockableStateWillChangeEvent event = new DockableStateWillChangeEvent(
					currentState, newState);

			if (location == DockableState.Location.FLOATING) {
				// floating to floating (create a new floating dialog by
				// removing a dockable from a detached tab)
				// note (@todo): as of version 2.1, we should trigger a
				// dockingActionEvent here... but which one ?
				// an addDockable with a floating state ?
				Dimension previousSize = null;
				remove(dockable);
				if (dockableContainer != null) {
					previousSize = ((Component) dockableContainer).getSize();
				}
				FloatingDockableContainer fdc = createFloatingDockableContainer(dockable);
				// JDialog dialog = (JDialog) fdc;

				if (previousSize != null) {
					DockingUtilities.setSize(fdc, previousSize); // 2006/02/20
					DockingUtilities.validate(fdc);
					// dialog.setSize(previousSize);
					// dialog.validate();
				} else {
					DockingUtilities.pack(fdc);
					// dialog.pack();
				}

				if (screenPosition == null) {
					DockingUtilities.setLocationRelativeTo(fdc, this);
					// dialog.setLocationRelativeTo(this);
				} else {
					DockingUtilities.setLocation(fdc, screenPosition);
					// dialog.setLocation(screenPosition);
				}
				DockingUtilities.setVisible(fdc, true);
				// dialog.setVisible(true);

			} else if (currentState != null) {
				DockingActionEvent dae = new DockingActionSimpleStateChangeEvent(
						this, dockable, currentLocation,
						DockableState.Location.FLOATING);
				if (isDockingActionAccepted(dae, event)) {
					// not already floating so we trigger state events
					Dimension previousSize = null;
					if (dockableContainer != null) {
						previousSize = ((Component) dockableContainer)
								.getSize();
					}
					remove(dockable);

					// store a return state, based on the current state +
					// updated relative position
					storePreviousFloatingState(dockable, new DockableState(
							currentState, position));

					FloatingDockableContainer fdc = createFloatingDockableContainer(dockable);
					// JDialog dialog = (JDialog) fdc;

					if (previousSize != null) {
						DockingUtilities.setSize(fdc, previousSize);
						DockingUtilities.validate(fdc);
						// dialog.setSize(previousSize);
						// dialog.validate();
					} else {
						DockingUtilities.pack(fdc);
						// dialog.pack();
					}

					if (screenPosition == null) {
						DockingUtilities.setLocationRelativeTo(fdc, this);
						// dialog.setLocationRelativeTo(this);
					} else {
						DockingUtilities.setLocation(fdc, screenPosition);
						// dialog.setLocation(screenPosition);
					}
					DockingUtilities.setVisible(fdc, true);
					// dialog.setVisible(true);

					context.setDockableState(dockable, newState);
					dockable.getDockKey().setLocation(
							DockableState.Location.FLOATING);
					fireDockingAction(dae, new DockableStateChangeEvent(
							currentState, newState));

					if (dockable instanceof CompoundDockable) {
						updateCompoundChildrenState(
								(CompoundDockable) dockable,
								DockableState.Location.FLOATING);
					}

					DockingUtilities.updateResizeWeights(dockingPanel);
					revalidate();
				}
			}
		} else { // attach !
			// remove the button, show again the view

			// was the dockable docked or hidden ?
			DockableState previousState = getPreviousDockableState(dockable);

			DockableState newState = new DockableState(this, dockable,
					previousState.getLocation(), previousState.getPosition());
			DockableStateWillChangeEvent event = new DockableStateWillChangeEvent(
					currentState, newState);
			DockingActionEvent dae;
			if (currentState != null && currentState.isFloating()) {
				if (previousState.isDocked()) {

					RelativeDockablePosition prevPos = previousState
							.getPosition();
					Container relativeAncestor = prevPos
							.getRelativeAncestorContainer();
					if (relativeAncestor == null) {
						relativeAncestor = dockingPanel; // safety : @todo we
															// have to refactor
															// xmlBuildFloatingNode
															// to
						// store the relativeAncestorContainer
					}
					dae = RelativeDockingUtilities.getInsertionDockingAction(
							relativeAncestor, dockable, currentState, newState);
				} else if (previousState.isHidden()) { // it was hidden
					dae = new DockingActionSimpleStateChangeEvent(this,
							dockable, DockableState.Location.FLOATING,
							DockableState.Location.HIDDEN);
				} else {
					// shoudn't be possible
					throw new RuntimeException();
				}
				if (isDockingActionAccepted(dae, event)) {
					removePreviousFloatingState(dockable);

					Container parentOfSdc = null; // 2005/10/07
					parentOfSdc = ((JComponent) dockableContainer).getParent();
					removeContainer(dockableContainer);
					FloatingDockableContainer fdc = (FloatingDockableContainer) SwingUtilities
							.getWindowAncestor(dockable.getComponent());
					if (parentOfSdc instanceof TabbedDockableContainer) {
						// dockable was contained in a tab on the floatable : we
						// must not dispose the window
					} else {
						DockingUtilities.dispose(fdc);
						// ((JDialog)fdc).dispose();
					}

					context.setDockableState(dockable, newState);

					if (previousState.isDocked()) {
						show(dockable, dae); // TODO Fix this null
					} else if (previousState.isHidden()) { // it was hidden
						floatingToHide(dockable, previousState.getPosition());
					} else { // unmanaged state
						throw new RuntimeException();
					}

					dockable.getDockKey().setLocation(
							previousState.getLocation());

					fireDockingAction(dae, new DockableStateChangeEvent(
							currentState, newState));

					dockable.getComponent().requestFocus();

					if (dockable instanceof CompoundDockable) {
						updateCompoundChildrenState(
								(CompoundDockable) dockable,
								newState.getLocation());
					}

					DockingUtilities.updateResizeWeights(dockingPanel);
					revalidate();

				}
			}

		}
	}