protected void partialTag(Hmm hmm, SequenceInput input,
			SequenceOutput partiallyLabeledOutput,
			SequenceOutput predictedOutput) {
		// Example length.
		int numberOfStates = hmm.getNumberOfStates();
		int lenExample = input.size();

		// Best partial-path weights.
		double[][] delta = new double[lenExample][numberOfStates];
		// Best partial-path backward table.
		int[][] psi = new int[lenExample][numberOfStates];

		// Weights for the first token.
		int curState = partiallyLabeledOutput.getLabel(0);

		// Emission weights at each token.
		double[] emissionWeights = new double[numberOfStates];

		if (curState == SequenceDataset.NON_ANNOTATED_STATE_CODE) {
			// Non-annotated token.
			getLossAugmentedTokenEmissionWeights(hmm, input, 0, emissionWeights);
			for (int state = 0; state < numberOfStates; ++state)
				delta[0][state] = emissionWeights[state]
						+ hmm.getInitialStateParameter(state);
		} else {
			/*
			 * Do not need to calculate anything since the next token will
			 * always choose the labeled state as previous state despite the
			 * delta values (see <code>partialViterbi</code> method).
			 */
		}

		// Apply each step of the Viterbi algorithm.
		for (int tkn = 1; tkn < lenExample; ++tkn) {
			int prevState = curState;
			curState = partiallyLabeledOutput.getLabel(tkn);
			if (curState == SequenceDataset.NON_ANNOTATED_STATE_CODE) {
				// Get emission weights for each state.
				getLossAugmentedTokenEmissionWeights(hmm, input, tkn, emissionWeights);
				/*
				 * If the current token is non-annotated, we need to calculate
				 * the best previous state and corresponding weight for each
				 * possible state.
				 */
				for (int state = 0; state < numberOfStates; ++state)
					partialViterbi(hmm, prevState, delta, psi, tkn, state,
							emissionWeights[state], defaultState);
			} else {
				/*
				 * If the current token is annotated, we already know its state
				 * and therefore only need to calculate the best previous state
				 * to this annotated state.
				 */
				partialViterbi(hmm, prevState, delta, psi, tkn, curState, 0d,
						defaultState);
			}
		}

		// Find the best state for the last token.
		int lastState = partiallyLabeledOutput.getLabel(lenExample - 1);
		if (lastState == SequenceDataset.NON_ANNOTATED_STATE_CODE) {

			// The default state is always the fisrt option.
			int bestState = defaultState;
			double bestWeight = delta[lenExample - 1][defaultState];

			// Find the best last state.
			for (int state = 0; state < numberOfStates; ++state) {
				double weight = delta[lenExample - 1][state];
				if (weight > bestWeight) {
					bestWeight = weight;
					bestState = state;
				}
			}

			lastState = bestState;

		}

		// Reconstruct the best path from the best final state, annotating
		// the output sequence.
		backwardTag(predictedOutput, psi, lastState);
	}