/** Move data from alert table into metadata table. */
  private void migrateAlarmsToMetadata() {
    Context context = ContextManager.getContext();

    if (!checkIfDatabaseExists(context, AlarmDatabase.NAME)) return;

    AlarmDatabase alarmsDatabase = new AlarmDatabase();
    DatabaseDao<TransitionalAlarm> dao =
        new DatabaseDao<TransitionalAlarm>(TransitionalAlarm.class, alarmsDatabase);

    TodorooCursor<TransitionalAlarm> cursor = dao.query(Query.select(TransitionalAlarm.PROPERTIES));
    try {
      if (cursor.getCount() == 0) return;

      Metadata metadata = new Metadata();
      metadata.setValue(Metadata.KEY, AlarmFields.METADATA_KEY);
      for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
        long task = cursor.get(TransitionalAlarm.TASK);
        long time = cursor.get(TransitionalAlarm.TIME);

        metadata.setValue(Metadata.TASK, task);
        metadata.setValue(AlarmFields.TIME, time);
        metadata.setValue(AlarmFields.TYPE, AlarmFields.TYPE_SINGLE);
        metadataDao.createNew(metadata);
        metadata.clearValue(Metadata.ID);
      }
    } finally {
      cursor.close();
      alarmsDatabase.close();
    }
  }
  /**
   * Perform the upgrade from Astrid 2 to Astrid 3
   *
   * @param context2
   */
  @SuppressWarnings("deprecation")
  public void upgrade2To3(final Context context, final int from) {

    // if from < 1 (we don't know what version, and database exists, leave it alone)
    if (from < 1 && checkIfDatabaseExists(context, database.getName())) return;

    // if you don't have a legacy task table, skip this step
    if (!checkIfDatabaseExists(context, tasksTable)) return;

    // else, if there's already a database table, clear it out (!!!)
    if (checkIfDatabaseExists(context, database.getName()))
      context.deleteDatabase(database.getName());
    database.openForWriting();

    // initiate a backup
    String backupFile = legacyBackup();

    try {

      // --- upgrade tasks table
      HashMap<String, Property<?>> propertyMap = new HashMap<String, Property<?>>();
      propertyMap.put("_id", Task.ID); // $NON-NLS-1$
      propertyMap.put(LegacyTaskModel.NAME, Task.TITLE);
      propertyMap.put(LegacyTaskModel.NOTES, Task.NOTES);
      // (don't update progress percentage, we don't use this anymore)
      propertyMap.put(LegacyTaskModel.IMPORTANCE, Task.IMPORTANCE);
      propertyMap.put(LegacyTaskModel.ESTIMATED_SECONDS, Task.ESTIMATED_SECONDS);
      propertyMap.put(LegacyTaskModel.ELAPSED_SECONDS, Task.ELAPSED_SECONDS);
      propertyMap.put(LegacyTaskModel.TIMER_START, Task.TIMER_START);
      propertyMap.put(LegacyTaskModel.DEFINITE_DUE_DATE, Task.DUE_DATE);
      propertyMap.put(LegacyTaskModel.HIDDEN_UNTIL, Task.HIDE_UNTIL);
      propertyMap.put(LegacyTaskModel.POSTPONE_COUNT, Task.POSTPONE_COUNT);
      propertyMap.put(LegacyTaskModel.NOTIFICATIONS, Task.REMINDER_PERIOD);
      propertyMap.put(LegacyTaskModel.NOTIFICATION_FLAGS, Task.REMINDER_FLAGS);
      propertyMap.put(LegacyTaskModel.LAST_NOTIFIED, Task.REMINDER_LAST);
      propertyMap.put(LegacyTaskModel.REPEAT, Task.RECURRENCE);
      propertyMap.put(LegacyTaskModel.CREATION_DATE, Task.CREATION_DATE);
      propertyMap.put(LegacyTaskModel.COMPLETION_DATE, Task.COMPLETION_DATE);
      propertyMap.put(LegacyTaskModel.CALENDAR_URI, Task.CALENDAR_URI);
      propertyMap.put(LegacyTaskModel.FLAGS, Task.FLAGS);
      upgradeTable(context, tasksTable, propertyMap, new Task(), taskDao);

      // --- upgrade tags tables
      migrateTagsToMetadata();

      // --- upgrade alerts
      AlarmDatabase alarmsDatabase = new AlarmDatabase();
      alarmsDatabase.openForWriting();
      propertyMap.clear();
      propertyMap.put("_id", TransitionalAlarm.ID); // $NON-NLS-1$
      propertyMap.put(LegacyAlertModel.TASK, TransitionalAlarm.TASK);
      propertyMap.put(LegacyAlertModel.DATE, TransitionalAlarm.TIME);
      upgradeTable(
          context, alertsTable, propertyMap, new TransitionalAlarm(), alarmsDatabase.getDao());
      alarmsDatabase.close();

      // --- upgrade RTM sync mappings
      migrateSyncMappingToMetadata();

      // --- clean up database
      metadataService.cleanup();

      // --- upgrade properties
      SharedPreferences prefs = Preferences.getPrefs(context);
      Editor editor = prefs.edit();
      int random = Preferences.getIntegerFromString(R.string.p_rmd_default_random_hours, -1);
      if (random != -1) {
        // convert days => hours
        editor.putString(
            context.getString(R.string.p_rmd_default_random_hours), Integer.toString(random * 24));
      }
    } catch (Exception e) {
      exceptionService.reportError("backup-error", e); // $NON-NLS-1$
      if (backupFile != null) {
        // try to restore the latest XML
        TasksXmlImporter.importTasks(context, backupFile, null);
      }
    }
  }