gt:                     repoId = cursor.getInt(i);
context: package org.fdroid.fdroid.data;
  
  import android.annotation.TargetApi;
  import android.content.ContentValues;
  import android.content.Context;
  import android.content.pm.PackageInfo;
  import android.database.Cursor;
  import android.os.Build;
  import android.os.Environment;
  import android.os.Parcel;
  import android.os.Parcelable;
  import android.support.annotation.NonNull;
  import android.text.TextUtils;
  import android.webkit.MimeTypeMap;
  import com.fasterxml.jackson.annotation.JacksonInject;
  import com.fasterxml.jackson.annotation.JsonIgnore;
  import com.fasterxml.jackson.annotation.JsonProperty;
  import org.fdroid.fdroid.RepoXMLHandler;
  import org.fdroid.fdroid.Utils;
  import org.fdroid.fdroid.data.Schema.ApkTable.Cols;
  
  import java.io.File;
  import java.util.Date;
  import java.util.HashSet;
  
  /**
   * Represents a single package of an application. This represents one particular
   * package of a given application, for info about the app in general, see
   * {@link App}.
   * <p>
   * <b>Do not rename these instance variables without careful consideration!</b>
   * They are mapped to JSON field names, the {@code fdroidserver} internal variable
   * names, and the {@code fdroiddata} YAML field names.  Only the instance variables
   * decorated with {@code @JsonIgnore} are not directly mapped.
   * <p>
   * <b>NOTE:</b>If an instance variable is only meant for internal state, and not for
   * representing data coming from the server, then it must also be decorated with
   * {@code @JsonIgnore} to prevent abuse!  The tests for
   * {@link org.fdroid.fdroid.IndexV1Updater} will also have to be updated.
   *
   * @see <a href="https://gitlab.com/fdroid/fdroiddata">fdroiddata</a>
   * @see <a href="https://gitlab.com/fdroid/fdroidserver">fdroidserver</a>
   */
  public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
  
      // Using only byte-range keeps it only 8-bits in the SQLite database
      @JsonIgnore
      public static final int SDK_VERSION_MAX_VALUE = Byte.MAX_VALUE;
      @JsonIgnore
      public static final int SDK_VERSION_MIN_VALUE = 0;
  
      // these are never set by the Apk/package index metadata
      @JsonIgnore
      String repoAddress;
      @JsonIgnore
      int repoVersion;
      @JsonIgnore
      public SanitizedFile installedFile; // the .apk file on this device's filesystem
      @JsonIgnore
      public boolean compatible; // True if compatible with the device.
  
      @JacksonInject("repoId")
      public long repoId; // the database ID of the repo it comes from
  
      // these come directly from the index metadata
      public String packageName;
      public String versionName;
      public int versionCode;
      public int size; // Size in bytes - 0 means we don't know!
      public String hash; // checksum of the APK, in lowercase hex
      public String hashType;
      public int minSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown
      public int targetSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown
      public int maxSdkVersion = SDK_VERSION_MAX_VALUE; // "infinity" if not set
      public String obbMainFile;
      public String obbMainFileSha256;
      public String obbPatchFile;
      public String obbPatchFileSha256;
      public Date added;
      /**
       * The array of the names of the permissions that this APK requests. This is the
       * same data as {@link android.content.pm.PackageInfo#requestedPermissions}. Note this
       * does not mean that all these permissions have been granted, only requested.  For
       * example, a regular app can request a system permission, but it won't be granted it.
       */
      public String[] requestedPermissions;
      public String[] features; // null if empty or unknown
  
      public String[] nativecode; // null if empty or unknown
  
      /**
       * ID (md5 sum of public key) of signature. Might be null, in the
       * transition to this field existing.
       */
      public String sig;
  
      public String apkName; // F-Droid style APK name
  
      /**
       * If not null, this is the name of the source tarball for the
       * application. Null indicates that it's a developer's binary
       * build - otherwise it's built from source.
       */
      public String srcname;
  
      public String[] incompatibleReasons;
  
      public String[] antiFeatures;
  
      /**
       * The numeric primary key of the Metadata table, which is used to join apks.
       */
      public long appId;
  
      public Apk() {
      }
  
      /**
       * If you need an {@link Apk} but it is no longer in the database any more (e.g. because the
       * version you have installed is no longer in the repository metadata) then you can instantiate
       * an {@link Apk} via an {@link InstalledApp} instance.
       * <p>
       * Note: Many of the fields on this instance will not be known in this circumstance. Currently
       * the only things that are known are:
       * <p>
       * <ul>
       * <li>{@link Apk#packageName}
       * <li>{@link Apk#versionName}
       * <li>{@link Apk#versionCode}
       * <li>{@link Apk#hash}
       * <li>{@link Apk#hashType}
       * </ul>
       * <p>
       * This could instead be implemented by accepting a {@link PackageInfo} and it would get much
       * the same information, but it wouldn't have the hash of the package. Seeing as we've already
       * done the hard work to calculate that hash and stored it in the database, we may as well use
       * that.
       */
      public Apk(@NonNull InstalledApp app) {
          packageName = app.getPackageName();
          versionName = app.getVersionName();
          versionCode = app.getVersionCode();
          hash = app.getHash(); // checksum of the APK, in lowercase hex
          hashType = app.getHashType();
  
          // zero for "we don't know". If we require this in the future, then we could look up the
          // file on disk if required.
          size = 0;
  
          // Same as size. We could look this up if required but not needed at time of writing.
          installedFile = null;
  
          // If we are being created from an InstalledApp, it is because we couldn't load it from the
          // apk table in the database, indicating it is not available in any of our repos.
          repoId = 0;
      }
  
      public Apk(Cursor cursor) {
  
          checkCursorPosition(cursor);
  
          for (int i = 0; i < cursor.getColumnCount(); i++) {
              switch (cursor.getColumnName(i)) {
                  case Cols.APP_ID:
                      appId = cursor.getLong(i);
                      break;
                  case Cols.HASH:
                      hash = cursor.getString(i);
                      break;
                  case Cols.HASH_TYPE:
                      hashType = cursor.getString(i);
                      break;
                  case Cols.ADDED_DATE:
                      added = Utils.parseDate(cursor.getString(i), null);
                      break;
                  case Cols.FEATURES:
                      features = Utils.parseCommaSeparatedString(cursor.getString(i));
                      break;
                  case Cols.Package.PACKAGE_NAME:
                      packageName = cursor.getString(i);
                      break;
                  case Cols.IS_COMPATIBLE:
                      compatible = cursor.getInt(i) == 1;
                      break;
                  case Cols.MIN_SDK_VERSION:
                      minSdkVersion = cursor.getInt(i);
                      break;
                  case Cols.TARGET_SDK_VERSION:
                      targetSdkVersion = cursor.getInt(i);
                      break;
                  case Cols.MAX_SDK_VERSION:
                      maxSdkVersion = cursor.getInt(i);
                      break;
                  case Cols.OBB_MAIN_FILE:
                      obbMainFile = cursor.getString(i);
                      break;
                  case Cols.OBB_MAIN_FILE_SHA256:
                      obbMainFileSha256 = cursor.getString(i);
                      break;
                  case Cols.OBB_PATCH_FILE:
                      obbPatchFile = cursor.getString(i);
                      break;
                  case Cols.OBB_PATCH_FILE_SHA256:
                      obbPatchFileSha256 = cursor.getString(i);
                      break;
                  case Cols.NAME:
                      apkName = cursor.getString(i);
                      break;
                  case Cols.REQUESTED_PERMISSIONS:
                      requestedPermissions = convertToRequestedPermissions(cursor.getString(i));
                      break;
                  case Cols.NATIVE_CODE:
                      nativecode = Utils.parseCommaSeparatedString(cursor.getString(i));
                      break;
                  case Cols.INCOMPATIBLE_REASONS:
                      incompatibleReasons = Utils.parseCommaSeparatedString(cursor.getString(i));
                      break;
                  case Cols.REPO_ID:
  