public void generateFeatures() {
		// List of feature codes used for every edge.
		LinkedList<Integer> ftrCodes = new LinkedList<Integer>();
		// List of feature values used for every edge.
		LinkedList<Double> ftrValues = new LinkedList<Double>();
		// Iterate over all examples.
		int numExs = inputExamples.length;
		for (int idxEx = 0; idxEx < numExs; ++idxEx) {
			// Current input structure.
			BisectionInput input = inputExamples[idxEx];

			// Allocate derived features matrix.
			input.allocFeatureArray();

			// Number of papers within the current input.
			int size = input.size();

			for (int paper1 = 0; paper1 < size; ++paper1) {
				for (int paper2 = 0; paper2 < size; ++paper2) {
					// Values of basic categorical features in the current edge.
					int[] basicCategoricalFeatures = input
							.getBasicCategoricalFeatures(paper1, paper2);
					if (basicCategoricalFeatures == null)
						// Inexistent edge. Skip it.
						continue;
					// Values of basic numerical features in the current edge.
					double[] basicNumericalFeatures = input
							.getBasicNumericalFeatures(paper1, paper2);

					// Clear auxiliary lists.
					ftrCodes.clear();
					ftrValues.clear();

					/*
					 * Instantiate edge features and add them to active features
					 * list.
					 */
					for (int idxTpl = 0; idxTpl < templates.length; ++idxTpl) {
						// Current template.
						BisectionTemplate tpl = templates[idxTpl];
						// Get temporary feature instance.
						Feature ftr = tpl.getInstance(input, paper1, paper2);
						// Lookup the feature in the encoding.
						int code = derivedEncoding.getCodeByValue(ftr);
						/*
						 * Instantiate a new feature, if it is not present in
						 * the encoding.
						 */
						if (code == FeatureEncoding.UNSEEN_VALUE_CODE) {
							try {
								code = derivedEncoding.put(ftr.clone());
							} catch (CloneNotSupportedException e) {
								LOG.error("Some feature is not cloneable", e);
							}
						}
						// Add feature code to the features list.
						ftrCodes.add(code);
						/*
						 * Compute derived feature value for this edge. This
						 * value is the multiplication of each numerical feature
						 * value in the edge.
						 */
						double val = 1d;
						for (int idxNumFtr : tpl.getNumericalFeatures())
							val *= basicNumericalFeatures[idxNumFtr];
						ftrValues.add(val);
					}

					// Set derived features codes and values for this edge.
					input.setFeatures(paper1, paper2, ftrCodes, ftrValues);
				}
			}

			// Progess report.
			if ((idxEx + 1) % 100 == 0) {
				System.out.print('.');
				System.out.flush();
			}
		}

		System.out.println();
		System.out.flush();
	}