protected void loadConfig() {
    if (FileUtil.resilientConfigFileExists(CONFIG_FILE)) {

      Map map = FileUtil.readResilientConfigFile(CONFIG_FILE);

      List list = (List) map.get("networks");

      if (list != null) {

        for (int i = 0; i < list.size(); i++) {

          Map cnet_map = (Map) list.get(i);

          try {

            ContentNetworkImpl cn = ContentNetworkImpl.importFromBEncodedMapStatic(this, cnet_map);

            if (cn.getID() != ContentNetwork.CONTENT_NETWORK_VUZE) {

              networks.add(cn);
            }
          } catch (Throwable e) {

            log("Failed to load " + cnet_map, e);
          }
        }
      }
    }
  }
  protected void removeNetwork(ContentNetworkImpl network) {
    synchronized (this) {
      if (!networks.remove(network)) {

        return;
      }

      network.destroy();

      saveConfig();
    }

    log("Removed network: " + network.getString());

    Iterator<ContentNetworkListener> it = (Iterator<ContentNetworkListener>) listeners.iterator();

    while (it.hasNext()) {

      try {
        it.next().networkRemoved(network);

      } catch (Throwable e) {

        Debug.out(e);
      }
    }
  }
  protected ContentNetworkImpl createNetwork(contentNetworkDetails details)
      throws ContentNetworkException {
    String main_url = details.getMainURL();
    String icon_url = details.getIconURL();

    String site_dns;

    try {
      site_dns = new URL(main_url).getHost();

    } catch (Throwable e) {

      log("Failed to get main-url host", e);

      throw (new ContentNetworkException("main url invald", e));
    }

    // propagate persistent property defaults and exclusions as currently not returned by webapp

    ContentNetworkImpl existing = getContentNetwork(details.getID());

    Map<String, Object> pprop_defaults = null;
    Set<Integer> service_exclusions = null;

    if (existing != null) {

      pprop_defaults = existing.getPersistentPropertyDefaults();

      if (existing instanceof ContentNetworkVuzeGeneric) {

        service_exclusions = ((ContentNetworkVuzeGeneric) existing).getServiceExclusions();
      }
    }

    return (new ContentNetworkVuzeGeneric(
        this,
        details.getID(),
        details.getVersion(),
        details.getName(),
        pprop_defaults,
        service_exclusions,
        site_dns,
        main_url,
        icon_url,
        null,
        null,
        null,
        null,
        null,
        null));
  }
  public ContentNetworkImpl getContentNetwork(long id) {
    synchronized (this) {
      for (int i = 0; i < networks.size(); i++) {

        ContentNetworkImpl network = networks.get(i);

        if (network.getID() == id) {

          return (network);
        }
      }

      return (null);
    }
  }
  public void generate(IndentWriter writer) {
    writer.println("Content Networks");

    try {
      writer.indent();

      synchronized (this) {
        Iterator<ContentNetworkImpl> it = networks.iterator();

        while (it.hasNext()) {

          ContentNetworkImpl network = it.next();

          writer.println(network.getString());
        }
      }
    } finally {

      writer.exdent();
    }
  }
  protected void saveConfig() {
    Map map = new HashMap();

    List list = new ArrayList();

    map.put("networks", list);

    Iterator<ContentNetworkImpl> it = networks.iterator();

    while (it.hasNext()) {

      ContentNetworkImpl network = it.next();

      if (network.getID() == ContentNetwork.CONTENT_NETWORK_VUZE) {

        continue;
      }

      Map cnet_map = new HashMap();

      try {
        network.exportToBEncodedMap(cnet_map);

        list.add(cnet_map);

      } catch (Throwable e) {

        log("Failed to save " + network.getName(), e);
      }
    }

    if (list.size() == 0) {

      FileUtil.deleteResilientConfigFile(CONFIG_FILE);

    } else {

      FileUtil.writeResilientConfigFile(CONFIG_FILE, map);
    }
  }
  protected ContentNetworkImpl addNetwork(ContentNetworkImpl network) {
    boolean replace = false;

    synchronized (this) {
      Iterator<ContentNetworkImpl> it = networks.iterator();

      while (it.hasNext()) {

        ContentNetworkImpl existing_network = it.next();

        if (existing_network.getID() == network.getID()) {

          if (network.getVersion() > existing_network.getVersion()) {

            try {
              existing_network.updateFrom(network);

            } catch (Throwable e) {

              Debug.printStackTrace(e);
            }

            network = existing_network;

            replace = true;

            break;

          } else {

            log("Network " + existing_network.getString() + " already up to date");

            return (existing_network);
          }
        }
      }

      if (replace) {

        log("Updated network: " + network.getString());

      } else {

        log("Added network: " + network.getString());

        networks.add(network);
      }

      // we never persist the vuze network

      if (network.getID() != ContentNetwork.CONTENT_NETWORK_VUZE) {

        saveConfig();
      }
    }

    Iterator<ContentNetworkListener> it = (Iterator<ContentNetworkListener>) listeners.iterator();

    while (it.hasNext()) {

      try {
        if (replace) {

          it.next().networkChanged(network);

        } else {

          it.next().networkAdded(network);
        }
      } catch (Throwable e) {

        Debug.out(e);
      }
    }

    return (network);
  }
  protected ContentNetworkImpl importNetwork(Map content) throws IOException {

    ContentNetworkImpl network = ContentNetworkImpl.importFromBEncodedMapStatic(this, content);

    return (addNetwork(network));
  }