public FibonacciHeapItem<T> deleteMin() throws NoSuchElementException {
		if (isEmpty()) {
			throw new NoSuchElementException("This heap is empty.");
		}
		
		/*
		 * remove the minimum node x from this heap and concatenate the list of
		 * children of x with the list of roots of this heap other than x
		 */
		TreeNode<T> x = minimumNode;
		FibonacciHeapItem<T> minimumItem = x.item;
		
		size--;
		
		// remember some node to start with the linking step later on
		TreeNode<T> someListNode;
		
		if (x.rightSibling == x) {
			if (x.someChild == null) {
				// the heap consists of only the root node
				minimumNode = null;
				
				return minimumItem;
			} else {
				// root has no siblings - apply linking step to list of children
				someListNode = x.someChild;
			}
		} else {
			if (x.someChild == null) {
				// root has no children - apply linking step to list of siblings
				x.leftSibling.rightSibling = x.rightSibling;
				x.rightSibling.leftSibling = x.leftSibling;
				
				someListNode = x.leftSibling;
			} else {
				// concatenate children and siblings and apply linking step
				x.leftSibling.rightSibling = x.someChild;
				x.someChild.leftSibling.rightSibling = x.rightSibling;
				x.rightSibling.leftSibling = x.someChild.leftSibling;
				x.someChild.leftSibling = x.leftSibling;

				someListNode = x.someChild;
			}
		}

		
		// Linking Step.
		/*
		 * create an hashtable indexed by rank, from one up to the maximum
		 * possible rank, each entry pointing to a tree root
		 */
		java.util.Hashtable<Integer, TreeNode<T>> rankIndexedRoots = new
			java.util.Hashtable<Integer, TreeNode<T>>();
		
		// insert the roots one-by-one into the appropriate table positions
		TreeNode<T> nextOldRoot = someListNode;
		
		do {
			TreeNode<T> toBeInserted = nextOldRoot;
			nextOldRoot = nextOldRoot.rightSibling;
			
			while (toBeInserted != null) {
				/*
				 * if the position is already occupied, perform a linking
				 * step and attempt to insert the root of the new tree into
				 * the next higher position
				 */
				TreeNode<T> other = rankIndexedRoots.get(toBeInserted.rank);
				
				if (other != null) {
					rankIndexedRoots.remove(toBeInserted.rank);
					toBeInserted = toBeInserted.link(other);
				} else {
					rankIndexedRoots.put(toBeInserted.rank, toBeInserted);
					toBeInserted = null;
				}
			}
		} while (nextOldRoot != someListNode);

		/*
		 * form a list of the remaining roots, in the process finding a root
		 * containing an item of minimum key to serve as the minimum node of the
		 * modified heap
		 */
		java.util.Enumeration<TreeNode<T>> newRoots =
			rankIndexedRoots.elements();
		
		// start with the first new root
		TreeNode<T> firstNewRoot = newRoots.nextElement();
		minimumNode = firstNewRoot;
		minimumNode.parent = null;
		
		TreeNode<T> previousNewRoot = null;
		TreeNode<T> currentNewRoot = firstNewRoot;
		
		while (newRoots.hasMoreElements()) {
			// get the next new root
			previousNewRoot = currentNewRoot;
			currentNewRoot = newRoots.nextElement();
			
			// update pointers
			previousNewRoot.rightSibling = currentNewRoot;
			currentNewRoot.leftSibling = previousNewRoot;
			currentNewRoot.parent = null;
			
			// check for new minimum node
			if (currentNewRoot.item.key < minimumNode.item.key) {
				minimumNode = currentNewRoot;
			}
		}
	
		currentNewRoot.rightSibling = firstNewRoot;
		firstNewRoot.leftSibling = currentNewRoot;
		
		
		return minimumItem;
	}