private VehicleActivity createActivity(VehicleStatusBean vehicleStatus, boolean onwardCalls) {

    if (vehicleStatus.getPhase().equals("DEADHEAD_AFTER")
        || vehicleStatus.getPhase().equals("DEADHEAD_BEFORE")
        || vehicleStatus.getPhase().equals("DEADHEAD_DURING")) {
      return null;
    }
    VehicleActivity activity = new VehicleActivity();

    Calendar time = Calendar.getInstance();
    time.setTime(new Date(vehicleStatus.getLastUpdateTime()));

    activity.RecordedAtTime = time;
    TripBean tripBean = vehicleStatus.getTrip();
    if (tripBean != null) {
      TripDetailsQueryBean query = new TripDetailsQueryBean();
      query.setTime(time.getTimeInMillis());
      query.setTripId(tripBean.getId());
      query.setVehicleId(vehicleStatus.getVehicleId());
      query.getInclusion().setIncludeTripStatus(true);
      TripStatusBean tripStatus = vehicleStatus.getTripStatus();
      query.setServiceDate(tripStatus.getServiceDate());
      TripDetailsBean tripDetails = _transitDataService.getSingleTripDetails(query);
      activity.MonitoredVehicleJourney =
          SiriUtils.getMonitoredVehicleJourney(
              tripDetails, new Date(tripStatus.getServiceDate()), vehicleStatus.getVehicleId());

      if (onwardCalls) {

        List<TripStopTimeBean> stopTimes = tripDetails.getSchedule().getStopTimes();

        long serviceDateMillis = tripStatus.getServiceDate();
        double distance = tripStatus.getDistanceAlongTrip();
        if (Double.isNaN(distance)) {
          distance = tripStatus.getScheduledDistanceAlongTrip();
        }
        activity.MonitoredVehicleJourney.OnwardCalls =
            SiriUtils.getOnwardCalls(
                stopTimes, serviceDateMillis, distance, tripStatus.getNextStop());
      }
    } else {
      activity.MonitoredVehicleJourney = new MonitoredVehicleJourney();
    }
    activity.MonitoredVehicleJourney.Monitored = true;

    activity.MonitoredVehicleJourney.VehicleRef = vehicleStatus.getVehicleId();

    activity.MonitoredVehicleJourney.ProgressRate =
        SiriUtils.getProgressRateForStatus(vehicleStatus.getStatus());

    VehicleLocation location = new VehicleLocation();
    location.Latitude = vehicleStatus.getLocation().getLat();
    location.Longitude = vehicleStatus.getLocation().getLon();

    activity.MonitoredVehicleJourney.VehicleLocation = location;
    return activity;
  }
  public TripDetailsV2Bean getTripDetails(TripDetailsBean tripDetails) {

    TripDetailsV2Bean bean = new TripDetailsV2Bean();

    bean.setTripId(tripDetails.getTripId());
    bean.setServiceDate(tripDetails.getServiceDate());

    if (tripDetails.getFrequency() != null)
      bean.setFrequency(getFrequency(tripDetails.getFrequency()));

    TripBean trip = tripDetails.getTrip();
    if (trip != null) addToReferences(trip);

    TripStopTimesBean stopTimes = tripDetails.getSchedule();
    if (stopTimes != null) bean.setSchedule(getTripStopTimes(stopTimes));

    List<ServiceAlertBean> situations = tripDetails.getSituations();
    if (!CollectionsLibrary.isEmpty(situations)) {
      List<String> situationIds = new ArrayList<String>();
      for (ServiceAlertBean situation : situations) {
        addToReferences(situation);
        situationIds.add(situation.getId());
      }
      bean.setSituationIds(situationIds);
    }

    return bean;
  }
  /** Create a VehicleActivity for a given vehicle's trip. */
  private VehicleActivity createActivity(TripDetailsBean trip, boolean onwardCalls) {
    VehicleActivity activity = new VehicleActivity();
    TripStatusBean status = trip.getStatus();
    if (status.getPhase().equals("DEADHEAD_AFTER")
        || status.getPhase().equals("DEADHEAD_BEFORE")
        || status.getPhase().equals("DEADHEAD_DURING")) {
      return null;
    }

    Calendar time = Calendar.getInstance();
    time.setTime(new Date(status.getLastUpdateTime()));

    activity.RecordedAtTime = time;

    activity.MonitoredVehicleJourney =
        SiriUtils.getMonitoredVehicleJourney(
            trip, new Date(status.getServiceDate()), status.getVehicleId());
    activity.MonitoredVehicleJourney.Monitored = true;
    activity.MonitoredVehicleJourney.VehicleRef = status.getVehicleId();

    activity.MonitoredVehicleJourney.ProgressRate = status.getStatus();

    VehicleLocation location = new VehicleLocation();
    location.Latitude = status.getLocation().getLat();
    location.Longitude = status.getLocation().getLon();

    activity.MonitoredVehicleJourney.VehicleLocation = location;

    if (onwardCalls) {
      List<TripStopTimeBean> stopTimes = trip.getSchedule().getStopTimes();

      long serviceDateMillis = status.getServiceDate();
      double distance = status.getDistanceAlongTrip();
      if (Double.isNaN(distance)) {
        distance = status.getScheduledDistanceAlongTrip();
      }
      activity.MonitoredVehicleJourney.OnwardCalls =
          SiriUtils.getOnwardCalls(stopTimes, serviceDateMillis, distance, status.getNextStop());
    }

    return activity;
  }
  /**
   * This is the default action, corresponding to a SIRI VehicleMonitoringRequest
   *
   * @return
   * @throws IOException
   */
  public DefaultHttpHeaders index() throws IOException {

    String agencyId = _request.getParameter("OperatorRef");

    if (_time == null) _time = new Date();

    String detailLevel = _request.getParameter("VehicleMonitoringDetailLevel");
    boolean onwardCalls = false;
    if (detailLevel != null) {
      onwardCalls = detailLevel.equals("calls");
    }

    String vehicleId = _request.getParameter("VehicleRef");

    // single trip, by vehicle
    if (vehicleId != null) {
      String vehicleIdWithAgency = agencyId + "_" + vehicleId;
      VehicleStatusBean vehicle =
          _transitDataService.getVehicleForAgency(vehicleIdWithAgency, _time.getTime());
      ArrayList<VehicleActivity> activities = new ArrayList<VehicleActivity>();
      if (vehicle != null) {
        if (!(vehicle.getPhase().equals("DEADHEAD_AFTER")
            || vehicle.getPhase().equals("DEADHEAD_BEFORE")
            || vehicle.getPhase().equals("DEADHEAD_DURING"))) {
          activities.add(createActivity(vehicle, onwardCalls));
        }
      }
      _response = generateSiriResponse(_time, activities);
      return new DefaultHttpHeaders();
    }

    String directionId = _request.getParameter("DirectionRef");

    // by trip (may be more than one trip)
    String tripId = _request.getParameter("VehicleJourneyRef");
    if (tripId != null) {
      TripBean tripBean = _transitDataService.getTrip(agencyId + "_" + tripId);
      if (tripBean == null) {
        throw new IllegalArgumentException("No such trip: " + tripId);
      }
      TripDetailsQueryBean query = new TripDetailsQueryBean();
      query.setTripId(tripId);
      ListBean<TripDetailsBean> trips = _transitDataService.getTripDetails(query);
      ArrayList<VehicleActivity> activities = new ArrayList<VehicleActivity>();
      for (TripDetailsBean trip : trips.getList()) {
        if (directionId != null && !trip.getTrip().getDirectionId().equals(directionId)) {
          continue;
        }
        if (trip.getStatus().isPredicted() == false) {
          /* only show trips with realtime info */
          continue;
        }
        VehicleActivity activity = createActivity(trip, onwardCalls);
        if (activity != null) {
          activities.add(activity);
        }
      }
      _response = generateSiriResponse(_time, activities);
      return new DefaultHttpHeaders();
    }

    String routeId = _request.getParameter("LineRef");
    // multiple trips by route
    if (routeId != null) {
      TripsForRouteQueryBean query = new TripsForRouteQueryBean();
      query.setRouteId(agencyId + "_" + routeId);
      query.setTime(_time.getTime());
      ListBean<TripDetailsBean> trips = _transitDataService.getTripsForRoute(query);
      ArrayList<VehicleActivity> activities = new ArrayList<VehicleActivity>();
      for (TripDetailsBean trip : trips.getList()) {
        if (directionId != null && !trip.getTrip().getDirectionId().equals(directionId)) {
          continue;
        }
        if (trip.getStatus().isPredicted() == false) {
          /* only show trips with realtime info */
          continue;
        }
        VehicleActivity activity = createActivity(trip, onwardCalls);
        if (activity != null) {
          activities.add(activity);
        }
      }
      _response = generateSiriResponse(_time, activities);
      return new DefaultHttpHeaders();
    }

    /* All vehicles */
    ListBean<VehicleStatusBean> vehicles =
        _transitDataService.getAllVehiclesForAgency(agencyId, _time.getTime());
    ArrayList<VehicleActivity> activities = new ArrayList<VehicleActivity>();
    for (VehicleStatusBean v : vehicles.getList()) {
      VehicleActivity activity = createActivity(v, onwardCalls);
      if (activity != null) {
        activities.add(activity);
      }
    }
    _response = generateSiriResponse(_time, activities);
    return new DefaultHttpHeaders();
  }