private void extend(ITNode currNode) throws IOException {
		// loop over the brothers of that node
		int i = 0;
		while (i < currNode.getParent().getChildNodes().size()) {
			// get the brother i
			ITNode brother = currNode.getParent().getChildNodes().get(i);
			// if the brother is not the current node
			if (brother != currNode) {

				// Property 1
				// If the tidset of the current node is the same as the one
				// of its brother
				if (currNode.getTidset().equals(brother.getTidset())) {
					// we can replace the current node itemset in the current node
					// and the subtree by the union of the brother itemset
					// and the current node itemset
					replaceInSubtree(currNode, brother.getItemset());
					// then we delete the brother
					delete(brother);
				}
				// Property 2
				// If the brother tidset contains the tidset of the current node
				else if (brother.getTidset().containsAll(currNode.getTidset())) {
					// Same as previous if condition except that we
					// do not delete the brother.
					replaceInSubtree(currNode, brother.getItemset());
					i++;
				}
				// Property 3
				// If the tidset of the current node contains the tidset of the
				// brother
				else if (currNode.getTidset().containsAll(brother.getTidset())) {
					// Generate a candidate by performing
					// the union of the itemsets of the current node and its brother
					ITNode candidate = getCandidate(currNode, brother);
					// delete the brother
					delete(brother);
					// if a candidate was obtained
					if (candidate != null) {
						// add the candidate as child node of the current node
						currNode.getChildNodes().add(candidate);
						candidate.setParent(currNode);
					}
				}
				// Property 4
				// if the tidset of the current node is not equal to the tidset
				// of its brother
				else if (!currNode.getTidset().equals(brother.getTidset())) {
					// Generate a candidate by performing
					// the union of the itemsets of the current node and its brother
					ITNode candidate = getCandidate(currNode, brother);
					// if a candidate was obtained
					if (candidate != null) {
						// add the candidate as child node of the current node
						currNode.getChildNodes().add(candidate);
						candidate.setParent(currNode);
					}
					i++; // go to next node
				} else {
					i++; // go to next node
				}
			} else {
				i++;  // go to next node
			} 
		}

		// for optimization, sort the child of the root according to the support
		sortChildren(currNode);

		// while the current node has child node
		while (currNode.getChildNodes().size() > 0) {
			// get the first child
			ITNode child = currNode.getChildNodes().get(0);
			extend(child);  // extend it (charm is a depth-first search algorithm)
			save(child); // save the node
			delete(child); // then delte it
		}
	}