class VelocityController {

  public void advanceTime(int dt) {
    if (dt < 1) {
      throw new IllegalArgumentException("dt is less than 1");
    }
    final int oldPosition = currentPosition;
    final int oldVelocity = currentVelocity;
    final Iterator<WayEntry> wayEntryIter = wayEntries.iterator();
    final WayEntry curWayEntry
        = wayEntryIter.hasNext() ? wayEntryIter.next() : null;
    final int targetVelocity;
    final long accelerationDistance;
    if (curWayEntry == null || paused) {
      targetVelocity = 0;
      accelerationDistance = 1;
      currentAcceleration = 0;
      currentVelocity = 0;
    }
    else {
      final int maxVelocity;
      final Vehicle.Orientation orientation = curWayEntry.vehicleOrientation;
      switch (orientation) {
        case FORWARD:
          maxVelocity = maxFwdVelocity;
          break;
        case BACKWARD:
          maxVelocity = maxRevVelocity;
          break;
        default:
          LOG.warn("Unhandled orientation: {}, assuming forward.", orientation);
          maxVelocity = maxFwdVelocity;
      }
      targetVelocity = Math.min(curWayEntry.targetVelocity, maxVelocity);
      // Accelerate as quickly as possible.
      accelerationDistance = 10;
      // Recompute the acceleration to reach/keep the desired velocity.
      currentAcceleration
          = (currentVelocity == targetVelocity) ? 0
              : suitableAcceleration(targetVelocity, accelerationDistance);
      // Recompute current velocity.
      currentVelocity = oldVelocity + currentAcceleration * dt / 1000;
      // Recompute current position.
      currentPosition = oldPosition + oldVelocity * dt / 1000
          + currentAcceleration * dt * dt / 1000000 / 2;
      // Check if we have left the way entry and entered the next.
      if (currentPosition >= curWayEntry.length) {
        currentPosition -= curWayEntry.length;
        wayEntries.poll();
      }
    }
    // The given time has now passed.
    currentTime += dt;
    // Let the listeners know about the new velocity value.
    for (VelocityListener curListener : velocityListeners) {
      curListener.addVelocityValue(currentVelocity);
    }
  }

  public  VelocityController(int maxDecel,
                            int maxAccel,
                            int maxRevVelo,
                            int maxFwdVelo);

}