@Override
	public void getTokenEmissionWeights(SequenceInput input, int idxTknTrain,
			double[] weights) {
		// Clear weights array.
		Arrays.fill(weights, 0d);

		/*
		 * Index of the given sequence within the training dataset, if it is
		 * part of one.
		 */
		int idxSeqTrain = input.getTrainingIndex();

		if (!distillationOnGoing) {
			if (idxTknTrain == 0)
				kernelCacheCurrentExample = new double[input.size()][][];
			kernelCacheCurrentExample[idxTknTrain] = new double[dualEmissionVariables
					.size()][];
		}

		int _idxSeqSV = 0;
		// For each sequence.
		for (Entry<Integer, TreeMap<Integer, TreeMap<Integer, AveragedParameter>>> entrySequence : dualEmissionVariables
				.entrySet()) {

			// Current sequence index.
			int idxSeqSV = entrySequence.getKey();

			TreeMap<Integer, TreeMap<Integer, AveragedParameter>> sequence = entrySequence
					.getValue();

			int _idxTknSV = 0;
			if (!distillationOnGoing)
				kernelCacheCurrentExample[idxTknTrain][_idxSeqSV] = new double[sequence
						.size()];

			// For each token within the current sequence.
			for (Entry<Integer, TreeMap<Integer, AveragedParameter>> entryToken : sequence
					.entrySet()) {

				// Currect token index.
				int idxTknSV = entryToken.getKey();

				// Calculate the kernel function value.
				double k;
				if (distillationOnGoing) {
					if (idxSeqTrain == idxSeqSV && idxTknTrain == idxTknSV) {
						/*
						 * Do not use the kernel function value between a
						 * support vector and itself, in order to calculate the
						 * prediction when removing this support vector.
						 */
						++_idxTknSV;
						continue;
					} else {
						/*
						 * Kernel function values between two support vectors
						 * are cached.
						 */
						k = kernelCache.get(new DualEmissionKeyPair(idxSeqSV,
								idxTknSV, idxSeqTrain, idxTknTrain));
					}
				} else {
					/*
					 * Evaluate the kernel function between the training example
					 * token and the current support vector.
					 */
					k = kernel(inputs[idxSeqSV], idxTknSV, input, idxTknTrain);

					/*
					 * Store the kernel function value in the current example
					 * temporary cache.
					 */
					kernelCacheCurrentExample[idxTknTrain][_idxSeqSV][_idxTknSV] = k;
				}

				/*
				 * Sum the kernel function values weighted by the alpha
				 * counters.
				 */
				for (Entry<Integer, AveragedParameter> entryAlpha : entryToken
						.getValue().entrySet()) {
					int state = entryAlpha.getKey();
					double alpha = entryAlpha.getValue().get();
					weights[state] += alpha * k;
				}

				++_idxTknSV;
			}

			++_idxSeqSV;
		}
	}