public Direction generateTransitSubdirection(Leg leg, boolean isOnDirection) {
    Direction direction = new Direction();
    direction.setRealTimeInfo(leg.realTime);

    // Set icon
    String mode =
        getLocalizedMode(TraverseMode.valueOf(leg.mode), applicationContext.getResources());
    int modeIcon;
    String route;
    String agencyName = leg.agencyName;
    Place from = leg.from;
    Place to = leg.to;
    Calendar newTime = Calendar.getInstance();
    Calendar oldTime = Calendar.getInstance();

    String shortName;
    // As a work-around for #662, we always use routeShortName and not tripShortName
    shortName = leg.routeShortName;

    route = ConversionUtils.getRouteLongNameSafe(leg.routeLongName, shortName, true);

    direction.setTransit(true);

    String action, placeAndHeadsign, extra = "";

    if (isOnDirection) {
      action = applicationContext.getResources().getString(R.string.step_by_step_transit_get_on);
      placeAndHeadsign = from.name;
      TraverseModeSet modeSet = new TraverseModeSet(leg.mode);
      modeIcon = getModeIcon(modeSet);
      newTime.setTime(new Date(Long.parseLong(leg.startTime)));
      oldTime.setTime(new Date(newTime.getTimeInMillis()));
      oldTime.add(Calendar.SECOND, -leg.departureDelay);

      // Only onDirection has subdirection (list of stops in between)
      ArrayList<Place> stopsInBetween = new ArrayList<Place>();
      if ((leg.getIntermediateStops() != null) && !leg.getIntermediateStops().isEmpty()) {
        stopsInBetween.addAll(leg.getIntermediateStops());
      } else if ((leg.stop != null) && !leg.stop.isEmpty()) {
        stopsInBetween.addAll(leg.stop);
      }
      // sub-direction
      ArrayList<Direction> subDirections = new ArrayList<Direction>();
      for (int i = 0; i < stopsInBetween.size(); i++) {
        Direction subDirection = new Direction();

        Place stop = stopsInBetween.get(i);
        String extraStopInformation = stop.stopCode;
        String subDirectionText = Integer.toString(i + 1) + ". " + stop.name;
        if (!TextUtils.isEmpty(extraStopInformation)) {
          subDirectionText += " (" + extraStopInformation + ")";
        }
        subDirection.setDirectionText(subDirectionText);
        subDirection.setIcon(DirectionsGenerator.getStopIcon(modeSet));

        subDirections.add(subDirection);
      }
      direction.setSubDirections(subDirections);

      if (stopsInBetween.size() > 0) {
        String connector =
            applicationContext
                .getResources()
                .getString(R.string.step_by_step_transit_stops_in_between);
        if (stopsInBetween.size() == 1) {
          connector =
              applicationContext
                  .getResources()
                  .getString(R.string.step_by_step_transit_stops_in_between_singular);
        }
        extra = stopsInBetween.size() + " " + connector;
      }

      if (!TextUtils.isEmpty(leg.headsign)) {
        placeAndHeadsign +=
            " "
                + applicationContext
                    .getResources()
                    .getString(R.string.step_by_step_transit_connector_headsign)
                + " "
                + leg.headsign;
      }
    } else {
      action = applicationContext.getResources().getString(R.string.step_by_step_transit_get_off);
      placeAndHeadsign = to.name;
      modeIcon = -1;
      newTime.setTime(new Date(Long.parseLong(leg.endTime)));
      oldTime.setTime(new Date(newTime.getTimeInMillis()));
      oldTime.add(Calendar.SECOND, -leg.arrivalDelay);
    }

    direction.setIcon(modeIcon);
    direction.setPlaceAndHeadsign(
        applicationContext
                .getResources()
                .getString(R.string.step_by_step_transit_connector_stop_name)
            + " "
            + placeAndHeadsign);
    direction.setService(action + " " + mode + " " + route);
    direction.setAgency(agencyName);
    direction.setExtra(extra);

    SpannableString oldTimeString;

    if (leg.realTime) {
      CharSequence newTimeString;
      newTimeString =
          ConversionUtils.getTimeUpdated(
              applicationContext,
              leg.agencyTimeZoneOffset,
              oldTime.getTimeInMillis(),
              newTime.getTimeInMillis());
      direction.setNewTime(newTimeString);
    }

    oldTimeString =
        new SpannableString(
            ConversionUtils.getTimeWithContext(
                applicationContext, leg.agencyTimeZoneOffset, oldTime.getTimeInMillis(), true));
    direction.setOldTime(oldTimeString);

    return direction;
  }