synchronized DocumentArchive get() throws FileNotFoundException {
      if (mArchive != null) {
        return mArchive;
      }

      try {
        if (mLocalFile != null) {
          mArchive =
              DocumentArchive.createForLocalFile(
                  mProvider.getContext(),
                  mLocalFile,
                  mId.mArchiveId,
                  mIdDelimiter,
                  mNotificationUri);
        } else {
          mArchive =
              DocumentArchive.createForParcelFileDescriptor(
                  mProvider.getContext(),
                  mProvider.openDocument(mId.mArchiveId, "r", null /* signal */),
                  mId.mArchiveId,
                  mIdDelimiter,
                  mNotificationUri);
        }
      } catch (IOException e) {
        throw new IllegalStateException(e);
      }

      return mArchive;
    }
  private Loader getInstanceUncheckedLocked(String documentId) throws FileNotFoundException {
    try {
      final ParsedDocumentId id = ParsedDocumentId.fromDocumentId(documentId, mIdDelimiter);
      if (mArchives.get(id.mArchiveId) != null) {
        return mArchives.get(id.mArchiveId);
      }

      final Cursor cursor =
          mProvider.queryDocument(
              id.mArchiveId, new String[] {Document.COLUMN_MIME_TYPE, COLUMN_LOCAL_FILE_PATH});
      cursor.moveToFirst();
      final String mimeType = cursor.getString(cursor.getColumnIndex(Document.COLUMN_MIME_TYPE));
      Preconditions.checkArgument(isSupportedArchiveType(mimeType), "Unsupported archive type.");
      final int columnIndex = cursor.getColumnIndex(COLUMN_LOCAL_FILE_PATH);
      final String localFilePath = columnIndex != -1 ? cursor.getString(columnIndex) : null;
      final File localFile = localFilePath != null ? new File(localFilePath) : null;
      final Uri notificationUri = cursor.getNotificationUri();
      final Loader loader = new Loader(mProvider, localFile, id, mIdDelimiter, notificationUri);

      // Remove the instance from mArchives collection once the archive file changes.
      if (notificationUri != null) {
        final LruCache<String, Loader> finalArchives = mArchives;
        mProvider
            .getContext()
            .getContentResolver()
            .registerContentObserver(
                notificationUri,
                false,
                new ContentObserver(null) {
                  @Override
                  public void onChange(boolean selfChange, Uri uri) {
                    synchronized (mArchives) {
                      final Loader currentLoader = mArchives.get(id.mArchiveId);
                      if (currentLoader == loader) {
                        mArchives.remove(id.mArchiveId);
                      }
                    }
                  }
                });
      }

      mArchives.put(id.mArchiveId, loader);
      return loader;
    } catch (IOException e) {
      // DocumentsProvider doesn't use IOException. For consistency convert it to
      // IllegalStateException.
      throw new IllegalStateException(e);
    }
  }