public void loadRootServers() throws com.grey.base.ConfigException
	{
		HashedMap<ByteChars, java.util.ArrayList<ResourceData>> newroots;
		try {
			newroots = config.loadRootServers(logger);
		} catch (Exception ex) {
			if (ns_roots.size()==0) throw new com.grey.base.ConfigException(ex, LOGLBL+"Failed to bootstrap root servers");
			logger.warn(LOGLBL+"Keeping existing root-servers due to reload failure - "+ex);
			return;
		}

		if (ns_roots.size() != 0) {
			// clean out our existing roots first
			java.util.Iterator<ByteChars> it = ns_roots.iterator();
			while (it.hasNext()) {
				ByteChars domnam = it.next();
				java.util.ArrayList<ResourceData> lst = cache_ns.remove(domnam);
				for (int idx = 0; idx != lst.size(); idx++) {
					ResourceData.RR_NS rr_ns = (ResourceData.RR_NS)lst.get(idx);
					cache_nameservers.remove(rr_ns.getIP());
					cache_a.remove(rr_ns.getHostname());
				}
			}
		}
		ns_roots.clear();
		ns_roots_a.clear();

		ns_roots.addAll(newroots.keySet());
		cache_ns.putAll(newroots);
		java.util.Iterator<java.util.ArrayList<ResourceData>> it = newroots.values().iterator();
		while (it.hasNext()) {
			java.util.ArrayList<ResourceData> lst = it.next();
			for (int idx = 0; idx != lst.size(); idx++) {
				ResourceData.RR_NS rr_ns = (ResourceData.RR_NS)lst.get(idx);
				ResourceData rr_a = new ResourceData.RR_A(rr_ns.getHostname(), rr_ns.getIP(), rr_ns.getExpiry());
				cache_a.put(rr_a.getName(), rr_a);
				ns_roots_a.add(rr_a.getName());
			}
		}
		java.util.Iterator<ByteChars> itbc = ns_roots.iterator();
		String txt = "";
		while (itbc.hasNext()) {
			ByteChars root = itbc.next();
			java.util.ArrayList<ResourceData> lst = cache_ns.get(root);
			txt += "\n\t- Root="+root+" has servers="+lst.size()+"/"+lst;
		}
		logger.info(LOGLBL+"Loaded nameservers for roots="+ns_roots.size()+"/"+ns_roots+txt);
	}