public interface InputStreamFactory {
	public InputStream get(URL url) throws Exception;
} public interface AppInstall {
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the URL of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL resource, URL dest, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resources the URL to the resources that are going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL[] resource, URL dest, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the URL of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL resource, URL dest, String format, String version, InputStreamFactory factory) throws Exception;
	
	
	/**
	 * Install the given resources in a given URL.
	 * 
	 * @param resources the URL of the resources that are going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL[] resources, URL dest, String format, String version, InputStreamFactory isFactory) throws Exception;
	
	public void install(URL resource, File dest, InputStreamFactory isFactory) throws Exception;
	
	public void install(URL[] resource, File dest, InputStreamFactory isFactory) throws Exception;
	
	public void validate(URL url, String format, String version) throws Exception;
	
	public void register(URL url, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the InputStream of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(InputStream source, URL dest, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param sources the InputStreams of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(InputStream sources[], URL dest, String format, String version) throws Exception;
	
	public void install(InputStream source, File target) throws Exception;
	
	public void install(InputStream[] sources, File target) throws Exception;
} public class AppLocate extends AbstractAppLocate {
} public interface Locate {
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the URL of the resource.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception if something goes wrong during the locating process.
	 */
	public String locate(String resource, String format, String version) throws Exception;
	
	/**
	 * Return the absolute path to the resource given by the URL or null if it
	 * does not exist.
	 * 
	 * @param url the URL of the resource
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @return the absolute path to the local file representing by the given url or null
	 *         if it does not exist
	 *         
	 * @throws Exception if something goes wrong during the locating process.
	 */	
	public File locate(URL resource, String format, String version) throws Exception;
	
	/**
	 * Checks if a given resource has a valid installation.
	 * 
	 * @param url the URL of the resource
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @return true if the resource has a valid installation and false otherwise.
	 * 
	 * @throws Exception if something goes wrong during the validating process.
	 */
	public boolean isValid(URL url, String format, String version) throws Exception;

} public class ResourceAppInstall extends AbstractAppInstall {	
	@Override
	public void install(InputStream source, File target) throws Exception {
		StreamUtils.stream(source, target);
	}
} public class ZipAppInstall extends AbstractDirectoryDataInstall {
	@Override
	public void install(InputStream source, File target) throws Exception {
		ZipUtil.unpack(source, target);
	}
} public class ConsoleInstallInputStreamFactory implements InputStreamFactory {
	
	private final static String MESSAGE = "Installing";

	@Override
	public InputStream get(URL url) throws IOException {
		ConsoleStreamListener listener = new ConsoleStreamListener(MESSAGE + " " + url, URLUtils.getContentLength(url));
		InputStreamInstaller installer = new InputStreamInstaller(url.openStream(), listener);
		return installer;
	}

} public class KBDereferencingException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public KBDereferencingException() {
		super("The knowledge base could not be dereferenced.");
	}
	
	public KBDereferencingException(String kb) {
		super("The knowledge base " + kb + " could not be dereferenced.");
	}
	
	public KBDereferencingException(String kb, Exception e) {
		super("The knowledge base " + kb + " could not be dereferenced.", e);
	}
} public class KBNotLocatedException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public KBNotLocatedException() {
		super("The knowledge base could not be located.");
	}
	
	public KBNotLocatedException(String message) {
		super(message);
	}
} public class KBNotResolvedException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public KBNotResolvedException() {
		super("The knowledge base could not be resolved.");
	}
	
	public KBNotResolvedException(String message) {
		super(message);
	}
} public class TDB {

	public static ResultSet queryGraph(String sparql, String graph, String dbDir) throws Exception {
		Query query = QueryFactory.create(sparql, graph);
		return query(query, dbDir);
	}

	public static Model createModel(String... dbDirs) {
		Model mainModel = null; 
		Dataset dataset = null;
		for(String dbDir : dbDirs) {
			dataset = TDBFactory.createDataset(dbDir);
			if(mainModel == null) {
				mainModel = dataset.getDefaultModel();
			} else {
				Model secondaryModel = dataset.getDefaultModel();
				mainModel = ModelFactory.createUnion(mainModel, secondaryModel);
			}
		}
		mainModel = ModelFactory.createRDFSModel(mainModel);
		return mainModel;
	}
	
	public static Model createModel(File... dirs) {
		return createModel(FileUtils.files2AbsolutePath(dirs));
	}

	public static ResultSet query(Query query, String... dbDirs) throws OperationNotSupportedException {
		Model mainModel = createModel(dbDirs);		
		return query(query, mainModel);
	}

	public static ResultSet query(String sparql, String... dbDirs) throws OperationNotSupportedException {
		Model model = createModel(dbDirs);
		Query query = QueryFactory.create(sparql);
		return query(query, model);
	}
	
	public static ResultSet query(String sparql, File... dbDirs) throws OperationNotSupportedException {
		return query(sparql, FileUtils.files2AbsolutePath(dbDirs));
	}
	
	public static ResultSet query(String sparql, Model model) throws OperationNotSupportedException {
		Query query = QueryFactory.create(sparql);
		return query(query, model);
	}

	public static ResultSet query(Query query, Model model) {
		QueryExecution qe = QueryExecutionFactory.create(query, model);
		ResultSet results = null;
		if(query.isSelectType()) {
			results = qe.execSelect();
		} else if(query.isDescribeType()) {
			Iterator<Triple> triples = qe.execDescribeTriples();
			results = new TripleResultSet(triples, model);
		} else if(query.isConstructType()) {
			Iterator<Triple> triples = qe.execConstructTriples();
			results = new TripleResultSet(triples, model);
		} else if(query.isAskType()) {
			Boolean answer = qe.execAsk();
			List<Boolean> result = new ArrayList<Boolean>();
			result.add(answer);
			results = new BooleanResultSet(result.iterator(), model);
		}
		return results;
	}

	/**
	 * Load a list of files into a database located in a given directory.
	 * 
	 * @param dir directory containing the database file.
	 * @param urls URLs of the files containing the RDF content to be loaded into the database file. 
	 */
	public static void bulkload(String dir, URL... urls) {
		DatasetGraphTransaction dataset = (DatasetGraphTransaction) TDBFactory.createDatasetGraph(dir);
		String[] stringURLs = new String[urls.length];
		int i=0;
		for(URL url : urls) {
			stringURLs[i] = url.toString();
			i++;
		}
		TDBLoader.load(dataset.getDatasetGraphToQuery(), Arrays.asList(stringURLs), true, false);
	}
	
	/**
	 * Load a list of files into a database located in a given directory.
	 * 
	 * @param dir directory containing the database file.
	 * @param urls URLs of the files containing the RDF content to be loaded into the database file. 
	 */
	public static void bulkload(String dir, InputStream... inputStreams) {
		DatasetGraphTransaction dataset = (DatasetGraphTransaction) TDBFactory.createDatasetGraph(dir);
		List<InputStream> streamsList = Arrays.asList(inputStreams);
		SequenceInputStream sInputStream = new SequenceInputStream(Collections.enumeration(streamsList));
		TDBLoader.load(dataset.getDatasetGraphToQuery(), sInputStream, true);
	}
	
	/**
	 * Load a list of files into a database located in a given directory.
	 * 
	 * @param dir directory containing the database file. 
	 * @param lang the RDF streams syntax.
	 * @param inputStreams URLs of the files containing the RDF content to be loaded into the database file.
	 */
	public static void bulkload(String dir, Lang lang, InputStream... inputStreams) {
		List<InputStream> streams = Arrays.asList(inputStreams);
		SequenceInputStream sInputStream = new SequenceInputStream(Collections.enumeration(streams));
		bulkload(dir, lang, sInputStream);
	}
	
	/**
	 * Load a list of files into a database located in a given directory.
	 * 
	 * @param dir directory containing the database file.	 * 
	 * @param lang the RDF streams syntax.
	 * @param inputStream URLs of the files containing the RDF content to be loaded into the database file.
	 */
	public static void bulkload(String dir, Lang lang, InputStream inputStream) {
		DatasetGraph dataset = TDBFactory.createDatasetGraph(dir);
		RDFDataMgr.read(dataset, inputStream, lang);
		dataset.close();
	}

	/**
	 * Query a given KBox endpoint.
	 * 
	 * @param sparql a valid SPARQL query.
	 * @param address the ServerAddress of the service that will be queried.
	 * @return an ResultSet containing the elements retrieved by the given SPARQL query.
	 */
	public static ResultSet queryService(String sparql, ServerAddress address) {
		QueryExecution qe = QueryExecutionFactory.sparqlService(
				address.getQueryURL(), sparql);
        ResultSet results = qe.execSelect();
		return results;
	}
} public class InstallFactory {

	private Map<String, AppInstall> methods = new HashMap<String, AppInstall>();

	public AppInstall get(KN kn) {
		String decoder = kn.getTargets().get(0).getInstall();
		if(decoder == null) {
			return new ResourceAppInstall();
		}
		decoder = decoder.toLowerCase();
		return methods.get(decoder);
	}
	
	public void put(String id, AppInstall install) {
		methods.put(id.toLowerCase(), install);
	}
	
	public AppInstall get(String format) {
		return methods.get(format.toLowerCase());
	}

} public class KN extends KNComparator {
	
	public static final String NAME = "name";
	public static final String SOURCE = "source";
	public static final String URL = "url";
	public static final String TARGET = "target";
	public static final String DESC = "description";
	public static final String KNS = "kns";
	public static final String LICENSE = "license";
	public static final String SUBSETS = "subsets";
	public static final String FORMAT = "format";
	public static final String VERSION = "version";
	public static final String PUBLISHER = "publisher";
	public static final String OWNER = "owner";
	public static final String TAGS = "tags";
	public static final String CHECKSUM = "checksum";
	public static final String DATAID = "dataId";
	public static final String INSTALL = "install";
	public static final String LABEL = "label";
	
	private String name;
	private List<Source> targets;
	private String desc;
	private String kns;
	private String license;
	private String subsets;
	private String format;
	private String version;
	private String publisher;
	private String owner;
	private String label;
	private Set<String> versionTags;
	private Set<String> nameTags;
	
	public KN() {
	}
	
	public KN(String name, List<Source> targets, String desc) {
		this.name = name;
		this.targets = targets;
		this.desc = desc;
	}
	
	public KN(String name, List<Source> targets, String license, String subsets, String desc) {
		this.name = name;
		this.targets = targets;
		this.license = license;
		this.subsets = subsets;
		this.desc = desc;
	}
	
	public KN(String name, 
			List<Source> targets,
			String format, 
			String version, 
			String license, 
			String subsets, 
			String desc) {
		this.name = name;
		this.targets = targets;
		this.format = format;
	    this.version = version;
		this.license = license;
		this.subsets = subsets;
		this.desc = desc;
	}
	
	public KN(String name, 
			List<Source> targets,
			String format, 
			String version, 
			String license, 
			String subsets, 
			String desc, 
			String publisher) {
		this.name = name;
		this.targets = targets;
		this.format = format;
	    this.version = version;
		this.license = license;
		this.subsets = subsets;
		this.desc = desc;
		this.publisher = publisher;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public List<Source> getTargets() {
		return targets;
	}
	
	public void setTargets(List<Source> sources) {
		this.targets = sources;
	}
	
	/**
	 * 
	 * @param json
	 * @return
	 * @throws Exception
	 * TODO: implement mirror.
	 */
	public static KN parse(String json) throws Exception {
		JSONParser jsonParser = new JSONParser();
		Reader stringReader = new StringReader(json);
		JSONObject jsonObject = (JSONObject) jsonParser.parse(stringReader);
		String name = (String) jsonObject.get(NAME);
		JSONArray jsonTarget = (JSONArray) jsonObject.get(TARGET);
		List<Source> sources = Source.toTarget(jsonTarget);
		String desc = (String) jsonObject.get(DESC);
		String publisher = (String) jsonObject.get(PUBLISHER);
		String owner = (String) jsonObject.get(OWNER);
		String label = (String) jsonObject.get(LABEL);
		String format = (String) jsonObject.get(FORMAT);
		Object o = jsonObject.get(LICENSE);
		String license = null;
		if(o != null) {
			license = o.toString().replace("\\", "");
		}		
		o = jsonObject.get(SUBSETS);
		String subsets = null;
		if(o != null) {
			subsets = o.toString().replace("\\", "");
		}
		JSONArray jsonAliases = (JSONArray) jsonObject.get(TAGS);
		Set<String> tags = null;
		if(jsonAliases != null) {
			tags = new HashSet<String>();
			for(int i= 0; i < jsonAliases.size(); i++) {
				tags.add((String)jsonAliases.get(i));				
			}
		}
		JSONObject jsonVersion = (JSONObject) jsonObject.get(VERSION);
		String version = null;
		Set<String> versionTags = null;
		if(jsonVersion != null) {
			version = (String) jsonVersion.get(NAME);
			JSONArray jsonVersionTags = (JSONArray) jsonVersion.get(TAGS);
			if(jsonVersionTags != null) {
				versionTags = new HashSet<String>();
				for(int i= 0; i < jsonVersionTags.size(); i++) {
					versionTags.add((String)jsonVersionTags.get(i));			
				}
			}
		}
		
		KN kn = new KN(name, sources, format, version, license, subsets, desc, publisher);
		kn.setOwner(owner);
		kn.setNameTags(tags);
		kn.setLabel(label);
		kn.setVersionTags(versionTags);
		return kn;
	}
	
	public void setDesc(String desc) {
		this.desc = desc;
	}

	public String getDesc() {
		return desc;
	}

	public void setKNS(String url) {
		this.kns = url;
	}
	
	public String getKNS() {
		return this.kns;
	}

	public String getLicense() {
		return license;
	}

	public void setLicense(String license) {
		this.license = license;
	}

	public String getSubsets() {
		return subsets;
	}

	public void setSubsets(String subsets) {
		this.subsets = subsets;
	}

	public void printURL(PrintStream out) {
		out.println(getName());
	}

	public String getFormat() {
		return format;
	}

	public void setFormat(String format) {
		this.format = format;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}
	
	public String getPublisher() {
		return publisher;
	}
	
	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}

	public boolean equals(String name) {
		return (this.name == name || 
				(this.name != null && (this.name.equals(name) 
						|| contains(nameTags, name))));
	}

	public boolean equals(String name, String format, String version) {
		return (this.name.equals(name) || contains(nameTags, name)) &&
				(format == null || format.equals(this.format)) &&
				(version == null || version.equals(this.version) 
					|| contains(versionTags, name));
	}

	public boolean contains(String name, String format, String version) {
		return (this.name.contains(name) || contains(nameTags, name)) &&
				(format == null || format.equals(this.format)) &&
				(version == null || version.equals(this.version) 
					|| contains(versionTags, name));
	}

	private boolean contains(Set<String> tags, String pattern) {
		if(tags != null) {
			for(String tag : tags) {
				if(tag.contains(pattern)) {
					return true;
				}
			}
		}
		return false;
	}

	public void print(PrintStream out) {
		println(out, "KNS:", kns);
		println(out, "KN:", name);
		println(out, "Name Tags:", nameTags);
		println(out, "label:", label);
		println(out, "Description:", desc);
		println(out, "Subsets:", subsets);
		println(out, "License:", license);
		println(out, "Publisher:", publisher);
		println(out, "Owner:", owner);
		println(out, "Format:", format);
		println(out, "Version:", version);
		println(out, "version Tags:", versionTags);
	}

	public org.json.JSONObject getJsonObject() {
		org.json.JSONObject jsonObject = new org.json.JSONObject();
		jsonObject.put("KNS:", kns);
		jsonObject.put("KN:", name);
		if (nameTags != null) {
			org.json.JSONArray nameTagsArr = new org.json.JSONArray();
			for (String tag : nameTags) {
				nameTagsArr.put(tag);
			}
			jsonObject.put("Name Tags:", nameTagsArr);
		}
		jsonObject.put("label:", label);
		jsonObject.put("Description:", desc);
		jsonObject.put("Subsets:", subsets);
		jsonObject.put("License:", license);
		jsonObject.put("Publisher:", publisher);
		jsonObject.put("Owner:", owner);
		jsonObject.put("Format:", format);
		jsonObject.put("Version:", version);
		if (versionTags != null) {
			org.json.JSONArray versionTagArr = new org.json.JSONArray();
			for (String versionTag : versionTags) {
				versionTagArr.put(versionTag);
			}
			jsonObject.put("version Tags:", versionTagArr);
		}
		return jsonObject;
	}

	private void println(PrintStream out, String label, Object variable) {
		if(variable != null) {
			out.println(label + variable.toString());
		}
	}

	public String getOwner() {
		return owner;
	}

	public void setOwner(String owner) {
		this.owner = owner;
	}

	public Set<String> getNameTags() {
		return nameTags;
	}

	public void setNameTags(Set<String> tags) {
		this.nameTags = tags;
	}

	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	public Set<String> getVersionTags() {
		return versionTags;
	}

	public void setVersionTags(Set<String> versionTags) {
		this.versionTags = versionTags;
	}	
} public interface KNSServerList  {	
	public boolean visit(KNSServerListVisitor visitor) throws Exception;
} public interface KNSServerListVisitor extends Visitor<KNSServer> {	
} public class ServerAddress {
	
	private String url = null;
	
	public ServerAddress(String url) {
		this.url = url;
	}
	
	public String getURL() {
		return url;
	}
	
	public String getQueryURL() {
		return url;
	}
} public class Source {
	private String install;
	private URL url;
	private Map<String,String> checksum;
	
	public String getInstall() {
		return install;
	}

	public void setInstall(String install) {
		this.install = install;
	}

	public URL getURL() {
		return url;
	}

	public void setURL(URL url) {
		this.url = url;
	}

	public Map<String,String> getChecksum() {
		return checksum;
	}

	public void setChecksum(Map<String,String> checksum) {
		this.checksum = checksum;
	}
	
	public static List<Source> toTarget(String json) throws Exception {
		JSONParser jsonParser = new JSONParser();
		Reader stringReader = new StringReader(json);
		JSONArray jsonArray = (JSONArray) jsonParser.parse(stringReader);
		return toTarget(jsonArray);
	}
	
	public static List<Source> toTarget(JSONArray targetArray) throws Exception {
		java.util.List<Source> sources = new ArrayList<Source>();
		if(targetArray != null) {
			for(int m = 0; m < targetArray.size(); m++) {
				JSONArray jsonMirror = (JSONArray) targetArray.get(m);
				for(int s = 0; s < jsonMirror.size(); s++) {
					JSONObject jsonSource = (JSONObject) jsonMirror.get(s);
					String install = (String) jsonSource.keySet().toArray()[0];
					JSONArray jsonSources = (JSONArray) jsonSource.values().toArray()[0];
					if(jsonSources != null) {
						for(int i= 0; i < jsonSources.size(); i++) {
							JSONObject jsonSourceEntry = (JSONObject)jsonSources.get(i);
							String url = (String)jsonSourceEntry.get(KN.URL);
							JSONObject jsonChecksum = (JSONObject) jsonSourceEntry.get(KN.CHECKSUM);
							Map<String, String> checksum = new HashMap<String, String>();
							if(jsonChecksum != null) {
								for(int c = 0; c < jsonChecksum.keySet().size(); c++) {
									String key = (String) jsonChecksum.keySet().toArray()[c];
									String value = (String) jsonChecksum.values().toArray()[c];
									checksum.put(key, value);
								}
							}
							JSONObject jsonDataId = (JSONObject) jsonSourceEntry.get(KN.DATAID);
							Map<String, String> dataId = new HashMap<String, String>();
							if(jsonDataId != null) {
								for(int di = 0; di < jsonDataId.keySet().size(); di++) {
									String key = (String) jsonDataId.keySet().toArray()[di];
									String value = (String) jsonDataId.values().toArray()[di];
									dataId.put(key, value);
								}
							}
							Source source = new Source();
							source.setInstall(install);
							source.setChecksum(checksum);
							URI uri = new URI(url);
							URL knName = null;
							if(uri.isAbsolute() && URLUtils.hasValidURLHost(uri)) {
								knName = new URL(url);
							} else {
								File file = new File(url);
								knName = file.toURI().toURL();
							}
							source.setURL(knName);
							sources.add(source);
						}
					}
				}
			}
		}
		return sources;
	}
} public class ResourceDereferencingException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public ResourceDereferencingException() {
		super("The resource could not be dereferenced.");
	}
	
	public ResourceDereferencingException(String resource) {
		super("The resource " + resource + " could not be dereferenced.");
	}
	
	public ResourceDereferencingException(String resource, Exception e) {
		super("The resource " + resource + " could not be dereferenced.", e);
	}
} public class ResourceNotResolvedException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public ResourceNotResolvedException() {
		super("The resource could not be resolved.");
	}
	
	public ResourceNotResolvedException(String message) {
		super(message);
	}
} public class URLUtils {
	
	private static Set<String> protocolsWithHost = new HashSet<String>( 
		      Arrays.asList( new String[]{ "file", "ftp", "http", "https" } ) 
		  );
	
	public static URL[] stringToURL(String... urls) throws Exception {
		URL[] urlArray = new URL[urls.length];
		for(int i=0; i < urls.length; i++) {
			urlArray[i]  = new URL(urls[i]);
		}
		return urlArray;
	}
	
	public static boolean checkStatus(URL url, int code) throws IOException {
		URLConnection conn = url.openConnection();
		if(conn instanceof HttpURLConnection) {
			HttpURLConnection huc =  (HttpURLConnection) conn;
			huc.setRequestMethod("HEAD");
			conn.connect();
			return huc.getResponseCode() == code;
		}
		return false;
	}
	
	public static URL[] fileToURL(File... files) throws MalformedURLException {
		URL[] urls = new URL[files.length];
		int i = 0;
		for(File file : files) {
			urls[i] = file.toURI().toURL();
			i++;
		}		
		return urls;
	}
	
	public static long getContentLength(URL url) throws IOException {
        URLConnection conn = url.openConnection();
        Long contentLength = conn.getContentLengthLong();
        if(contentLength != null && contentLength >= 0) {
        	return contentLength;
        }
		String contentLengthValue = conn.getHeaderField("content-length");
		if(contentLengthValue != null) {
			return Long.valueOf(contentLengthValue);
		}
		return -1;
	}
	
	public static URL getURLForward(URL url) throws Exception {
		URLConnection con = url.openConnection();
		String location = con.getHeaderField("Location");
		if(location != null) {
			return new URL(location);
		}
		return url;
	}
	
	public static boolean hasValidURLHost(URI uri) {
		return protocolsWithHost.contains(uri.getScheme());
	}
	
	public static String getContentType(URL url) throws Exception {
		URL forwardURL = getURLForward(url);
		HttpURLConnection connection = (HttpURLConnection)  forwardURL.openConnection();
		connection.setRequestMethod("HEAD");
		connection.connect();
		return connection.getContentType();
	}
}
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.naming.spi.Resolver;
import org.aksw.kbox.InputStreamFactory;
import org.aksw.kbox.apple.AppInstall;
import org.aksw.kbox.apple.AppLocate;
import org.aksw.kbox.apple.Locate;
import org.aksw.kbox.apple.ResourceAppInstall;
import org.aksw.kbox.apple.ZipAppInstall;
import org.aksw.kbox.kibe.console.ConsoleInstallInputStreamFactory;
import org.aksw.kbox.kibe.exception.KBDereferencingException;
import org.aksw.kbox.kibe.exception.KBNotLocatedException;
import org.aksw.kbox.kibe.exception.KBNotResolvedException;
import org.aksw.kbox.kibe.tdb.TDB;
import org.aksw.kbox.kns.InstallFactory;
import org.aksw.kbox.kns.KN;
import org.aksw.kbox.kns.KNSServerList;
import org.aksw.kbox.kns.KNSServerListVisitor;
import org.aksw.kbox.kns.ServerAddress;
import org.aksw.kbox.kns.Source;
import org.aksw.kbox.kns.exception.ResourceDereferencingException;
import org.aksw.kbox.kns.exception.ResourceNotResolvedException;
import org.aksw.kbox.utils.URLUtils;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.tdb.TDBFactory;
import org.zeroturnaround.zip.ZipUtil;
		Locate kbLocate = new AppLocate();
		DefaultKNSServerList knsServerList = new DefaultKNSServerList();
		InstallFactory installFactory = new DefaultInstallFactory();
		for(URL knowledgeBase : urls) {
			try {
				File kbDir = getResource(knsServerList,
						knowledgeBase,
						kbLocate,
						KIBE_FORMAT,
						KIBE_VERSION,
						installFactory,
						isFactory,
						install);
				knowledgeBasesPaths[i] = kbDir;
				i++;
			} catch (ResourceNotResolvedException e) {
				throw new KBNotResolvedException("The Knowledge base " + knowledgeBase.toString() + " is not installed."
						+ " You can install it setting the flag install.");
			} catch (ResourceDereferencingException e) {
				throw new KBDereferencingException(knowledgeBase.toString(), e);
			}
			
		}
		return knowledgeBasesPaths;
	}
	
	/**
	 * Return the local path(s) from the given knowledge name(s).
	 * 
	 * @param isFactory a {@link InputStreamFactory} to stream the given KB in case they are not locally available.
	 * @param install flag indicating to install the KB in case it cannot be located.
	 * @param kns an array containing the KBs' KN(s) {@link URL}(s).
	 * @return An array containing the relative path to the KB(s).
	 * 
	 * @throws Exception if an error occurs during resolving or dereferencing any of the KBs.
	 */
	public static File[] getKB(URL knsServer, URL[] kns, InputStreamFactory isFactory, boolean install) throws Exception {
		File[] knowledgeBasesPaths = new File[kns.length];
		int i = 0;
		Locate kbLocate = new AppLocate();
		InstallFactory installFactory = new DefaultInstallFactory();
		for(URL knowledgeBase : kns) {
			try {
				File kbDir = getResource(knsServer,
						knowledgeBase,
						kbLocate,
						KIBE_FORMAT,
						KIBE_VERSION,
						installFactory,
						isFactory,
						install);
				knowledgeBasesPaths[i] = kbDir;
				i++;
			} catch (ResourceNotResolvedException e) {
				throw new KBNotResolvedException("The Knowledge base " + knowledgeBase.toString() + " is not installed."
						+ " You can install it setting the flag install.");
			} catch (ResourceDereferencingException e) {
				throw new KBDereferencingException(knowledgeBase.toString(), e);
			}
			
		}
		return knowledgeBasesPaths;
	}
	
	
	/**
	 * Create a {@link Model} with a given RDF knowledge base Names.
	 * Warning: This method automatically dereference the RDF KBs.
	 * 
	 * @param knowledgeNames the RDF KB Names to be queried.        
	 * 
	 * @return a {@link Model} containing the RDF KBs.
	 * 
	 * @throws Exception if some error occurs during the knowledge base 
	 *         dereference or model instantiation. 
	 */
	public static Model createModel(URL... knowledgeNames) throws Exception {
		return createModel(new ConsoleInstallInputStreamFactory(), true, knowledgeNames);
	}
	
	/**
	 * Create a Model with a given Knowledge base Names.
	 * 
	 * 
	 * @param install install a given knowledge base in case it does not exist.
	 * @param knowledgeNames the RDF KB Names to be queried.
	 * 
	 * @return a {@link Model} containing the RDF KBs.
	 * 
	 * @throws Exception if some error occurs during the KB 
	 *         dereference or model instantiation. 
	 */
	public static Model createModel(boolean install, URL... knowledgeNames) throws Exception {
		return createModel(new ConsoleInstallInputStreamFactory(), install, knowledgeNames);
	}
	
	/**
	 * Query a given model.
	 * 
	 * @param sparql the SPARQL query that will be used to query.
	 * @param model the {@link  Model} that will be queried.
	 * 
	 * @return a {@link ResultSet} containing the result to a given query.	 
	 *  
	 * @throws Exception if some error occurs during the query execution.
	 */
	public static ResultSet query(String sparql, Model model) throws Exception {
		return TDB.query(sparql, model);
	}
	
	/**
	 * Executes a given query in a KBox service endpoints address.
	 * 
	 * @param sparql the SPARQL query that will be used to query.
	 * @param url the {@link URL} of the service.
	 * 
	 * @return a {@link ResultSet} containing the result to a given query.
	 * 
	 * @throws Exception if some error occurs during the query execution.
	 */
	public static ResultSet query(String sparql, ServerAddress service) throws Exception {