private VCardEntry parseVcard(String str) throws IOException, ParseException {
    VCardEntry vcard = null;

    try {
      VCardParser p = new VCardParser_V21();
      VCardEntryConstructor c = new VCardEntryConstructor();
      VcardHandler handler = new VcardHandler();
      c.addEntryHandler(handler);
      p.addInterpreter(c);
      p.parse(new ByteArrayInputStream(str.getBytes()));

      vcard = handler.vcard;

    } catch (VCardVersionException e1) {

      try {
        VCardParser p = new VCardParser_V30();
        VCardEntryConstructor c = new VCardEntryConstructor();
        VcardHandler handler = new VcardHandler();
        c.addEntryHandler(handler);
        p.addInterpreter(c);
        p.parse(new ByteArrayInputStream(str.getBytes()));

        vcard = handler.vcard;

      } catch (VCardVersionException e2) {
        // will throw below
      } catch (VCardException e2) {
        // will throw below
      }

    } catch (VCardException e1) {
      // will throw below
    }

    if (vcard == null) {
      throw new ParseException("Cannot parse vCard object (neither 2.1 nor 3.0?)", mParser.pos());
    }

    return vcard;
  }
    /**
     * Reads localDataUri (possibly multiple times) and constructs {@link ImportRequest} from its
     * content.
     *
     * @arg localDataUri Uri actually used for the import. Should be stored in app local storage, as
     *     we cannot guarantee other types of Uris can be read multiple times. This variable
     *     populates {@link ImportRequest#uri}.
     * @arg displayName Used for displaying information to the user. This variable populates {@link
     *     ImportRequest#displayName}.
     */
    private ImportRequest constructImportRequest(
        final byte[] data, final Uri localDataUri, final String displayName)
        throws IOException, VCardException {
      final ContentResolver resolver = ImportVCardActivity.this.getContentResolver();
      VCardEntryCounter counter = null;
      VCardSourceDetector detector = null;
      int vcardVersion = VCARD_VERSION_V21;
      try {
        boolean shouldUseV30 = false;
        InputStream is;
        if (data != null) {
          is = new ByteArrayInputStream(data);
        } else {
          is = resolver.openInputStream(localDataUri);
        }
        mVCardParser = new VCardParser_V21();
        try {
          counter = new VCardEntryCounter();
          detector = new VCardSourceDetector();
          mVCardParser.addInterpreter(counter);
          mVCardParser.addInterpreter(detector);
          mVCardParser.parse(is);
        } catch (VCardVersionException e1) {
          try {
            is.close();
          } catch (IOException e) {
          }

          shouldUseV30 = true;
          if (data != null) {
            is = new ByteArrayInputStream(data);
          } else {
            is = resolver.openInputStream(localDataUri);
          }
          mVCardParser = new VCardParser_V30();
          try {
            counter = new VCardEntryCounter();
            detector = new VCardSourceDetector();
            mVCardParser.addInterpreter(counter);
            mVCardParser.addInterpreter(detector);
            mVCardParser.parse(is);
          } catch (VCardVersionException e2) {
            throw new VCardException("vCard with unspported version.");
          }
        } finally {
          if (is != null) {
            try {
              is.close();
            } catch (IOException e) {
            }
          }
        }

        vcardVersion = shouldUseV30 ? VCARD_VERSION_V30 : VCARD_VERSION_V21;
      } catch (VCardNestedException e) {
        Log.w(LOG_TAG, "Nested Exception is found (it may be false-positive).");
        // Go through without throwing the Exception, as we may be able to detect the
        // version before it
      }
      return new ImportRequest(
          mAccount,
          data,
          localDataUri,
          displayName,
          detector.getEstimatedType(),
          detector.getEstimatedCharset(),
          vcardVersion,
          counter.getCount());
    }