code: private ForwardStepResult<S, O, D> forwardStep(O observation, Collection<S> prevCandidates,
              Collection<S> curCandidates, Map<S, Double> message,
              Map<S, Double> emissionLogProbabilities,
              Map<Transition<S>, Double> transitionLogProbabilities,
              Map<Transition<S>,D> transitionDescriptors) {
          final ForwardStepResult<S, O, D> result = new ForwardStepResult<>(curCandidates.size());
          assert !prevCandidates.isEmpty();
  
          for (S curState : curCandidates) {
              double maxLogProbability = Double.NEGATIVE_INFINITY;
              S maxPrevState = null;
              for (S prevState : prevCandidates) {
                  final double logProbability = message.get(prevState) + transitionLogProbability(
                          prevState, curState, transitionLogProbabilities);
                  if (logProbability > maxLogProbability) {
                      maxLogProbability = logProbability;
                      maxPrevState = prevState;
                  }
              }
              // Throws NullPointerException if curState is not stored in the map.
              result.newMessage.put(curState, maxLogProbability
                      + emissionLogProbabilities.get(curState));
  
              // Note that maxPrevState == null if there is no transition with non-zero probability.
              // In this case curState has zero probability and will not be part of the most likely
              // sequence, so we don't need an ExtendedState.
              if (maxPrevState != null) {
                  final Transition<S> transition = new Transition<>(maxPrevState, curState);
                  final ExtendedState<S, O, D> extendedState = new ExtendedState<>(curState,
                          lastExtendedStates.get(maxPrevState), observation,
                          transitionDescriptors.get(transition));
                  result.newExtendedStates.put(curState, extendedState);
              }
          }
          return result;
      }
docs: Computes the new forward message and the back pointers to the previous states.
  
  @throws NullPointerException if any emission probability is missing