NS_IMETHODIMP
nsStringBundleService::CreateBundle(const char* aURLSpec, 
                                    nsIStringBundle** aResult)
{
#ifdef DEBUG_tao_
  printf("\n++ nsStringBundleService::CreateBundle ++\n");
  printf("\n** nsStringBundleService::CreateBundle: %s\n", aURLSpec ? aURLSpec : "null");
#endif

  return getStringBundle(aURLSpec,aResult);
}
NS_IMETHODIMP
nsStringBundleService::FormatStatusMessage(nsresult aStatus,
                                           const PRUnichar* aStatusArg,
                                           PRUnichar* *result)
{
  nsresult rv;
  PRUint32 i, argCount = 0;
  nsCOMPtr<nsIStringBundle> bundle;
  nsXPIDLCString stringBundleURL;

  // XXX hack for mailnews who has already formatted their messages:
  if (aStatus == NS_OK && aStatusArg) {
    *result = nsCRT::strdup(aStatusArg);
    NS_ENSURE_TRUE(*result, NS_ERROR_OUT_OF_MEMORY);
    return NS_OK;
  }

  if (aStatus == NS_OK) {
    return NS_ERROR_FAILURE;       // no message to format
  }

  // format the arguments:
  const nsDependentString args(aStatusArg);
  argCount = args.CountChar(PRUnichar('\n')) + 1;
  NS_ENSURE_ARG(argCount <= 10); // enforce 10-parameter limit
  PRUnichar* argArray[10];

  // convert the aStatusArg into a PRUnichar array
  if (argCount == 1) {
    // avoid construction for the simple case:
    argArray[0] = (PRUnichar*)aStatusArg;
  }
  else if (argCount > 1) {
    PRInt32 offset = 0;
    for (i = 0; i < argCount; i++) {
      PRInt32 pos = args.FindChar('\n', offset);
      if (pos == -1) 
        pos = args.Length();
      argArray[i] = ToNewUnicode(Substring(args, offset, pos - offset));
      if (argArray[i] == nsnull) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        argCount = i - 1; // don't try to free uninitialized memory
        goto done;
      }
      offset = pos + 1;
    }
  }

  // find the string bundle for the error's module:
  rv = mErrorService->GetErrorStringBundle(NS_ERROR_GET_MODULE(aStatus), 
                                           getter_Copies(stringBundleURL));
  if (NS_SUCCEEDED(rv)) {
    rv = getStringBundle(stringBundleURL, getter_AddRefs(bundle));
    if (NS_SUCCEEDED(rv)) {
      rv = FormatWithBundle(bundle, aStatus, argCount, argArray, result);
    }
  }
  if (NS_FAILED(rv)) {
    rv = getStringBundle(GLOBAL_PROPERTIES, getter_AddRefs(bundle));
    if (NS_SUCCEEDED(rv)) {
      rv = FormatWithBundle(bundle, aStatus, argCount, argArray, result);
    }
  }

done:
  if (argCount > 1) {
    for (i = 0; i < argCount; i++) {
      if (argArray[i])
        nsMemory::Free(argArray[i]);
    }
  }
  return rv;
}
/* nsIRDFNode GetTarget (in nsIRDFResource aSource, in nsIRDFResource property, in boolean aTruthValue); */
NS_IMETHODIMP
nsMsgAccountManagerDataSource::GetTarget(nsIRDFResource *source,
                                         nsIRDFResource *property,
                                         PRBool aTruthValue,
                                         nsIRDFNode **target)
{
  nsresult rv;


  rv = NS_RDF_NO_VALUE;

  nsAutoString str;
  if (property == kNC_Name || property == kNC_FolderTreeName ||
      property == kNC_FolderTreeSimpleName) 
  {
    rv = getStringBundle();
    NS_ENSURE_SUCCESS(rv, rv);

    nsXPIDLString pageTitle;
    if (source == kNC_PageTitleServer)
      mStringBundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-server").get(),
                                       getter_Copies(pageTitle));

    else if (source == kNC_PageTitleCopies)
      mStringBundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-copies").get(),
                                       getter_Copies(pageTitle));
    else if (source == kNC_PageTitleOfflineAndDiskSpace)
      mStringBundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-offline-and-diskspace").get(),
                                       getter_Copies(pageTitle));
    else if (source == kNC_PageTitleDiskSpace)
      mStringBundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-diskspace").get(),
                                       getter_Copies(pageTitle));
    else if (source == kNC_PageTitleAddressing)
      mStringBundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-addressing").get(),
                                       getter_Copies(pageTitle));
    else if (source == kNC_PageTitleSMTP)
      mStringBundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-smtp").get(),
                                       getter_Copies(pageTitle));
    else if (source == kNC_PageTitleJunk)
      mStringBundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-junk").get(),
                                       getter_Copies(pageTitle));

    else if (source == kNC_PageTitleFakeAccount) {
      PRBool showFakeAccount;
      nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
      if (NS_SUCCEEDED(rv))
        rv = prefBranch->GetBoolPref(PREF_SHOW_FAKE_ACCOUNT, &showFakeAccount);

      if (showFakeAccount) {
        nsCOMPtr<nsIStringBundleService> strBundleService =
          do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
        if (NS_FAILED(rv)) return rv;
        nsCOMPtr<nsIStringBundle> bundle;
        rv = strBundleService->CreateBundle("chrome://messenger/locale/fakeAccount.properties",
                                             getter_AddRefs(bundle));
        if (NS_SUCCEEDED(rv))
          bundle->GetStringFromName(NS_LITERAL_STRING("prefPanel-fake-account").get(),
                                    getter_Copies(pageTitle));
      }
    }

    else {
      // if it's a server, use the pretty name
      nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(source, &rv);
      if (NS_SUCCEEDED(rv) && folder) {
        PRBool isServer;
        rv = folder->GetIsServer(&isServer);
        if (NS_SUCCEEDED(rv) && isServer)
          rv = folder->GetPrettyName(getter_Copies(pageTitle));
      }
      else {
        // allow for the accountmanager to be dynamically extended.

        nsCOMPtr<nsIStringBundleService> strBundleService =
          do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
        NS_ENSURE_SUCCESS(rv,rv);

        const char *sourceValue;
        rv = source->GetValueConst(&sourceValue);
        NS_ENSURE_SUCCESS(rv,rv);

        // make sure the pointer math we're about to do is safe.
        NS_ENSURE_TRUE(sourceValue && (strlen(sourceValue) > strlen(NC_RDF_PAGETITLE_PREFIX)), NS_ERROR_UNEXPECTED);

        nsCOMPtr<nsIMsgAccountManager> am = do_QueryReferent(mAccountManager, &rv);
        NS_ENSURE_SUCCESS(rv, PR_FALSE);

        // turn NC#PageTitlefoobar into foobar, so we can get the am-foobar.properties bundle
        nsXPIDLCString chromePackageName;
        rv = am->GetChromePackageName((sourceValue + strlen(NC_RDF_PAGETITLE_PREFIX)), getter_Copies(chromePackageName));
        NS_ENSURE_SUCCESS(rv,rv);

        nsCAutoString bundleURL;
        bundleURL = "chrome://";
        bundleURL += chromePackageName;
        bundleURL += "/locale/am-";
        bundleURL += (sourceValue + strlen(NC_RDF_PAGETITLE_PREFIX));
        bundleURL += ".properties";

        nsCOMPtr <nsIStringBundle> bundle;
        rv = strBundleService->CreateBundle(bundleURL.get(), getter_AddRefs(bundle));

        NS_ENSURE_SUCCESS(rv,rv);

        nsAutoString panelTitleName;
        panelTitleName.AssignLiteral("prefPanel-");
        panelTitleName.AppendWithConversion(sourceValue + strlen(NC_RDF_PAGETITLE_PREFIX));
        bundle->GetStringFromName(panelTitleName.get(), getter_Copies(pageTitle));
      }
    }
    str = pageTitle.get();
  }
  else if (property == kNC_PageTag) {
    // do NOT localize these strings. these are the urls of the XUL files
    if (source == kNC_PageTitleServer)
      str.AssignLiteral("am-server.xul");
    else if (source == kNC_PageTitleCopies)
      str.AssignLiteral("am-copies.xul");
    else if ((source == kNC_PageTitleOfflineAndDiskSpace) ||
             (source == kNC_PageTitleDiskSpace))
      str.AssignLiteral("am-offline.xul");
    else if (source == kNC_PageTitleAddressing)
      str.AssignLiteral("am-addressing.xul");
    else if (source == kNC_PageTitleSMTP)
      str.AssignLiteral("am-smtp.xul");
    else if (source == kNC_PageTitleJunk)
      str.AssignLiteral("am-junk.xul");
    else if (source == kNC_PageTitleFakeAccount)
      str.AssignLiteral("am-fakeaccount.xul");
    else {
      nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(source, &rv);
      if (NS_SUCCEEDED(rv) && folder) {
        /* if this is a server, with no identities, then we show a special panel */
        nsCOMPtr<nsIMsgIncomingServer> server;
        rv = getServerForFolderNode(source, getter_AddRefs(server));
        if (server)
          server->GetAccountManagerChrome(str);
        else 
          str.AssignLiteral("am-main.xul");
      }
      else {
        // allow for the accountmanager to be dynamically extended
        const char *sourceValue;
        rv = source->GetValueConst(&sourceValue);
        NS_ENSURE_SUCCESS(rv,rv);

        // make sure the pointer math we're about to do is safe.
        NS_ENSURE_TRUE(sourceValue && (strlen(sourceValue) > strlen(NC_RDF_PAGETITLE_PREFIX)), NS_ERROR_UNEXPECTED);

        // turn NC#PageTitlefoobar into foobar, so we can get the am-foobar.xul file
        str.AssignLiteral("am-");
        str.AppendWithConversion((sourceValue + strlen(NC_RDF_PAGETITLE_PREFIX)));
        str.AppendLiteral(".xul");
      }
    }
  }

  // handle sorting of servers
  else if ((property == kNC_NameSort) ||
           (property == kNC_FolderTreeNameSort)) {

    // order for the folder pane
    // and for the account manager tree is:
    //
    // - default mail account
    // - <other mail accounts>
    // - "Local Folders" account
    // - news accounts
    // - smtp settings (note, this is only in account manager tree)
    // - fake account

    // make sure we're handling a root folder that is a server
    nsCOMPtr<nsIMsgIncomingServer> server;
    rv = getServerForFolderNode(source, getter_AddRefs(server));

    if (NS_SUCCEEDED(rv) && server) {
      PRInt32 accountNum;
      nsCOMPtr<nsIMsgAccountManager> am = do_QueryReferent(mAccountManager);

      if (isDefaultServer(server))
        str.AssignLiteral("0000");
      else {
        rv = am->FindServerIndex(server, &accountNum);
        if (NS_FAILED(rv)) return rv;

        // this is a hack for now - hardcode server order by type
        nsXPIDLCString serverType;
        server->GetType(getter_Copies(serverType));

        if (nsCRT::strcasecmp(serverType, "none")==0)
          accountNum += 2000;
        else if (nsCRT::strcasecmp(serverType, "nntp")==0)
          accountNum += 3000;
        else
          accountNum += 1000;     // default is to appear at the top

        str.AppendInt(accountNum);
      }
    }
    else {
      const char *sourceValue;
      rv = source->GetValueConst(&sourceValue);
      NS_ENSURE_SUCCESS(rv, NS_RDF_NO_VALUE);

      // if this is a page (which we determine by the prefix of the URI)
      // we want to generate a sort value
      // so that we can sort the categories in the account manager tree
      // (or the folder pane)
      //
      // otherwise, return NS_RDF_NO_VALUE
      // so that the folder data source will take care of it.
      if (sourceValue && (strncmp(sourceValue, NC_RDF_PAGETITLE_PREFIX, strlen(NC_RDF_PAGETITLE_PREFIX)) == 0)) {
        if (source == kNC_PageTitleSMTP)
          str.AssignLiteral("4000");
        else if (source == kNC_PageTitleFakeAccount)
          str.AssignLiteral("5000");
        else if (source == kNC_PageTitleServer)
          str.AssignLiteral("1");
        else if (source == kNC_PageTitleCopies)
          str.AssignLiteral("2");
        else if (source == kNC_PageTitleAddressing)
          str.AssignLiteral("3");
        else if (source == kNC_PageTitleOfflineAndDiskSpace)
          str.AssignLiteral("4");
        else if (source == kNC_PageTitleDiskSpace)
          str.AssignLiteral("4");
        else if (source == kNC_PageTitleJunk)
          str.AssignLiteral("5");
        else {
          // allow for the accountmanager to be dynamically extended
          // all the other pages come after the standard ones
          // server, copies, addressing, disk space (or offline & disk space)
          str.AssignWithConversion(sourceValue);
        }
      }
      else {
        return NS_RDF_NO_VALUE;
      }
    }
  }

  // GetTargets() stuff - need to return a valid answer so that
  // twisties will appear
  else if (property == kNC_Settings) {
    nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(source,&rv);
    if (NS_FAILED(rv))
      return NS_RDF_NO_VALUE;

    PRBool isServer=PR_FALSE;
    folder->GetIsServer(&isServer);
    // no need to localize this!
    if (isServer)
      str.AssignLiteral("ServerSettings");
  }

  else if (property == kNC_IsDefaultServer) {
    nsCOMPtr<nsIMsgIncomingServer> thisServer;
    rv = getServerForFolderNode(source, getter_AddRefs(thisServer));
    if (NS_FAILED(rv) || !thisServer) return NS_RDF_NO_VALUE;

    if (isDefaultServer(thisServer))
      str.AssignLiteral("true");
  }

  else if (property == kNC_SupportsFilters) {
    nsCOMPtr<nsIMsgIncomingServer> server;
    rv = getServerForFolderNode(source, getter_AddRefs(server));
    if (NS_FAILED(rv) || !server) return NS_RDF_NO_VALUE;

    if (supportsFilters(server))
      str.AssignLiteral("true");
  }
  else if (property == kNC_CanGetMessages) {
    nsCOMPtr<nsIMsgIncomingServer> server;
    rv = getServerForFolderNode(source, getter_AddRefs(server));
    if (NS_FAILED(rv) || !server) return NS_RDF_NO_VALUE;

    if (canGetMessages(server))
      str.AssignLiteral("true");
  }
  else if (property == kNC_CanGetIncomingMessages) {
    nsCOMPtr<nsIMsgIncomingServer> server;
    rv = getServerForFolderNode(source, getter_AddRefs(server));
    if (NS_FAILED(rv) || !server) return NS_RDF_NO_VALUE;

    if (canGetIncomingMessages(server))
      str.AssignLiteral("true");
  }
  else if (property == kNC_PageTitleFakeAccount) {
    if (source == kNC_PageTitleFakeAccount)
      str.AssignLiteral("true");
  }
  if (!str.IsEmpty())
    rv = createNode(str.get(), target, getRDFService());

  //if we have an empty string and we don't have an error value, then
  //we don't have a value for RDF.
  else if(NS_SUCCEEDED(rv))
    rv = NS_RDF_NO_VALUE;

  return rv;
}