@Override
  protected void init(int sessionId) {

    Cursor sessionCursor = null;
    Cursor splitMarkerSetCursor = null;
    Cursor splitMarkerCursor = null;

    try {
      sessionCursor =
          context
              .getContentResolver()
              .query(
                  TrackLoggerData.Session.CONTENT_URI,
                  null,
                  TrackLoggerData.Session._ID + "= ?",
                  new String[] {Integer.toString(sessionId)},
                  null);

      if (!sessionCursor.moveToFirst()) {
        LOG.error("No session found for session ID {}.", sessionId);
        throw new IllegalStateException("No session found for ID " + sessionId);
      }

      String startDateString =
          sessionCursor.getString(
              sessionCursor.getColumnIndex(TrackLoggerData.Session.COLUMN_NAME_START_DATE));

      sessionStartDate = TrackLoggerDataUtil.parseSqlDate(startDateString);
      int splitMarkerSetId =
          sessionCursor.getInt(
              sessionCursor.getColumnIndex(
                  TrackLoggerData.Session.COLUMN_NAME_SPLIT_MARKER_SET_ID));

      splitMarkerSetCursor =
          context
              .getContentResolver()
              .query(
                  ContentUris.withAppendedId(
                      TrackLoggerData.SplitMarkerSet.CONTENT_URI, splitMarkerSetId),
                  null,
                  null,
                  null,
                  null);

      if (!splitMarkerSetCursor.moveToFirst()) {
        LOG.error("No split marker set found for split marker set ID {}.", splitMarkerSetId);
        throw new IllegalStateException(
            "No split marker set found for split marker set ID " + splitMarkerSetId);
      }

      splitMarkerSetName =
          splitMarkerSetCursor.getString(
              splitMarkerSetCursor.getColumnIndex(TrackLoggerData.SplitMarkerSet.COLUMN_NAME_NAME));

      splitMarkerCursor =
          context
              .getContentResolver()
              .query(
                  TrackLoggerData.SplitMarker.CONTENT_URI,
                  null,
                  TrackLoggerData.SplitMarker.COLUMN_NAME_SPLIT_MARKER_SET_ID + " = ?",
                  new String[] {String.valueOf(splitMarkerSetId)},
                  null);

      splitMarkerCount = splitMarkerCursor.getCount();
    } finally {
      if (sessionCursor != null) {
        sessionCursor.close();
      }

      if (splitMarkerCursor != null) {
        splitMarkerCursor.close();
      }

      if (splitMarkerSetCursor != null) {
        splitMarkerSetCursor.close();
      }
    }
  }
  private void duplicate(int id) {
    Uri splitMarkerSetUri = createSplitMarkerSetUri(id);

    final ArrayList<ContentProviderOperation> operations =
        new ArrayList<ContentProviderOperation>();

    Cursor splitMarkerSetCursor = null;
    Cursor splitMarkerCursor = null;

    try {
      splitMarkerSetCursor = getContentResolver().query(splitMarkerSetUri, null, null, null, null);

      if (splitMarkerSetCursor.getCount() != 1) {
        LOG.error(
            "Wrong number of split marker sets found.  Expected 1 but found [{}].",
            splitMarkerSetCursor.getCount());
        onNonTerminalError();
      } else {
        splitMarkerSetCursor.moveToFirst();
        final String name =
            splitMarkerSetCursor.getString(
                splitMarkerSetCursor.getColumnIndex(
                    TrackLoggerData.SplitMarkerSet.COLUMN_NAME_NAME));

        String newName =
            TrackLoggerDataUtil.createUniqueSplitMarkerSetName(
                getContentResolver(), name + " Copy");

        if (newName == null) {
          onNonTerminalError();
        } else if (!TrackLoggerDataUtil.isValidSplitMarkerSetName(newName)) {
          LOG.error("[{}] is an invalid split marker set name.", newName);
          onNonTerminalError();
        } else {
          operations.add(
              ContentProviderOperation.newInsert(TrackLoggerData.SplitMarkerSet.CONTENT_URI)
                  .withValue(TrackLoggerData.SplitMarkerSet.COLUMN_NAME_NAME, newName)
                  .build());

          splitMarkerCursor =
              getContentResolver()
                  .query(
                      TrackLoggerData.SplitMarker.CONTENT_URI,
                      null,
                      TrackLoggerData.SplitMarker.COLUMN_NAME_SPLIT_MARKER_SET_ID + " = ?",
                      new String[] {String.valueOf(id)},
                      null);

          splitMarkerCursor.moveToFirst();

          final int nameIndex =
              splitMarkerCursor.getColumnIndex(TrackLoggerData.SplitMarker.COLUMN_NAME_NAME);
          final int latIndex =
              splitMarkerCursor.getColumnIndex(TrackLoggerData.SplitMarker.COLUMN_NAME_LATITUDE);
          final int lonIndex =
              splitMarkerCursor.getColumnIndex(TrackLoggerData.SplitMarker.COLUMN_NAME_LONGITUDE);

          while (!splitMarkerCursor.isAfterLast()) {
            operations.add(
                ContentProviderOperation.newInsert(TrackLoggerData.SplitMarker.CONTENT_URI)
                    // Back reference to the set insertion
                    .withValueBackReference(
                        TrackLoggerData.SplitMarker.COLUMN_NAME_SPLIT_MARKER_SET_ID, 0)
                    // Index can be size - 1 because the set is always the first element in the list
                    .withValue(
                        TrackLoggerData.SplitMarker.COLUMN_NAME_ORDER_INDEX, operations.size() - 1)
                    .withValue(
                        TrackLoggerData.SplitMarker.COLUMN_NAME_NAME,
                        splitMarkerCursor.getString(nameIndex))
                    .withValue(
                        TrackLoggerData.SplitMarker.COLUMN_NAME_LATITUDE,
                        splitMarkerCursor.getDouble(latIndex))
                    .withValue(
                        TrackLoggerData.SplitMarker.COLUMN_NAME_LONGITUDE,
                        splitMarkerCursor.getDouble(lonIndex))
                    .build());

            splitMarkerCursor.move(1);
          }

          getContentResolver().applyBatch(TrackLoggerData.AUTHORITY, operations);

          Toast.makeText(
                  this,
                  getString(R.string.split_marker_set_list_duplicated_notification, name, newName),
                  Toast.LENGTH_LONG)
              .show();
        }
      }
    } catch (Exception e) {
      LOG.error(
          "Error applying batch operations for split marker set clone.  Operations included ["
              + operations
              + "].",
          e);
      onNonTerminalError();
    } finally {
      if (splitMarkerSetCursor != null) {
        splitMarkerSetCursor.close();
      }

      if (splitMarkerCursor != null) {
        splitMarkerCursor.close();
      }
    }
  }