private int insertAccountsHeaders(List<Header> target, int headerIndex) {
    String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes();
    List<Header> accountHeaders = new ArrayList<Header>(accountTypes.length);
    for (String accountType : accountTypes) {
      CharSequence label = mAuthenticatorHelper.getLabelForType(this, accountType);
      if (label == null) {
        continue;
      }

      Account[] accounts = AccountManager.get(this).getAccountsByType(accountType);
      boolean skipToAccount =
          accounts.length == 1 && !mAuthenticatorHelper.hasAccountPreferences(accountType);
      Header accHeader = new Header();
      accHeader.title = label;
      if (accHeader.extras == null) {
        accHeader.extras = new Bundle();
      }
      if (skipToAccount) {
        accHeader.breadCrumbTitleRes = R.string.account_sync_settings_title;
        accHeader.breadCrumbShortTitleRes = R.string.account_sync_settings_title;
        accHeader.fragment = AccountSyncSettings.class.getName();
        accHeader.fragmentArguments = new Bundle();
        // Need this for the icon
        accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
        accHeader.extras.putParcelable(AccountSyncSettings.ACCOUNT_KEY, accounts[0]);
        accHeader.fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY, accounts[0]);
      } else {
        accHeader.breadCrumbTitle = label;
        accHeader.breadCrumbShortTitle = label;
        accHeader.fragment = ManageAccountsSettings.class.getName();
        accHeader.fragmentArguments = new Bundle();
        accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
        accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
        if (!isMultiPane()) {
          accHeader.fragmentArguments.putString(
              ManageAccountsSettings.KEY_ACCOUNT_LABEL, label.toString());
        }
      }
      accountHeaders.add(accHeader);
    }

    // Sort by label
    Collections.sort(
        accountHeaders,
        new Comparator<Header>() {
          @Override
          public int compare(Header h1, Header h2) {
            return h1.title.toString().compareTo(h2.title.toString());
          }
        });

    for (Header header : accountHeaders) {
      target.add(headerIndex++, header);
    }
    if (!mListeningToAccountUpdates) {
      AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
      mListeningToAccountUpdates = true;
    }
    return headerIndex;
  }
  /**
   * Override initial header when an activity-alias is causing Settings to be launched for a
   * specific fragment encoded in the android:name parameter.
   */
  @Override
  public Header onGetInitialHeader() {
    String fragmentClass = getStartingFragmentClass(super.getIntent());
    if (fragmentClass != null) {
      Header header = new Header();
      header.fragment = fragmentClass;
      header.title = getTitle();
      header.fragmentArguments = getIntent().getExtras();
      mCurrentHeader = header;
      return header;
    }

    return mFirstHeader;
  }
  /**
   * Parse the given XML file as a header description, adding each parsed Header into the target
   * list.
   *
   * @param resid The XML resource to load and parse.
   * @param target The list in which the parsed headers should be placed.
   */
  public void loadHeadersFromResource(int resid, List<Header> target) {
    XmlResourceParser parser = null;
    try {
      parser = getResources().getXml(resid);
      AttributeSet attrs = Xml.asAttributeSet(parser);

      int type;
      while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
          && type != XmlPullParser.START_TAG) {
        // Parse next until start tag is found
      }

      String nodeName = parser.getName();
      if (!"preference-headers".equals(nodeName)) {
        throw new RuntimeException(
            "XML document must start with <preference-headers> tag; found"
                + nodeName
                + " at "
                + parser.getPositionDescription());
      }

      Bundle curBundle = null;

      final int outerDepth = parser.getDepth();
      while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
          && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
          continue;
        }

        nodeName = parser.getName();
        if ("header".equals(nodeName)) {
          Header header = new Header();

          TypedArray sa = getResources().obtainAttributes(attrs, R.styleable.PreferenceHeader);
          header.id = sa.getResourceId(R.styleable.PreferenceHeader_id, (int) HEADER_ID_UNDEFINED);
          TypedValue tv = sa.peekValue(R.styleable.PreferenceHeader_title);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.titleRes = tv.resourceId;
            } else {
              header.title = tv.string;
            }
          }
          tv = sa.peekValue(R.styleable.PreferenceHeader_summary);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.summaryRes = tv.resourceId;
            } else {
              header.summary = tv.string;
            }
          }
          tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbTitle);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.breadCrumbTitleRes = tv.resourceId;
            } else {
              header.breadCrumbTitle = tv.string;
            }
          }
          tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbShortTitle);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.breadCrumbShortTitleRes = tv.resourceId;
            } else {
              header.breadCrumbShortTitle = tv.string;
            }
          }
          header.iconRes = sa.getResourceId(R.styleable.PreferenceHeader_icon, 0);
          header.fragment = sa.getString(R.styleable.PreferenceHeader_fragment);
          sa.recycle();

          if (curBundle == null) {
            curBundle = new Bundle();
          }

          final int innerDepth = parser.getDepth();
          while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
              && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
              continue;
            }

            String innerNodeName = parser.getName();
            if (innerNodeName.equals("extra")) {
              getResources().parseBundleExtra("extra", attrs, curBundle);
              XmlUtils.skipCurrentTag(parser);

            } else if (innerNodeName.equals("intent")) {
              header.intent = Intent.parseIntent(getResources(), parser, attrs);

            } else {
              XmlUtils.skipCurrentTag(parser);
            }
          }

          if (curBundle.size() > 0) {
            header.fragmentArguments = curBundle;
            curBundle = null;
          }

          target.add(header);
        } else {
          XmlUtils.skipCurrentTag(parser);
        }
      }

    } catch (XmlPullParserException e) {
      throw new RuntimeException("Error parsing headers", e);
    } catch (IOException e) {
      throw new RuntimeException("Error parsing headers", e);
    } finally {
      if (parser != null) parser.close();
    }
  }