@Override
 public void deleteWaypoint(long waypointId, DescriptionGenerator descriptionGenerator) {
   final Waypoint waypoint = getWaypoint(waypointId);
   if (waypoint != null && waypoint.getType() == Waypoint.TYPE_STATISTICS) {
     final Waypoint nextWaypoint = getNextStatisticsWaypointAfter(waypoint);
     if (nextWaypoint == null) {
       Log.d(TAG, "Unable to find the next statistics marker after deleting one.");
     } else {
       nextWaypoint.getTripStatistics().merge(waypoint.getTripStatistics());
       nextWaypoint.setDescription(
           descriptionGenerator.generateWaypointDescription(nextWaypoint.getTripStatistics()));
       if (!updateWaypoint(nextWaypoint)) {
         Log.e(TAG, "Unable to update the next statistics marker after deleting one.");
       }
     }
   }
   contentResolver.delete(
       WaypointsColumns.CONTENT_URI,
       WaypointsColumns._ID + "=?",
       new String[] {Long.toString(waypointId)});
 }
  @Override
  public Waypoint createWaypoint(Cursor cursor) {
    int idIndex = cursor.getColumnIndexOrThrow(WaypointsColumns._ID);
    int nameIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.NAME);
    int descriptionIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.DESCRIPTION);
    int categoryIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.CATEGORY);
    int iconIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.ICON);
    int trackIdIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.TRACKID);
    int typeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.TYPE);
    int lengthIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.LENGTH);
    int durationIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.DURATION);
    int startTimeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.STARTTIME);
    int startIdIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.STARTID);
    int stopIdIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.STOPID);
    int longitudeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.LONGITUDE);
    int latitudeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.LATITUDE);
    int timeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.TIME);
    int altitudeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.ALTITUDE);
    int accuracyIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.ACCURACY);
    int speedIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.SPEED);
    int bearingIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.BEARING);
    int totalDistanceIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.TOTALDISTANCE);
    int totalTimeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.TOTALTIME);
    int movingTimeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.MOVINGTIME);
    int maxSpeedIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.MAXSPEED);
    int minElevationIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.MINELEVATION);
    int maxElevationIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.MAXELEVATION);
    int elevationGainIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.ELEVATIONGAIN);
    int minGradeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.MINGRADE);
    int maxGradeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.MAXGRADE);

    Waypoint waypoint = new Waypoint();

    if (!cursor.isNull(idIndex)) {
      waypoint.setId(cursor.getLong(idIndex));
    }
    if (!cursor.isNull(nameIndex)) {
      waypoint.setName(cursor.getString(nameIndex));
    }
    if (!cursor.isNull(descriptionIndex)) {
      waypoint.setDescription(cursor.getString(descriptionIndex));
    }
    if (!cursor.isNull(categoryIndex)) {
      waypoint.setCategory(cursor.getString(categoryIndex));
    }
    if (!cursor.isNull(iconIndex)) {
      waypoint.setIcon(cursor.getString(iconIndex));
    }
    if (!cursor.isNull(trackIdIndex)) {
      waypoint.setTrackId(cursor.getLong(trackIdIndex));
    }
    if (!cursor.isNull(typeIndex)) {
      waypoint.setType(cursor.getInt(typeIndex));
    }
    if (!cursor.isNull(lengthIndex)) {
      waypoint.setLength(cursor.getFloat(lengthIndex));
    }
    if (!cursor.isNull(durationIndex)) {
      waypoint.setDuration(cursor.getLong(durationIndex));
    }
    if (!cursor.isNull(startIdIndex)) {
      waypoint.setStartId(cursor.getLong(startIdIndex));
    }
    if (!cursor.isNull(stopIdIndex)) {
      waypoint.setStopId(cursor.getLong(stopIdIndex));
    }

    Location location = new Location("");
    if (!cursor.isNull(longitudeIndex) && !cursor.isNull(latitudeIndex)) {
      location.setLongitude(((double) cursor.getInt(longitudeIndex)) / 1E6);
      location.setLatitude(((double) cursor.getInt(latitudeIndex)) / 1E6);
    }
    if (!cursor.isNull(timeIndex)) {
      location.setTime(cursor.getLong(timeIndex));
    }
    if (!cursor.isNull(altitudeIndex)) {
      location.setAltitude(cursor.getFloat(altitudeIndex));
    }
    if (!cursor.isNull(accuracyIndex)) {
      location.setAccuracy(cursor.getFloat(accuracyIndex));
    }
    if (!cursor.isNull(speedIndex)) {
      location.setSpeed(cursor.getFloat(speedIndex));
    }
    if (!cursor.isNull(bearingIndex)) {
      location.setBearing(cursor.getFloat(bearingIndex));
    }
    waypoint.setLocation(location);

    TripStatistics tripStatistics = new TripStatistics();
    boolean hasTripStatistics = false;
    if (!cursor.isNull(startTimeIndex)) {
      tripStatistics.setStartTime(cursor.getLong(startTimeIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(totalDistanceIndex)) {
      tripStatistics.setTotalDistance(cursor.getFloat(totalDistanceIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(totalTimeIndex)) {
      tripStatistics.setTotalTime(cursor.getLong(totalTimeIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(movingTimeIndex)) {
      tripStatistics.setMovingTime(cursor.getLong(movingTimeIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(maxSpeedIndex)) {
      tripStatistics.setMaxSpeed(cursor.getFloat(maxSpeedIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(minElevationIndex)) {
      tripStatistics.setMinElevation(cursor.getFloat(minElevationIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(maxElevationIndex)) {
      tripStatistics.setMaxElevation(cursor.getFloat(maxElevationIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(elevationGainIndex)) {
      tripStatistics.setTotalElevationGain(cursor.getFloat(elevationGainIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(minGradeIndex)) {
      tripStatistics.setMinGrade(cursor.getFloat(minGradeIndex));
      hasTripStatistics = true;
    }
    if (!cursor.isNull(maxGradeIndex)) {
      tripStatistics.setMaxGrade(cursor.getFloat(maxGradeIndex));
      hasTripStatistics = true;
    }

    if (hasTripStatistics) {
      waypoint.setTripStatistics(tripStatistics);
    }
    return waypoint;
  }