[Arakhnę-Dev] [343] * Java 1.6 -> Java 1.7

[ Thread Index | Date Index | More arakhne.org/dev Archives ]


Revision: 343
Author:   galland
Date:     2012-07-09 22:15:00 +0200 (Mon, 09 Jul 2012)
Log Message:
-----------
* Java 1.6 -> Java 1.7

Added Paths:
-----------
    trunk/arakhneVmutils/arakhneVmutils-java/pom.xml
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AbstractOperatingSystemWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Android.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AndroidResourceWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Caller.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassComparator.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClasspathUtil.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/FileSystem.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/LibraryLoader.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/MACNumber.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystem.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemAndroidWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemDiskUtilWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemIdentificationType.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemNativeWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemUDevWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Resources.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/StandardJREResourceWrapper.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URISchemeType.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URLHandlerUtil.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/VMCommandLine.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/Caller.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/StackTraceCaller.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/SunCaller.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/Handler.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/HandlerFactory.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/URLConnection.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/Locale.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/LocaleMessageFormat.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/Handler.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/HandlerFactory.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/URLConnection.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem.properties
    trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem_fr.properties
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/CallerTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ClasspathUtilTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/FileSystemTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ResourcesTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/file/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/file/URLConnectionTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleStub.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/resource/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/resource/URLConnectionTest.java
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleStub.properties
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleTest.properties
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test.txt
    trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test2.txt

Added: trunk/arakhneVmutils/arakhneVmutils-java/pom.xml
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/pom.xml	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/pom.xml	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd";>
+
+	<modelVersion>4.0.0</modelVersion>
+
+	<!-- === CAUTION === CAUTION === CAUTION === The parent module is not arakhneVmutils 
+		to avoid cyclic compilation problems -->
+	<parent>
+		<artifactId>afc</artifactId>
+		<groupId>org.arakhne.afc</groupId>
+		<version>4.3-SNAPSHOT</version>
+		<relativePath>../../pom.xml</relativePath>
+	</parent>
+
+	<artifactId>arakhneVmutils-java</artifactId>
+	<packaging>jar</packaging>
+	<version>7.0-SNAPSHOT</version>
+	<name>VM Utilities</name>
+	<url>http://www.arakhne.org/arakhneVmutils/</url>
+
+	<properties>
+		<manifest.file>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifest.file>
+	</properties>
+
+	<!-- ======================================= -->
+	<!-- ==== Project Information === -->
+	<!-- ======================================= -->
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<extensions>true</extensions>
+				<executions>
+					<execution>
+						<id>bundle-manifest</id>
+						<phase>process-classes</phase>
+						<goals>
+							<goal>manifest</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+
+					<supportedProjectTypes>
+						<supportedProjectType>jar</supportedProjectType>
+						<supportedProjectType>bundle</supportedProjectType>
+						<supportedProjectType>war</supportedProjectType>
+					</supportedProjectTypes>
+
+					<archive>
+						<manifestFile>${manifest.file}</manifestFile>
+						<manifest>
+							<mainClass>org.arakhne.vmutil.OperatingSystemInfo</mainClass>
+						</manifest>
+					</archive>
+
+					<instructions>
+						<Export-Package>org.arakhne.vmutil.*;version=${project.version}</Export-Package>
+						<Bundle-Name>arakhneVmutils</Bundle-Name>
+						<Bundle-SymbolicName>org.arakhne.afc.arakhneVmutils</Bundle-SymbolicName>
+						<Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
+						<Import-Package>
+							!sun.reflect,!sun.misc,!sun,*;resolution:=optional
+						</Import-Package>
+						<Embed-Dependency>*;scope=compile|runtime;inline=false</Embed-Dependency>
+					</instructions>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifestFile>${manifest.file}</manifestFile>
+						<manifest>
+							<mainClass>org.arakhne.vmutil.OperatingSystemInfo</mainClass>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<phase>verify</phase>
+						<goals>
+							<goal>jar-no-fork</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.arakhne.afc</groupId>
+				<artifactId>tag-replacer</artifactId>
+				<executions>
+					<execution>
+						<id>property_preparation</id>
+						<phase>process-resources</phase>
+						<goals>
+							<goal>replaceresource</goal>
+						</goals>
+					</execution>
+					<execution>
+						<id>source_generation</id>
+						<phase>pre-integration-test</phase>
+						<goals>
+							<goal>generatereplacesrc</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<projectGroupId>${project.groupId}</projectGroupId>
+					<projectArtifactId>arakhneVmutils</projectArtifactId>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.arakhne.afc</groupId>
+				<artifactId>license-installer</artifactId>
+				<executions>
+					<execution>
+						<phase>compile</phase>
+						<goals>
+							<goal>installlicense</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<name>${project.name}</name>
+					<licenses>
+						<param>lgplv3</param>
+					</licenses>
+					<copyrightDates>${project.inceptionYear}-${year}</copyrightDates>
+					<copyrighters>Arakhn&amp;ecirc;.org Consortium</copyrighters>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-deploy-plugin</artifactId>
+				<configuration>
+					<skip>true</skip>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+
+	<!-- ======================================== -->
+	<!-- ==== Project Dependencies === -->
+	<!-- ======================================== -->
+
+
+	<dependencies>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.osgi.core</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.main</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+	</dependencies>
+
+</project>


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/pom.xml
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AbstractOperatingSystemWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AbstractOperatingSystemWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AbstractOperatingSystemWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,119 @@
+/* 
+  * $Id$
+ * 
+ * Copyright (C) 2004-2009 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.InputStream;
+import java.util.regex.Pattern;
+
+/**
+ * Wrapper to the OS dependent functions.
+ * This class was introduced to avoid to kill the current
+ * JVM even if the native functions are unloadable.
+ * In this way, on operating system without the support
+ * for the native libs is still able to be run. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.3
+ */
+abstract class AbstractOperatingSystemWrapper implements OperatingSystemWrapper {
+
+	/**
+	 */
+	public AbstractOperatingSystemWrapper() {
+		//
+	}
+	
+	/** Run a shell command.
+	 * 
+	 * @param command is the sheel command.
+	 * @return the standard output
+	 */
+	protected static String runCommand(String... command) {
+		try {
+			Process p = Runtime.getRuntime().exec(command);
+			if (p==null) return null;
+			StringBuilder bStr = new StringBuilder();
+			try (InputStream standardOutput = p.getInputStream()) {
+				byte[] buffer = new byte[4086];
+				int len;
+				while ((len=standardOutput.read(buffer))>0) {
+					bStr.append(new String(buffer, 0, len));
+				}
+				p.waitFor();
+				return bStr.toString();
+			}
+		}
+		catch (Exception e) {
+			return null;
+		}
+	}
+	
+	/** Replies the first line that contains the given selector.
+	 * 
+	 * @param selector is the string to search for.
+	 * @param text is the text to search in.
+	 * @return the found line or <code>null</code>.
+	 */
+	protected static String grep(String selector, String text) {
+		if (text==null || text.isEmpty()) return null;
+		StringBuilder line = new StringBuilder();
+		char c;
+		String s;
+		for(int i=0; i<text.length(); ++i) {
+			c = text.charAt(i);
+			if (c=='\n' || c=='\r') {
+				s = line.toString();
+				if (s.contains(selector)) return s;
+				line.setLength(0);
+			}
+			else {
+				line.append(c);
+			}
+		}
+		if (line.length()>0) {
+			s = line.toString();
+			if (s.contains(selector)) return s;
+		}
+		return null;
+	}
+
+	/** Cut the line in columns and replies the given column.
+	 * 
+	 * @param delimiter is the delmiter to use to cut.
+	 * @param column is the number of the column to reply.
+	 * @param lineText is the line to cut.
+	 * @return the column or <code>null</code>.
+	 */
+	protected static String cut(String delimiter, int column, String lineText) {
+		if (lineText==null || lineText.isEmpty()) return null;
+		String[] columns = lineText.split(Pattern.quote(delimiter));
+		if (columns!=null && column>=0 && column<columns.length) {
+			return columns[column].trim();
+		}
+		return null;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AbstractOperatingSystemWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Android.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Android.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Android.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,312 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+
+/**
+ * This class stores several information given by
+ * the Android operating systems.
+ * The stored informations are used by the arakhneVmutil
+ * tools to proceed several tasks, such as {@link OperatingSystem}. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 7.0
+ */
+public class Android {
+
+	/** Name of the home directory.
+	 */
+	public static final String HOME_DIRECTORY = "sdcard"; //$NON-NLS-1$
+
+	/** Name of the system-wide configuration directory.
+	 */
+	public static final String CONFIGURATION_DIRECTORY = "config"; //$NON-NLS-1$
+
+	/** Name of the system-wide data directory.
+	 */
+	public static final String DATA_DIRECTORY = "data"; //$NON-NLS-1$
+
+	private static SoftReference<Object> context = null;
+	private static WeakReference<Object> contextResolver = null;
+	private static WeakReference<ClassLoader> contextClassLoader = null;
+
+	/**
+	 */
+	private Android() {
+		//
+	}
+
+	/** Make a valid android application name from the given application name.
+	 * A valid android application name is a package name followed by the name
+	 * of the application.
+	 * 
+	 * @param applicationName is the simple application name.
+	 * @return the android application name.
+	 */
+	public static String makeAndroidApplicationName(String applicationName) {
+		String fullName;
+		if (applicationName.indexOf('.')>=0) {
+			fullName = applicationName;
+		}
+		else {
+			fullName = "org.arakhne.partnership."+applicationName; //$NON-NLS-1$
+		}
+		return fullName;
+	}
+
+	/** Replies the class {@code Context} from Android.
+	 * 
+	 * @return the class {@code Context} from Android.
+	 * @throws AndroidException when the class cannot be found.
+	 */
+	public static Class<?> getContextClass() throws AndroidException {
+		try {
+			ClassLoader loader = ClassLoaderFinder.findClassLoader();
+			return Class.forName("android.content.Context", true, loader); //$NON-NLS-1$
+		}
+		catch(Throwable e) {
+			throw new AndroidException(e);
+		}
+	}
+
+	/** Replies the class {@code ContextResolver} from Android.
+	 * 
+	 * @return the class {@code ContextResolver} from Android.
+	 * @throws AndroidException when the class cannot be found.
+	 */
+	public static Class<?> getContextResolverClass() throws AndroidException {
+		try {
+			ClassLoader loader = ClassLoaderFinder.findClassLoader();
+			return Class.forName("android.content.ContentResolver", true, loader); //$NON-NLS-1$
+		}
+		catch(Throwable e) {
+			throw new AndroidException(e);
+		}
+	}
+
+	private static Class<?> getInnerClass(String enclosingClassname, String innerClassname) throws AndroidException {
+		ClassLoader loader = ClassLoaderFinder.findClassLoader();
+		Throwable ex = null;
+		try {
+			Class<?> innerClass = Class.forName(
+					enclosingClassname + "$" + innerClassname, //$NON-NLS-1$
+					true, loader);
+			return innerClass;
+		}
+		catch(Throwable e) {
+			ex = e;
+		}
+		try {
+			Class<?> enclosingClass = Class.forName(enclosingClassname, true, loader);
+			for(Class<?> innerClass : enclosingClass.getClasses()) {
+				if (innerClassname.equals(innerClass.getName())) {
+					return innerClass;
+				}
+			}
+		}
+		catch(Throwable _) {
+			//
+		}
+		throw new AndroidException(ex);
+	}
+
+	/** Replies the class {@code Secure} from Android.
+	 * 
+	 * @return the class {@code Secure} from Android.
+	 * @throws AndroidException when the class cannot be found.
+	 */
+	public static Class<?> getSecureSettingsClass() throws AndroidException {
+		return getInnerClass(
+				"android.provider.Settings", //$NON-NLS-1$
+				"Secure"); //$NON-NLS-1$
+	}
+
+	/** Replies the class {@code Secure} from Android.
+	 * 
+	 * @return the class {@code Secure} from Android.
+	 * @throws AndroidException when the class cannot be found.
+	 */
+	public static Class<?> getSystemSettingsClass() throws AndroidException {
+		return getInnerClass(
+				"android.provider.Settings", //$NON-NLS-1$
+				"System"); //$NON-NLS-1$
+	}
+
+	/** Extract informations from the current {@code Context} of the android task.
+	 * 
+	 * @param androidContext is the Android {@code Context}.
+	 * @throws AndroidException when the information cannot be extracted.
+	 */
+	public static void initialize(Object androidContext) throws AndroidException {
+		assert(androidContext!=null);
+		try {
+			Class<?> contextType = androidContext.getClass();
+			Class<?> contextClass = getContextClass();
+			if (!contextClass.isAssignableFrom(contextType))
+				throw new AndroidException("not an Android Context class"); //$NON-NLS-1$
+			synchronized(Android.class) {
+				contextResolver = null;
+				context = new SoftReference<>(androidContext);
+			}
+		}
+		catch(AssertionError e) {
+			throw e;
+		}
+		catch(Throwable e) {
+			throw new AndroidException(e);
+		}
+		ClassLoaderFinder.setPreferredClassLoader(getContextClassLoader());
+	}
+
+	/** Replies the current {@code Context} for the android task.
+	 * 
+	 * @return the current {@code Context} for the android task.
+	 * @throws AndroidException when the context is <code>null</code>.
+	 * @see #initialize(Object)
+	 */
+	public static Object getContext() throws AndroidException {
+		Object c;
+		synchronized(Android.class) {
+			if (context==null) throw new AndroidException();
+			c = context.get();
+		}
+		if (c==null) throw new AndroidException();
+		return c;
+	}
+
+	/** Replies the class loader of the current Android context.
+	 * 
+	 * @return class loader used by the current Android context.
+	 * @throws AndroidException when the context is <code>null</code>.
+	 * @see #initialize(Object)
+	 */
+	public static ClassLoader getContextClassLoader() throws AndroidException {
+		ClassLoader cl;
+		synchronized(Android.class) {
+			cl = (contextClassLoader==null) ? null : contextClassLoader.get();
+		}
+		if (cl==null) {
+			Object context = getContext();
+			try {
+				Method method = context.getClass().getMethod("getClassLoader"); //$NON-NLS-1$
+				Object classLoader = method.invoke(context);
+				if (classLoader instanceof ClassLoader) {
+					cl = (ClassLoader)classLoader;
+					synchronized(Android.class) {
+						contextClassLoader = new WeakReference<>(cl);
+					}
+				}
+				else {
+					throw new AndroidException();
+				}
+			}
+			catch (Throwable e) {
+				throw new AndroidException(e);
+			}
+		}
+		return cl;
+	}
+
+	/** Replies the current {@code ContextResolver} for the android task.
+	 * 
+	 * @return the current {@code ContextResolver} for the android task.
+	 * @throws AndroidException when the context is <code>null</code>.
+	 * @see #initialize
+	 */
+	public static Object getContextResolver() throws AndroidException {
+		Object resolver;
+		synchronized(Android.class) {
+			resolver = (contextResolver==null) ? null : contextResolver.get();
+		}
+		if (resolver==null) {
+			Object context = getContext();
+			try {
+				Class<?> resolverType = getContextResolverClass();
+				Class<?> contextType = context.getClass();
+				Method getContextResolverMethod = contextType.getMethod("getContentResolver"); //$NON-NLS-1$
+				resolver = getContextResolverMethod.invoke(context);
+				resolver = resolverType.cast(resolver);
+				synchronized(Android.class) {
+					contextResolver = new WeakReference<>(resolver);
+				}
+			}
+			catch(AssertionError e) {
+				throw e;
+			}
+			catch(Throwable e) {
+				throw new AndroidException(e);
+			}
+		}
+		return resolver;
+	}
+
+	/**
+	 * This exception is thrown when the {@link Android} attributes
+	 * are not correctly initialized.
+	 *
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 * @since 7.0
+	 */
+	public static class AndroidException extends Exception {
+
+		private static final long serialVersionUID = 1521675695582278476L;
+
+		/**
+		 */
+		public AndroidException() {
+			//
+		}
+
+		/**
+		 * @param message is the error message.
+		 */
+		public AndroidException(String message) {
+			super(message);
+		}
+
+		/**
+		 * @param exception is the cause of this exception.
+		 */
+		public AndroidException(Throwable exception) {
+			super(exception);
+		}
+
+		/**
+		 * @param message is the error message.
+		 * @param exception is the cause of this exception.
+		 */
+		public AndroidException(String message, Throwable exception) {
+			super(message, exception);
+		}
+
+	} // class AndroidException
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Android.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AndroidResourceWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AndroidResourceWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AndroidResourceWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,99 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.arakhne.vmutil.Android.AndroidException;
+
+/**
+ * This interface provides the Android implementation to load resources.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 7.0
+ */
+class AndroidResourceWrapper implements ResourceWrapper {
+
+	private static String decodeResourceName(String resourceName) {
+		if (resourceName.startsWith("/")) { //$NON-NLS-1$
+			return resourceName.substring(1);
+		}
+		return resourceName;
+	}
+	
+	/**
+	 */
+	public AndroidResourceWrapper() {
+		//
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public URL getResource(ClassLoader classLoader, String path) {
+		String resourceName = decodeResourceName(path);
+		ClassLoader androidClassLoader;
+		try {
+			androidClassLoader = Android.getContextClassLoader();
+			assert(androidClassLoader!=null);
+			URL url = androidClassLoader.getResource(resourceName);
+			if (url!=null) return url;
+		}
+		catch (AndroidException e) {
+			//
+		}
+		return classLoader.getResource(resourceName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public InputStream getResourceAsStream(ClassLoader classLoader, String path) {
+		String resourceName = decodeResourceName(path);
+		ClassLoader androidClassLoader;
+		try {
+			androidClassLoader = Android.getContextClassLoader();
+			assert(androidClassLoader!=null);
+			InputStream stream = androidClassLoader.getResourceAsStream(resourceName);
+			if (stream!=null) return stream;
+		}
+		catch (AndroidException e) {
+			//
+		}
+		return classLoader.getResourceAsStream(resourceName);
+    }
+    
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+    public String translateResourceName(String resourceName) {
+		return resourceName.replaceAll("[.]", "/");  //$NON-NLS-1$//$NON-NLS-2$
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/AndroidResourceWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Caller.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Caller.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Caller.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,183 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2008, 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.lang.reflect.Method;
+
+import org.arakhne.vmutil.caller.StackTraceCaller;
+import org.arakhne.vmutil.caller.SunCaller;
+
+/**
+ * This utility class provides a way to determine which class
+ * call a function.
+ * <p>
+ * It inspirated from the Sun's <code>sun.reflect.Reflection</code> class
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class Caller {
+	
+	private static org.arakhne.vmutil.caller.Caller caller = null;
+
+	/** Replies the stack trace mamager used by this utility
+	 * class.
+	 * 
+	 * @return the stack trace mamager.
+	 */
+	public static org.arakhne.vmutil.caller.Caller getCaller() {
+		synchronized(Caller.class) {
+			if (caller==null) {
+				if (StackTraceCaller.loadClass("sun.reflect.Reflection")!=null) { //$NON-NLS-1$
+					caller = new SunCaller();
+				}
+				else {
+					caller = new StackTraceCaller();
+				}
+			}
+			return caller;
+		}
+	}
+	
+	/** Replies the method of the caller that invoked the function
+	 * from which <code>getCallerMethod()</code> was invoked.
+	 * <p>
+	 * The returned value is the name of the method instead of a
+	 * {@link Method} instance. It is due to JRE that does not
+	 * store in the stack trace the complete prototype of the
+	 * methods. So the following code failed: the stack contains
+	 * the method name "test2", but no function has the prototype
+	 * {@code void test2()}.
+	 * <pre>
+	 * class Test {
+	 *     public void test1(int a) {
+	 *         test2();
+	 *     }
+	 *     public void test2(int a) {
+	 *     	   getCallerMethod(); // IllegalArgumentException because test1() not defined.
+	 *     }
+	 * }
+	 * </pre>
+	 * Another failure example: 
+	 * <pre>
+	 * class Test2 {
+	 *     public void test1(int a) {
+	 *         test2();
+	 *     }
+	 *     public void test1() {
+	 *     }
+	 *     public void test2(int a) {
+	 *     	   getCallerMethod(); // test1() is replied !!! not test1(int)
+	 *     }
+	 * }
+	 * </pre>
+	 * 
+	 * @return the method of the caller that invoked the function
+	 * from which <code>getCallerMethod()</code> was invoked.
+	 */
+	public static String getCallerMethod() {
+    	return getCaller().getCallerMethod(2);
+	}
+
+	/** Replies the class of the caller that invoked the function
+	 * from which <code>getCallerClass()</code> was invoked.
+	 * 
+	 * @return the class of the caller that invoked the function
+	 * from which <code>getCallerClass()</code> was invoked.
+	 */
+	public static Class<?> getCallerClass() {
+    	return getCaller().getCallerClass(2);
+	}
+	
+	/** Replies the class from the stack according to its level.
+	 * <p>
+	 * The given <var>level</var> permits to specify which class to reply:
+	 * <ul>
+	 * <li><code>0</code>: the class where is defined the function (<code>f<sub>0</sub></code>) 
+	 * that has called <code>getCallerClass()</code></li>
+	 * <li><code>1</code>: the class where is defined the function (<code>f<sub>1</sub></code>) 
+	 * that has called <code>f<sub>0</sub></code></li>
+	 * <li><code>2</code>: the class where is defined the function (<code>f<sub>2</sub></code>) 
+	 * that has called <code>f<sub>1</sub></code></li>
+	 * <li>etc.</li>
+	 * </ul>
+	 * 
+	 * @param level is the desired level of the class
+	 * @return the class from the call stack according to the given level.
+	 */
+	public static Class<?> getCallerClass(int level) {
+    	return getCaller().getCallerClass(level+1);
+	}
+
+	/** Replies the method from the stack according to its level.
+	 * <p>
+	 * The given <var>level</var> permits to specify which method to reply:
+	 * <ul>
+	 * <li><code>0</code>: the method where is defined the function (<code>f<sub>0</sub></code>) 
+	 * that has called <code>getCallerClass()</code></li>
+	 * <li><code>1</code>: the method where is defined the function (<code>f<sub>1</sub></code>) 
+	 * that has called <code>f<sub>0</sub></code></li>
+	 * <li><code>2</code>: the method where is defined the function (<code>f<sub>2</sub></code>) 
+	 * that has called <code>f<sub>1</sub></code></li>
+	 * <li>etc.</li>
+	 * </ul>
+	 * <p>
+	 * The returned value is the name of the method instead of a
+	 * {@link Method} instance. It is due to JRE that does not
+	 * store in the stack trace the complete prototype of the
+	 * methods. So the following code failed: the stack contains
+	 * the method name "test2", but no function has the prototype
+	 * {@code void test2()}.
+	 * <pre>
+	 * class Test {
+	 *     public void test1(int a) {
+	 *         test2();
+	 *     }
+	 *     public void test2(int a) {
+	 *     	   getCallerMethod(); // IllegalArgumentException because test1() not defined.
+	 *     }
+	 * }
+	 * </pre>
+	 * Another failure example: 
+	 * <pre>
+	 * class Test2 {
+	 *     public void test1(int a) {
+	 *         test2();
+	 *     }
+	 *     public void test1() {
+	 *     }
+	 *     public void test2(int a) {
+	 *     	   getCallerMethod(); // test1() is replied !!! not test1(int)
+	 *     }
+	 * }
+	 * </pre>
+	 * 
+	 * @param level is the desired level of the class
+	 * @return the method from the call stack according to the given level.
+	 */
+	public static String getCallerMethod(int level) {
+    	return getCaller().getCallerMethod(level+1);
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Caller.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassComparator.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassComparator.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassComparator.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,64 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.util.Comparator;
+
+/**
+ * This comparator permits to compare two class objects.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 7.0
+ */
+public class ClassComparator implements Comparator<Class<?>> {
+
+	/**
+	 * Singleton of a class comparator.
+	 */
+	public static final ClassComparator SINGLETON = new ClassComparator();
+	
+	/**
+	 */
+	protected ClassComparator() {
+		//
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int compare(Class<?> o1, Class<?> o2) {
+		if (o1==o2) return 0;
+		if (o1==null) return Integer.MIN_VALUE;
+		if (o2==null) return Integer.MAX_VALUE;
+		String n1 = o1.getCanonicalName();
+		String n2 = o2.getCanonicalName();
+		if (n1==n2) return 0;
+		if (n1==null) return Integer.MIN_VALUE;
+		if (n2==null) return Integer.MAX_VALUE;
+		return n1.compareTo(n2);
+	}
+	
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,103 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2008 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+/**
+ * This utility class permits to find the better class loader
+ * for your application.
+ * <p>
+ * It tries to find the preferred class loader registered with
+ * {@link #setPreferredClassLoader(ClassLoader)}.
+ * If none was found, the default class loader will be replied.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public final class ClassLoaderFinder {
+
+	private static volatile ClassLoader dynamicLoader = null;
+	
+    /**
+     * Replies the better class loader.
+	 * <p>
+	 * It tries to find the preferred class loader.
+	 * If none was found, the default class loader will be replied.
+	 * 
+     * @return the class loader, never <code>null</code>
+     */
+    public static ClassLoader findClassLoader() {
+
+    	if (dynamicLoader==null)
+    		return ClassLoaderFinder.class.getClassLoader();
+    	return dynamicLoader;
+    }
+
+    /**
+     * Set the preferred class loader.
+	 * 
+     * @param class_loader is the preferred class loader
+     */
+    public static void setPreferredClassLoader(ClassLoader class_loader) {
+    	if (class_loader!=dynamicLoader) {
+	    	dynamicLoader = class_loader;
+	    	Thread[] threads = new Thread[Thread.activeCount()];
+	    	Thread.enumerate(threads);
+	    	for(Thread t : threads) {
+	    		if (t!=null)
+	    			t.setContextClassLoader(class_loader);
+	    	}
+    	}
+    }
+    
+    /**
+     * Pop the preferred class loader.
+     */
+    public static void popPreferredClassLoader() {
+    	ClassLoader sysLoader = ClassLoaderFinder.class.getClassLoader();
+    	
+    	if ((dynamicLoader==null)||
+    		(dynamicLoader==sysLoader)) {
+    		dynamicLoader = null;
+	    	Thread[] threads = new Thread[Thread.activeCount()];
+	    	Thread.enumerate(threads);
+	    	for(Thread t : threads) {
+	    		if (t!=null)
+	    			t.setContextClassLoader(sysLoader);
+	    	}
+    		return;
+    	}
+    	
+    	ClassLoader parent = dynamicLoader.getParent();
+    	
+    	dynamicLoader = (parent==sysLoader) ? null : parent;    	
+
+    	Thread[] threads = new Thread[Thread.activeCount()];
+    	Thread.enumerate(threads);
+    	for(Thread t : threads) {
+    		if (t!=null)
+    			t.setContextClassLoader(parent);
+    	}
+    }
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClassLoaderFinder.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClasspathUtil.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClasspathUtil.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClasspathUtil.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,312 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2010 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Current classpath and associated utility functions.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.0
+ */
+public class ClasspathUtil {
+
+	/** Replies the classpath at start of the virtual machine.
+	 * 
+	 * @return the startup classpath, never <code>null</code>.
+	 * @deprecated see {@link #getStartClasspath()}
+	 */
+	@Deprecated
+	public static URL[] getStartupClasspath() {
+		Iterator<URL> iterator = getStartClasspath();
+		List<URL> list = new ArrayList<>();
+		while (iterator.hasNext())
+			list.add(iterator.next());
+		URL[] tab = new URL[list.size()];
+		list.toArray(tab);
+		list.clear();
+		return tab;
+	}
+
+	/** Replies the classpath at start of the virtual machine.
+	 * 
+	 * @return the startup classpath, never <code>null</code>.
+	 * @since 6.0
+	 */
+	public static Iterator<URL> getStartClasspath() {
+		return new PathIterator(System.getProperty("java.class.path")); //$NON-NLS-1$
+	}
+
+	/** Replies the current classpath.
+	 * 
+	 * @return the current classpath, never <code>null</code>.
+	 * @deprecated see {@link #getClasspath()}
+	 */
+	@Deprecated
+	public static URL[] getCurrentClasspath() {
+		Iterator<URL> iterator = getClasspath();
+		List<URL> list = new ArrayList<>();
+		while (iterator.hasNext())
+			list.add(iterator.next());
+		URL[] tab = new URL[list.size()];
+		list.toArray(tab);
+		list.clear();
+		return tab;
+	}
+	
+	/** Replies the current classpath.
+	 * 
+	 * @return the current classpath, never <code>null</code>.
+	 * @since 6.0
+	 */
+	@SuppressWarnings("resource")
+	public static Iterator<URL> getClasspath() {
+		Iterator<URL> iterator = getStartClasspath();
+		
+		ClassLoader loader = ClassLoaderFinder.findClassLoader();
+		if (loader instanceof DynamicURLClassLoader) {
+			DynamicURLClassLoader dLoader = (DynamicURLClassLoader)loader;
+			iterator = new IteratorIterator(
+					new FilteringIterator(Arrays.asList(dLoader.getURLs()).iterator()),
+					iterator);
+		}
+		else if (loader instanceof URLClassLoader) {
+			URLClassLoader dLoader = (URLClassLoader)loader;
+			iterator = new IteratorIterator(
+					new FilteringIterator(Arrays.asList(dLoader.getURLs()).iterator()),
+					iterator);
+		}
+		
+		return iterator;
+	}
+	
+	/**
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 * @since 6.0
+	 */
+	private static class IteratorIterator implements Iterator<URL> {
+		
+		private final Iterator<URL> i1;
+		private final Iterator<URL> i2;
+		
+		/**
+		 * @param i1
+		 * @param i2
+		 */
+		public IteratorIterator(Iterator<URL> i1, Iterator<URL> i2) {
+			assert(i1!=null && i2!=null);
+			this.i1 = i1;
+			this.i2 = i2;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public boolean hasNext() {
+			return (this.i1.hasNext() || this.i2.hasNext());
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public URL next() {
+			if (this.i1.hasNext())
+				return this.i1.next();
+			return this.i2.next();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+		
+	}
+
+	/**
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 * @since 6.0
+	 */
+	private static class FilteringIterator implements Iterator<URL> {
+		
+		private final Iterator<URL> iterator;
+		private URL next;
+		
+		/**
+		 * @param iterator
+		 */
+		public FilteringIterator(Iterator<URL> iterator) {
+			assert(iterator!=null);
+			this.iterator = iterator;
+			searchNext();
+		}
+		
+		private void searchNext() {
+			this.next = null;
+			URL u;
+			while (this.next==null && this.iterator.hasNext()) {
+				u = this.iterator.next();
+				if (u!=null) {
+					this.next = u;
+				}
+			}
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public boolean hasNext() {
+			return this.next!=null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public URL next() {
+			URL n = this.next;
+			if (n==null) throw new NoSuchElementException();
+			searchNext();
+			return n;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+		
+	}
+
+	/**
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 * @since 6.0
+	 */
+	private static class PathIterator implements Iterator<URL> {
+		
+		private String path;
+		private URL next;
+		private int nextIndex;
+		
+		/**
+		 * @param path
+		 */
+		public PathIterator(String path) {
+			this.path = path;
+			this.nextIndex = -1;
+			searchNext();
+		}
+		
+		private void searchNext() {
+			String p;
+			int index;
+			URL url;
+			
+			this.next = null;
+			
+			while (this.next==null && this.path!=null && this.nextIndex<this.path.length()) {
+				index = this.path.indexOf(File.pathSeparatorChar, this.nextIndex + 1);
+				
+				if (index>this.nextIndex+1) {
+					p = this.path.substring(this.nextIndex+1, index);
+				}
+				else {
+					p = this.path.substring(this.nextIndex+1);
+					this.path = null; // no more element
+				}
+
+				this.nextIndex = index;
+
+				if (p!=null && !"".equals(p)) { //$NON-NLS-1$
+					try {
+						url = FileSystem.convertStringToURL(p, false, true, false);
+						if (url!=null) {
+							this.next = url;
+						}
+					}
+					catch(AssertionError e) {
+						throw e;
+					}
+					catch(Throwable e) {
+						//
+					}
+				}
+			}
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public boolean hasNext() {
+			return this.next!=null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public URL next() {
+			URL n = this.next;
+			if (n==null) throw new NoSuchElementException();
+			searchNext();
+			return n;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+		
+	}
+	
+}
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ClasspathUtil.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,597 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2008 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureClassLoader;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes.Name;
+import java.util.regex.Pattern;
+
+import sun.misc.Resource;
+import sun.misc.URLClassPath;
+import sun.net.www.ParseUtil;
+import sun.security.util.SecurityConstants;
+
+/** This class loader permits to load classes from
+ * a set of classpaths.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+@SuppressWarnings("restriction")
+public class DynamicURLClassLoader extends SecureClassLoader {
+
+	/**
+	 * The search path for classes and resources.
+	 */
+	protected URLClassPath _ucp;
+	
+	/**
+	 * The context to be used when loading classes and resources
+	 */
+	protected AccessControlContext _acc;
+	
+	/**
+	 * Constructs a new ClassPathClassLoader for the given URLs. The URLs will be
+	 * searched in the order specified for classes and resources after first
+	 * searching in the specified parent class loader. Any URL that ends with
+	 * a '/' is assumed to refer to a directory. Otherwise, the URL is assumed
+	 * to refer to a JAR file which will be downloaded and opened as needed.
+	 *
+	 * <p>If there is a security manager, this method first
+	 * calls the security manager's <code>checkCreateClassLoader</code> method
+	 * to ensure creation of a class loader is allowed.
+	 * 
+	 * @param parent the parent class loader for delegation
+	 * @param acc is the current access context
+	 * @param urls the URLs from which to load classes and resources
+	 * @exception  SecurityException  if a security manager exists and its  
+	 *             <code>checkCreateClassLoader</code> method doesn't allow 
+	 *             creation of a class loader.
+	 * @see SecurityManager#checkCreateClassLoader
+	 */
+	protected DynamicURLClassLoader(ClassLoader parent, AccessControlContext acc, URL... urls) {
+		super(parent);
+		// this is to make the stack depth consistent with 1.1
+		SecurityManager security = System.getSecurityManager();
+		if (security != null) {
+			security.checkCreateClassLoader();
+		}
+		this._ucp = new URLClassPath(mergeClassPath(urls));
+		this._acc = acc;
+	}
+	
+	/**
+	 * Appends the specified URL to the list of URLs to search for
+	 * classes and resources.
+	 *
+	 * @param url the URL to be added to the search path of URLs
+	 */
+	public void addURL(final URL url) {
+		AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			@Override
+			public Object run() {
+				DynamicURLClassLoader.this._ucp.addURL(url);
+				return null;
+			}
+		}, this._acc);
+	}
+	
+	/**
+	 * Appends the specified URL to the list of URLs to search for
+	 * classes and resources.
+	 *
+	 * @param urls the URLs to be added to the search path of URLs
+	 */
+	public void addURLs(URL... urls) {
+		for (URL url : urls) {
+			addURL(url);
+		}
+	}
+
+	/**
+	 * Appends the specified URL to the list of URLs to search for
+	 * classes and resources.
+	 *
+	 * @param urls the URL to be added to the search path of URLs
+	 */
+	public void removeURLs(URL... urls) {
+		HashSet<URL> set = new HashSet<>();
+		set.addAll(Arrays.asList(this._ucp.getURLs()));
+		set.removeAll(Arrays.asList(urls));
+		URL[] tab = new URL[set.size()];
+		set.toArray(tab);
+		this._ucp = new URLClassPath(tab);
+		tab = null;
+	}
+
+	/**
+	 * Appends the specified URL to the list of URLs to search for
+	 * classes and resources.
+	 *
+	 * @param url the URL to be added to the search path of URLs
+	 */
+	public void removeURL(URL url) {
+		removeURLs(url);
+	}
+
+	/**
+	 * Returns the search path of URLs for loading classes and resources.
+	 * This includes the original list of URLs specified to the constructor,
+	 * along with any URLs subsequently appended by the addURL() method.
+	 * @return the search path of URLs for loading classes and resources.
+	 */
+	public URL[] getURLs() {
+		return this._ucp.getURLs();
+	}
+	
+	/**
+	 * Finds and loads the class with the specified name from the URL search
+	 * path. Any URLs referring to JAR files are loaded and opened as needed
+	 * until the class is found.
+	 *
+	 * @param name the name of the class
+	 * @return the resulting class
+	 * @exception ClassNotFoundException if the class could not be found
+	 */
+	@Override
+	protected Class<?> findClass(final String name) throws ClassNotFoundException {
+		try {
+			return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
+				@Override
+				public Class<?> run() throws ClassNotFoundException {
+					String path = name.replace('.', '/').concat(".class"); //$NON-NLS-1$
+					Resource res = DynamicURLClassLoader.this._ucp.getResource(path, false);
+					if (res != null) {
+						try {
+							return defineClass(name, res);
+						}
+						catch (IOException e) {
+							throw new ClassNotFoundException(name, e);
+						}
+					}
+					throw new ClassNotFoundException(name);
+				}
+			}, this._acc);
+		}
+		catch (java.security.PrivilegedActionException pae) {
+			throw (ClassNotFoundException) pae.getException();
+		}
+	}
+	
+	/**
+	 * Defines a Class using the class bytes obtained from the specified
+	 * Resource. The resulting Class must be resolved before it can be
+	 * used.
+	 * 
+	 * @param name is the name of the class to define
+	 * @param res is the resource from which the class byte-code could be obtained
+	 * @return the loaded class.
+	 * @throws IOException in case the byte-code was unavailable.
+	 */
+	protected Class<?> defineClass(String name, Resource res) throws IOException {
+		int i = name.lastIndexOf('.');
+		URL url = res.getCodeSourceURL();
+		if (i != -1) {
+			String pkgname = name.substring(0, i);
+			// Check if package already loaded.
+			Package pkg = getPackage(pkgname);
+			Manifest man = res.getManifest();
+			if (pkg != null) {
+				// Package found, so check package sealing.
+				if (pkg.isSealed()) {
+					// Verify that code source URL is the same.
+					if (!pkg.isSealed(url)) {
+						throw new SecurityException(
+								"sealing violation: package " + pkgname + " is sealed"); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+					
+				} else {
+					// Make sure we are not attempting to seal the package
+					// at this code source URL.
+					if ((man != null) && isSealed(pkgname, man)) {
+						throw new SecurityException(
+								"sealing violation: can't seal package " + pkgname +  //$NON-NLS-1$
+						": already loaded"); //$NON-NLS-1$
+					}
+				}
+			} else {
+				if (man != null) {
+					definePackage(pkgname, man, url);
+				} else {
+					definePackage(pkgname, null, null, null, null, null, null, null);
+				}
+			}
+		}
+		// Now read the class bytes and define the class
+		java.nio.ByteBuffer bb = res.getByteBuffer();
+		if (bb != null) {
+			// Use (direct) ByteBuffer:
+			CodeSigner[] signers = res.getCodeSigners();
+			CodeSource cs = new CodeSource(url, signers);
+			return defineClass(name, bb, cs);
+		}
+
+		byte[] b = res.getBytes();
+		// must read certificates AFTER reading bytes.
+		CodeSigner[] signers = res.getCodeSigners();
+		CodeSource cs = new CodeSource(url, signers);
+		return defineClass(name, b, 0, b.length, cs);
+
+	}
+	
+	/**
+	 * Defines a new package by name in this ClassLoader. The attributes
+	 * contained in the specified Manifest will be used to obtain package
+	 * version and sealing information. For sealed packages, the additional
+	 * URL specifies the code source URL from which the package was loaded.
+	 *
+	 * @param name  the package name
+	 * @param man   the Manifest containing package version and sealing
+	 *              information
+	 * @param url   the code source url for the package, or null if none
+	 * @exception   IllegalArgumentException if the package name duplicates
+	 *              an existing package either in this class loader or one
+	 *              of its ancestors
+	 * @return the newly defined Package object
+	 */
+	protected Package definePackage(String name, Manifest man, URL url)
+	throws IllegalArgumentException
+	{
+		String path = name.replace('.', '/').concat("/"); //$NON-NLS-1$
+		String specTitle = null, specVersion = null, specVendor = null;
+		String implTitle = null, implVersion = null, implVendor = null;
+		String sealed = null;
+		URL sealBase = null;
+		
+		Attributes attr = man.getAttributes(path);
+		if (attr != null) {
+			specTitle   = attr.getValue(Name.SPECIFICATION_TITLE);
+			specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+			specVendor  = attr.getValue(Name.SPECIFICATION_VENDOR);
+			implTitle   = attr.getValue(Name.IMPLEMENTATION_TITLE);
+			implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+			implVendor  = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+			sealed      = attr.getValue(Name.SEALED);
+		}
+		attr = man.getMainAttributes();
+		if (attr != null) {
+			if (specTitle == null) {
+				specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+			}
+			if (specVersion == null) {
+				specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+			}
+			if (specVendor == null) {
+				specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+			}
+			if (implTitle == null) {
+				implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+			}
+			if (implVersion == null) {
+				implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+			}
+			if (implVendor == null) {
+				implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+			}
+			if (sealed == null) {
+				sealed = attr.getValue(Name.SEALED);
+			}
+		}
+		if ("true".equalsIgnoreCase(sealed)) { //$NON-NLS-1$
+			sealBase = url;
+		}
+		return definePackage(name, specTitle, specVersion, specVendor,
+				implTitle, implVersion, implVendor, sealBase);
+	}
+	
+	/*
+	 * Returns true if the specified package name is sealed according to the
+	 * given manifest.
+	 */
+	private static boolean isSealed(String name, Manifest man) {
+		String path = name.replace('.', '/').concat("/"); //$NON-NLS-1$
+		Attributes attr = man.getAttributes(path);
+		String sealed = null;
+		if (attr != null) {
+			sealed = attr.getValue(Name.SEALED);
+		}
+		if (sealed == null) {
+			if ((attr = man.getMainAttributes()) != null) {
+				sealed = attr.getValue(Name.SEALED);
+			}
+		}
+		return "true".equalsIgnoreCase(sealed); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Finds the resource with the specified name on the URL search path.
+	 *
+	 * @param name the name of the resource
+	 * @return a <code>URL</code> for the resource, or <code>null</code> 
+	 * if the resource could not be found.
+	 */
+	@Override
+	public URL findResource(final String name) {
+		/*
+		 * The same restriction to finding classes applies to resources
+		 */
+		URL url = 
+			AccessController.doPrivileged(new PrivilegedAction<URL>() {
+				@Override
+				public URL run() {
+					return DynamicURLClassLoader.this._ucp.findResource(name, true);
+				}
+			}, this._acc);
+		
+		return url != null ? this._ucp.checkURL(url) : null;
+	}
+	
+	/**
+	 * Returns an Enumeration of URLs representing all of the resources
+	 * on the URL search path having the specified name.
+	 *
+	 * @param name the resource name
+	 * @exception IOException if an I/O exception occurs
+	 * @return an <code>Enumeration</code> of <code>URL</code>s
+	 */
+	@Override
+	public Enumeration<URL> findResources(final String name) throws IOException {
+		final Enumeration<?> e = this._ucp.findResources(name, true);
+		
+		return new Enumeration<URL>() {
+			private URL url = null;
+			
+			private boolean next() {
+				if (this.url != null) {
+					return true;
+				}
+				do {
+					URL u = AccessController.doPrivileged(new PrivilegedAction<URL>() {
+						@Override
+						public URL run() {
+							if (!e.hasMoreElements())
+								return null;
+							return (URL)e.nextElement();
+						}
+					}, DynamicURLClassLoader.this._acc);
+					if (u == null) break;
+					this.url = DynamicURLClassLoader.this._ucp.checkURL(u);
+				}
+				while (this.url == null);
+				
+				return (this.url != null);
+			}
+			
+			@Override
+			public URL nextElement() {
+				if (!next()) {
+					throw new NoSuchElementException();
+				}
+				URL u = this.url;
+				this.url = null;
+				return u;
+			}
+			
+			@Override
+			public boolean hasMoreElements() {
+				return next();
+			}
+		};
+	}
+	
+	/**
+	 * Returns the permissions for the given codesource object.
+	 * The implementation of this method first calls super.getPermissions
+	 * and then adds permissions based on the URL of the codesource.
+	 * <p>
+	 * If the protocol is "file"
+	 * and the path specifies a file, then permission to read that
+	 * file is granted. If protocol is "file" and the path is
+	 * a directory, permission is granted to read all files
+	 * and (recursively) all files and subdirectories contained in
+	 * that directory.
+	 * <p>
+	 * If the protocol is not "file", then
+	 * to connect to and accept connections from the URL's host is granted.
+	 * @param codesource the codesource
+	 * @return the permissions granted to the codesource
+	 */
+	@Override
+	protected PermissionCollection getPermissions(CodeSource codesource) {
+		PermissionCollection perms = super.getPermissions(codesource);
+		
+		URL url = codesource.getLocation();
+		
+		Permission p;
+		URLConnection urlConnection;
+		
+		try {
+			urlConnection = url.openConnection();
+			p = urlConnection.getPermission();
+		}
+		catch (java.io.IOException ioe) {
+			p = null;
+			urlConnection = null;
+		}
+		
+		if ((p!=null)&&(p instanceof FilePermission)) {
+			// if the permission has a separator char on the end,
+			// it means the codebase is a directory, and we need
+			// to add an additional permission to read recursively
+			String path = p.getName();
+			if (path.endsWith(File.separator)) {
+				path += "-"; //$NON-NLS-1$
+				p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
+			}
+		}
+		else if ((p == null) && (URISchemeType.FILE.isURL(url))) {
+			String path = url.getFile().replace('/', File.separatorChar);
+			path = ParseUtil.decode(path);
+			if (path.endsWith(File.separator))
+				path += "-"; //$NON-NLS-1$
+			p =  new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
+		}
+		else {
+			URL locUrl = url;
+			if (urlConnection instanceof JarURLConnection) {
+				locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
+			}
+			String host = locUrl.getHost();
+			if (host == null)
+				host = "localhost"; //$NON-NLS-1$
+			p = new SocketPermission(host,
+					SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION);
+		}
+		
+		// make sure the person that created this class loader
+		// would have this permission
+		
+		final SecurityManager sm = System.getSecurityManager();
+		if (sm != null) {
+			final Permission fp = p;
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
+				@Override
+				public Object run() throws SecurityException {
+					sm.checkPermission(fp);
+					return null;
+				}
+			}, this._acc);
+		}
+		perms.add(p);
+
+		return perms;
+	}
+	
+	/**
+	 * Creates a new instance of DynamicURLClassLoader for the specified
+	 * URLs and parent class loader. If a security manager is
+	 * installed, the <code>loadClass</code> method of the URLClassLoader
+	 * returned by this method will invoke the
+	 * <code>SecurityManager.checkPackageAccess</code> method before
+	 * loading the class.
+	 *
+	 * @param parent the parent class loader for delegation
+	 * @param urls the URLs to search for classes and resources
+	 * @return the resulting class loader
+	 */
+	public static DynamicURLClassLoader newInstance(final ClassLoader parent, final URL... urls) {
+		// Save the caller's context
+		final AccessControlContext acc = AccessController.getContext();
+		// Need a privileged block to create the class loader
+		DynamicURLClassLoader ucl =
+			AccessController.doPrivileged(new PrivilegedAction<DynamicURLClassLoader>() {
+				@Override
+				public DynamicURLClassLoader run() {
+					// Now set the context on the loader using the one we saved,
+					// not the one inside the privileged block...
+					return new FactoryDynamicURLClassLoader(parent, acc, urls);
+				}
+			});
+		return ucl;
+	}
+	
+    /**
+     * Merge the specified URLs to the current classpath.
+     */
+    private static URL[] mergeClassPath(URL... urls) {
+    	String path = System.getProperty("java.class.path"); //$NON-NLS-1$
+    	String separator = System.getProperty("path.separator"); //$NON-NLS-1$
+    	String[] parts = path.split(Pattern.quote(separator));
+    	URL[] u = new URL[parts.length+urls.length];
+    	for(int i=0; i<parts.length; i++) {
+    		try {
+				u[i] = new File(parts[i]).toURI().toURL();
+			}
+    		catch (MalformedURLException _) {
+				// ignore exception
+			}
+    	}
+    	System.arraycopy(urls,0,u,parts.length,urls.length);
+    	return u;
+    }
+
+    /** 
+     * @author $Author: galland$
+     * @version $FullVersion$
+     * @mavengroupid $GroupId$
+     * @mavenartifactid $ArtifactId$
+     */
+    protected final static class FactoryDynamicURLClassLoader extends DynamicURLClassLoader {
+
+    	/**
+    	 * @param parent is the parent class loader.
+    	 * @param acc is the accessible context.
+    	 * @param urls is the list of urls to insert inside the class loading path.
+    	 */
+    	protected FactoryDynamicURLClassLoader(ClassLoader parent, AccessControlContext acc, URL... urls) {
+    		super(parent,acc,urls);
+    	}
+    	
+    	/** {@inheritDoc}
+    	 * 
+    	 * @param name {@inheritDoc}
+    	 * @param resolve {@inheritDoc}
+    	 * @return {@inheritDoc}
+    	 * @throws ClassNotFoundException {@inheritDoc}
+    	 */
+    	@Override
+    	public final synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+    		// First check if we have permission to access the package. This
+    		// should go away once we've added support for exported packages.
+    		SecurityManager sm = System.getSecurityManager();
+    		if (sm != null) {
+    			int i = name.lastIndexOf('.');
+    			if (i != -1) {
+    				sm.checkPackageAccess(name.substring(0, i));
+    			}
+    		}
+    		return super.loadClass(name, resolve);
+    	}
+    	
+    }
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/DynamicURLClassLoader.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,49 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2010 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.URL;
+
+/**
+ * Indicates that the object implementing this interface
+ * owns a external resource.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 4.2
+ */
+public interface ExternalizableResource {
+
+	/** Replies the URL where the resource data could be find.
+	 * 
+	 * @return the URL to the external resource.
+	 */
+	public URL getExternalizableResourceLocation();
+
+	/** Replies the MIME type of the external resource.
+	 * 
+	 * @return the MIME of the external resource.
+	 */
+	public String getExternalizableResourceType();
+
+}
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ExternalizableResource.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/FileSystem.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/FileSystem.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/FileSystem.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,2993 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/** An utility class that permits to deal with filenames.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class FileSystem {
+
+	static {
+		URLHandlerUtil.installArakhneHandlers();
+
+		String validChars = "[^\\\\/:*?\"<>|]"; //$NON-NLS-1$
+		String bslashChar = "\\\\"; //$NON-NLS-1$
+
+		StringBuilder pattern = new StringBuilder();
+		pattern.append("^"); //$NON-NLS-1$
+		pattern.append("(([a-zA-Z]:"); //$NON-NLS-1$
+		pattern.append(validChars);
+		pattern.append("*)|("); //$NON-NLS-1$
+		pattern.append(validChars);
+		pattern.append("+"); //$NON-NLS-1$
+		pattern.append(bslashChar);
+		pattern.append(validChars);
+		pattern.append("+)|("); //$NON-NLS-1$
+		pattern.append(bslashChar);
+		pattern.append("))?("); //$NON-NLS-1$
+		pattern.append(bslashChar);
+		pattern.append(validChars);
+		pattern.append("*)*"); //$NON-NLS-1$
+		pattern.append("$"); //$NON-NLS-1$
+		//"^([A-Za-z]:)?([^\\\\/:*?\"<>|]*\\\\)*[^\\\\/:*?\"<>|]*$"; //$NON-NLS-1$
+		WINDOW_NATIVE_FILENAME_PATTERN = pattern.toString();
+	}
+
+	/** Regular expression pattern which corresponds to Windows native filename.
+	 */
+	private static final String WINDOW_NATIVE_FILENAME_PATTERN;
+
+	/** Character used to specify a file extension.
+	 */
+	public static final char EXTENSION_SEPARATOR_CHAR = '.';
+
+	/** String which is representing the current directory in a relative path.
+	 */
+	public static final String CURRENT_DIRECTORY = "."; //$NON-NLS-1$
+
+	/** String which is representing the parent directory in a relative path.
+	 */
+	public static final String PARENT_DIRECTORY = ".."; //$NON-NLS-1$
+
+	/** Character used to separate paths on an URL.
+	 */
+	public static final char URL_PATH_SEPARATOR_CHAR = '/';
+
+	/** Character used to separate paths on an URL.
+	 */
+	public static final String URL_PATH_SEPARATOR = "/"; //$NON-NLS-1$
+
+	/** String used to specify a file extension.
+	 */
+	public static final String EXTENSION_SEPARATOR = "."; //$NON-NLS-1$
+
+	/** Prefix used to join in a Jar URL the jar filename and the inside-jar filename.
+	 */
+	public static final String JAR_URL_FILE_ROOT = "!/"; //$NON-NLS-1$
+
+	private static final Random RANDOM = new Random();
+	
+	private static final DeleteOnExitHook deleteOnExitHook = new DeleteOnExitHook();
+	
+	private static Boolean isFileCompatibleWithURL = null;
+
+	/** Replace the HTML entities by the current charset characters.
+	 * 
+	 * @param s
+	 * @return decoded string or <var>s/<var>.
+	 */
+	private static String decodeHTMLEntities(String s) {
+		if (s==null) return null;
+		try {
+			return URLDecoder.decode(s, Charset.defaultCharset().displayName());
+		}
+		catch (UnsupportedEncodingException _) {
+			return s;
+		}
+	}
+	
+	/** Replace the special characters by HTML entities.
+	 * 
+	 * @param s
+	 * @return decoded string or <var>s/<var>.
+	 */
+	private static String encodeHTMLEntities(String s) {
+		if (s==null) return null;
+		try {
+			return URLEncoder.encode(s, Charset.defaultCharset().displayName());
+		}
+		catch (UnsupportedEncodingException _) {
+			return s;
+		}
+	}
+
+	/** Decode the given file to obtain a string representation
+	 * which is compatible with the URL standard.
+	 * This function was introduced to have a work around
+	 * on the '\' character on Windows operating system.
+	 * 
+	 * @since 6.2
+	 */
+	private static String getFilePath(File f) {
+		if (f==null) return null;
+		return getFilePath(f.getPath());
+	}
+
+	/** Decode the given file to obtain a string representation
+	 * which is compatible with the URL standard.
+	 * This function was introduced to have a work around
+	 * on the '\' character on Windows operating system.
+	 * 
+	 * @since 6.2
+	 */
+	private static String getFilePath(String f) {
+		if (f==null) return null;
+		if (isFileCompatibleWithURL==null) {
+			isFileCompatibleWithURL = Boolean.valueOf(
+					URL_PATH_SEPARATOR.equals(File.separator));
+		}
+		String filePath = f;
+		if (!isFileCompatibleWithURL) {
+			filePath = filePath.replaceAll(
+					Pattern.quote(File.separator),
+					Matcher.quoteReplacement(URL_PATH_SEPARATOR));
+		}
+		return filePath;
+	}
+
+	/** Replies if the given URL has a jar scheme.
+	 * 
+	 * @param url
+	 * @return <code>true</code> if the given URL uses a jar scheme.
+	 */
+	public static boolean isJarURL(URL url) {
+		return URISchemeType.JAR.isURL(url);
+	}
+
+	/** Replies the jar part of the jar-scheme URL.
+	 * 
+	 * @param url
+	 * @return the URL of the jar file in the given URL, or <code>null</code>
+	 * if the given URL does not use jar scheme.
+	 */
+	public static URL getJarURL(URL url) {
+		if (!isJarURL(url)) return null;
+		String path = url.getPath();
+		int idx = path.lastIndexOf(JAR_URL_FILE_ROOT);
+		if (idx>=0) path = path.substring(0, idx);
+		try {
+			return new URL(path);
+		}
+		catch(MalformedURLException _) {
+			return null;
+		}
+	}
+
+	/** Replies the file part of the jar-scheme URL.
+	 * 
+	 * @param url
+	 * @return the file in the given URL, or <code>null</code>
+	 * if the given URL does not use jar scheme.
+	 */
+	public static File getJarFile(URL url) {
+		if (isJarURL(url)) {
+			String path = url.getPath();
+			int idx = path.lastIndexOf(JAR_URL_FILE_ROOT);
+			if (idx>=0) return new File(decodeHTMLEntities(path.substring(idx+1)));
+		}
+		return null;
+	}
+
+	/** Replies the jar-schemed URL composed of the two given components.
+	 * 
+	 * @param jarFile is the URL to the jar file.
+	 * @param insideFile is the name of the file inside the jar.
+	 * @return the jar-schemed URL.
+	 * @throws MalformedURLException when the URL is malformed.
+	 */
+	public static URL toJarURL(File jarFile, File insideFile) throws MalformedURLException {
+		if (jarFile==null || insideFile==null) return null;
+		return toJarURL(jarFile, getFilePath(insideFile));
+	}
+
+	/** Replies the jar-schemed URL composed of the two given components.
+	 * 
+	 * @param jarFile is the URL to the jar file.
+	 * @param insideFile is the name of the file inside the jar.
+	 * @return the jar-schemed URL.
+	 * @throws MalformedURLException when the URL is malformed.
+	 */
+	public static URL toJarURL(File jarFile, String insideFile) throws MalformedURLException {
+		return toJarURL(jarFile.toURI().toURL(), insideFile);
+	}
+
+	/** Replies the jar-schemed URL composed of the two given components.
+	 * 
+	 * @param jarFile is the URL to the jar file.
+	 * @param insideFile is the name of the file inside the jar.
+	 * @return the jar-schemed URL.
+	 * @throws MalformedURLException when the URL is malformed.
+	 */
+	public static URL toJarURL(URL jarFile, File insideFile) throws MalformedURLException {
+		if (jarFile==null || insideFile==null) return null;
+		return toJarURL(jarFile, getFilePath(insideFile));
+	}
+
+	/** Replies the jar-schemed URL composed of the two given components.
+	 * 
+	 * @param jarFile is the URL to the jar file.
+	 * @param insideFile is the name of the file inside the jar.
+	 * @return the jar-schemed URL.
+	 * @throws MalformedURLException when the URL is malformed.
+	 */
+	public static URL toJarURL(URL jarFile, String insideFile) throws MalformedURLException {
+		if (jarFile==null || insideFile==null) return null;
+		StringBuilder buf = new StringBuilder();
+		buf.append(jarFile.toExternalForm());
+		buf.append(JAR_URL_FILE_ROOT);
+		String path = getFilePath(insideFile);
+		if (path.startsWith(URL_PATH_SEPARATOR)) {
+			buf.append(path.substring(URL_PATH_SEPARATOR.length()));
+		}
+		else {
+			buf.append(path);
+		}
+		return new URL(URISchemeType.JAR.name(), "", buf.toString()); //$NON-NLS-1$
+	}
+
+	/** Replies if the current operating system uses case-sensitive filename.
+	 * 
+	 * @return <code>true</code> if the filenames on the current file system are case sensitive,
+	 * otherwise <code>false</code>
+	 */
+	public static boolean isCaseSensitiveFilenameSystem() {
+		switch(OperatingSystem.getCurrentOS()) {
+		case AIX:
+		case BSD:
+		case FREEBSD:
+		case NETBSD:
+		case OPENBSD:
+		case LINUX:
+		case SOLARIS:
+		case HPUX:
+			return true;
+		case MACOSX:
+		case WIN:
+		case OTHER:
+		default:
+			return false;
+		}
+	}
+
+	/** Replies the character used to separate the basename and the file extension.
+	 * 
+	 * @return the character used to separate the basename and the file extension.
+	 */
+	public static char getFileExtensionCharacter() {
+		return EXTENSION_SEPARATOR_CHAR;
+	}
+
+	/** Replies the dirname of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the dirname of the specified file.
+	 * @see #shortBasename(File)
+	 * @see #largeBasename(File)
+	 * @see #basename(File)
+	 * @see #extension(File)
+	 */
+	public static URL dirname(File filename) {
+		if (filename==null) return null;
+		String parent = getFilePath(filename.getParent());
+		try {
+			if (parent==null || "".equals(parent)) { //$NON-NLS-1$
+				if (filename.isAbsolute()) return null;
+				return new URL(URISchemeType.FILE.name(), "", CURRENT_DIRECTORY); //$NON-NLS-1$
+			}
+			return new URL(URISchemeType.FILE.name(), "", parent); //$NON-NLS-1$
+		}
+		catch(MalformedURLException _) {
+			return null;
+		}
+	}
+
+	/** Replies the dirname of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the dirname of the specified file.
+	 * @see #shortBasename(URL)
+	 * @see #largeBasename(URL)
+	 * @see #basename(URL)
+	 * @see #extension(URL)
+	 */
+	public static URL dirname(URL filename) {
+		if (filename==null) return null;
+
+		URL prefix = null;
+		String path;
+		if (isJarURL(filename)) {
+			prefix = getJarURL(filename);
+			path = getFilePath(getJarFile(filename));
+		}
+		else
+			path = filename.getPath();
+
+		if ("".equals(path)) return null; //$NON-NLS-1$
+
+		int idx = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR);
+		if (idx==path.length()-1)
+			idx = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR, path.length()-2);
+
+		if (idx<0) {
+			if (URISchemeType.getSchemeType(filename).isFileBasedScheme())
+				path = CURRENT_DIRECTORY;
+			else
+				path = URL_PATH_SEPARATOR;
+		}
+		else {
+			path = path.substring(0, idx+1);
+		}
+
+		try {
+			if (prefix!=null) {
+				return toJarURL(prefix, path);
+			}
+			URI uri = new URI(
+					filename.getProtocol(), 
+					filename.getUserInfo(), 
+					filename.getHost(), 
+					filename.getPort(), 
+					decodeHTMLEntities(path),
+					null,
+					null);
+			return uri.toURL();
+		}
+		catch (Throwable _) {
+			//
+		}
+
+		try {
+			return new URL(
+					filename.getProtocol(), 
+					filename.getHost(), 
+					path);
+		}
+		catch (Throwable _) {
+			//
+		}
+		return null;
+	}
+
+	/** Replies the basename of the specified file with the extension.
+	 * <p>
+	 * Caution: This function does not support URL format.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file with the extension.
+	 */
+	public static String largeBasename(String filename) {
+		if (filename==null) return null;
+		assert(!isWindowsNativeFilename(filename));
+		int end = filename.length();
+		int idx;
+		do {
+			end--;
+			idx = filename.lastIndexOf(File.separatorChar, end);
+		}
+		while (idx>=0 && end>=0 && idx>=end);
+		if (idx<0) {
+			if (end<filename.length()-1)
+				return filename.substring(0, end+1);
+			return filename;
+		}
+		return filename.substring(idx+1, end+1);
+	}
+
+	/** Replies the basename of the specified file with the extension.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file with the extension.
+	 */
+	public static String largeBasename(File filename) {
+		if (filename==null) return null;
+		return filename.getName();
+	}
+
+	/** Replies the basename of the specified file with the extension.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file with the extension.
+	 */
+	public static String largeBasename(URL filename) {
+		if (filename==null) return null;
+		String fullPath = filename.getPath();
+		assert(!isWindowsNativeFilename(fullPath));
+		int idx;
+		int end = fullPath.length();
+		do {
+			end--;
+			idx = fullPath.lastIndexOf(URL_PATH_SEPARATOR_CHAR, end);
+		}
+		while (idx>=0 && end>=0 && idx>=end);
+		String r;
+		if (idx<0) {
+			if (end<fullPath.length()-1)
+				r = fullPath.substring(0, end+1);
+			else
+				r = fullPath;
+		}
+		else 
+			r = fullPath.substring(idx+1, end+1);
+		return decodeHTMLEntities(r);
+	}
+
+	/** Reply the basename of the specified file without the last extension.
+	 * <p>
+	 * Caution: This function does not support URL format.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file without the last extension.
+	 * @see #shortBasename(String)
+	 * @see #largeBasename(String)
+	 */
+	public static String basename(String filename) {
+		if (filename==null) return null;
+		assert(!isWindowsNativeFilename(filename));
+		int end = filename.length();
+		int idx;
+		do {
+			end--;
+			idx = filename.lastIndexOf(File.separatorChar, end);
+		}
+		while (idx>=0 && end>=0 && idx>=end);
+		String basename;
+		if (idx<0) {
+			if (end<filename.length()-1)
+				basename = filename.substring(0, end+1);
+			else
+				basename = filename;
+		}
+		else
+			basename =filename.substring(idx+1, end+1);
+		idx = basename.lastIndexOf(getFileExtensionCharacter());
+		if (idx<0) return basename;
+		return basename.substring(0,idx);
+	}
+
+	/** Reply the basename of the specified file without the last extension.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file without the last extension.
+	 * @see #shortBasename(File)
+	 * @see #largeBasename(File)
+	 * @see #dirname(File)
+	 * @see #extension(File)
+	 */
+	public static String basename(File filename) {
+		if (filename==null) return null;
+		String largeBasename = filename.getName();
+		int idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+		if (idx<=0) return largeBasename;
+		return largeBasename.substring(0,idx);
+	}
+
+	/** Reply the basename of the specified file without the last extension.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file without the last extension.
+	 * @see #shortBasename(URL)
+	 * @see #largeBasename(URL)
+	 * @see #dirname(URL)
+	 * @see #extension(URL)
+	 */
+	public static String basename(URL filename) {
+		if (filename==null) return null;
+		String largeBasename = filename.getPath();
+		assert(!isWindowsNativeFilename(largeBasename));
+		int end = largeBasename.length();
+		int idx;
+		do {
+			end--;
+			idx = largeBasename.lastIndexOf(URL_PATH_SEPARATOR_CHAR, end);
+		}
+		while (idx>=0 && end>=0 && idx>=end);
+		String basename;
+		if (idx<0) {
+			if (end<largeBasename.length()-1)
+				basename = largeBasename.substring(0, end+1);
+			else
+				basename = largeBasename;
+		}
+		else
+			basename = largeBasename.substring(idx+1, end+1);
+		idx = basename.lastIndexOf(getFileExtensionCharacter());
+		if (idx>=0) basename = basename.substring(0,idx);
+		return decodeHTMLEntities(basename);
+	}
+
+	/** Reply the basename of the specified file without all the extensions.
+	 * <p>
+	 * Caution: This function does not support URL format.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file without all the extensions.
+	 */
+	public static String shortBasename(String filename) {
+		if (filename==null) return null;
+		if (isWindowsNativeFilename(filename)) {
+			return shortBasename(normalizeWindowsNativeFilename(filename));
+		}
+		String normalizedFilename = getFilePath(filename);
+		int idx;
+		int end = normalizedFilename.length();
+		do {
+			end--;
+			idx = normalizedFilename.lastIndexOf(URL_PATH_SEPARATOR_CHAR, end);
+		}
+		while (idx>=0 && end>=0 && idx>=end);
+		String basename;
+		if (idx<0) {
+			if (end<normalizedFilename.length()-1)
+				basename = normalizedFilename.substring(0, end+1);
+			else
+				basename = normalizedFilename;
+		}
+		else
+			basename = normalizedFilename.substring(idx+1, end+1);
+
+		idx = basename.indexOf(getFileExtensionCharacter());
+		if (idx<0) return basename;
+		return basename.substring(0,idx);
+	}
+
+	/** Reply the basename of the specified file without all the extensions.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file without all the extensions.
+	 */
+	public static String shortBasename(File filename) {
+		if (filename==null) return null;
+		String largeBasename = filename.getName();
+		int idx = largeBasename.indexOf(getFileExtensionCharacter());
+		if (idx<0) return largeBasename;
+		return largeBasename.substring(0,idx);
+	}
+
+	/** Reply the basename of the specified file without all the extensions.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the basename of the specified file without all the extensions.
+	 */
+	public static String shortBasename(URL filename) {
+		if (filename==null) return null;
+		String largeBasename = filename.getPath();
+		assert(!isWindowsNativeFilename(largeBasename));
+		int idx;
+		int end = largeBasename.length();
+		do {
+			end--;
+			idx = largeBasename.lastIndexOf(URL_PATH_SEPARATOR_CHAR, end);
+		}
+		while (idx>=0 && end>=0 && idx>=end);
+		String basename;
+		if (idx<0) {
+			if (end<largeBasename.length()-1)
+				basename = largeBasename.substring(0, end+1);
+			else
+				basename = largeBasename;
+		}
+		else
+			basename = largeBasename.substring(idx+1, end+1);
+
+		idx = basename.indexOf(getFileExtensionCharacter());
+		if (idx>=0) basename = basename.substring(0,idx);
+		return decodeHTMLEntities(basename);
+	}
+
+	/** Reply the extension of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the extension of the specified file
+	 * @see #shortBasename(File)
+	 * @see #largeBasename(File)
+	 * @see #basename(File)
+	 * @see #dirname(File)
+	 * @see #extensions(File)
+	 */
+	public static String extension(File filename) {
+		if (filename==null) return null;
+		String largeBasename = largeBasename(filename);
+		int idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+		if (idx<=0) return ""; //$NON-NLS-1$
+		return largeBasename.substring(idx);
+	}
+
+	/** Reply the extension of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the extension of the specified file
+	 * @see #shortBasename(File)
+	 * @see #largeBasename(File)
+	 * @see #basename(File)
+	 * @see #dirname(File)
+	 * @see #extensions(File)
+	 * @since 7.0
+	 */
+	public static String extension(String filename) {
+		if (filename==null) return null;
+		String largeBasename = largeBasename(filename);
+		int idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+		if (idx<=0) return ""; //$NON-NLS-1$
+		return largeBasename.substring(idx);
+	}
+
+	/** Reply the extension of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the extension of the specified file
+	 * @see #shortBasename(URL)
+	 * @see #largeBasename(URL)
+	 * @see #basename(URL)
+	 * @see #dirname(URL)
+	 * @see #extensions(URL)
+	 */
+	public static String extension(URL filename) {
+		if (filename==null) return null;
+		String largeBasename = largeBasename(filename);
+		int idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+		if (idx<=0) return ""; //$NON-NLS-1$
+		return decodeHTMLEntities(largeBasename.substring(idx));
+	}
+
+	/** Reply all the extensions of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the extensions of the specified file
+	 */
+	public static String[] extensions(File filename) {
+		if (filename==null) return new String[0];
+		String largeBasename = largeBasename(filename);
+		String[] parts = largeBasename.split(Pattern.quote(Character.toString(getFileExtensionCharacter())));
+		if (parts.length<=1) return new String[0];
+		String[] r = new String[parts.length-1];
+		System.arraycopy(parts, 1, r, 0, r.length);
+		return r;
+	}
+
+	/** Reply all the extensions of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the extensions of the specified file
+	 * @since 7.0
+	 */
+	public static String[] extensions(String filename) {
+		if (filename==null) return new String[0];
+		String largeBasename = largeBasename(filename);
+		String[] parts = largeBasename.split(Pattern.quote(Character.toString(getFileExtensionCharacter())));
+		if (parts.length<=1) return new String[0];
+		String[] r = new String[parts.length-1];
+		System.arraycopy(parts, 1, r, 0, r.length);
+		return r;
+	}
+
+	/** Reply all the extensions of the specified file.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the extensions of the specified file
+	 */
+	public static String[] extensions(URL filename) {
+		if (filename==null) return new String[0];
+		String largeBasename = largeBasename(filename);
+		String[] parts = largeBasename.split(Pattern.quote(Character.toString(getFileExtensionCharacter())));
+		if (parts.length<=1) return new String[0];
+		String[] r = new String[parts.length-1];
+		for(int i=0; i<r.length; ++i) {
+			r[i] = decodeHTMLEntities(parts[i+1]);
+		}
+		return r;
+	}
+
+	/** Replies the parts of a path.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the parts of a path.
+	 */
+	public static String[] split(File filename) {
+		if (filename==null) return new String[0];
+		return filename.getPath().split(Pattern.quote(File.separator));
+	}
+
+	/** Replies the parts of a path.
+	 *
+	 * @param filename is the name to parse.
+	 * @return the parts of a path.
+	 */
+	public static String[] split(URL filename) {
+		if (filename==null) return new String[0];
+		String path;
+		if (isJarURL(filename))
+			return split(getJarFile(filename));
+		path = filename.getPath();
+		String[] tab = path.split(Pattern.quote(URL_PATH_SEPARATOR));
+		for(int i=0; i<tab.length; ++i) {
+			tab[i] = decodeHTMLEntities(tab[i]);
+		}
+		return tab;
+	}
+
+	/** Join the parts of a path and append them to the given File.
+	 *
+	 * @param fileBase is the file to put as prefix.
+	 * @param elements are the path's elements to join.
+	 * @return the result of the join of the path's elements.
+	 */
+	public static File join(File fileBase, String... elements) {
+		if (fileBase==null) return null;
+		StringBuilder buf = new StringBuilder(fileBase.getPath());
+		boolean empty;
+		for(String elt : elements) {
+			empty = (elt==null || elt.length()==0);
+			if (!empty) {
+				assert(elt!=null);
+				if (!elt.startsWith(File.separator) 
+						&& buf.length()>=0
+						&& buf.charAt(buf.length()-1)!=File.separatorChar) {
+					buf.append(File.separatorChar);
+				}
+				buf.append(elt);
+			}
+		}
+		return new File(buf.toString());
+	}
+
+	/** Join the parts of a path and append them to the given File.
+	 *
+	 * @param fileBase is the file to put as prefix.
+	 * @param elements are the path's elements to join.
+	 * @return the result of the join of the path's elements.
+	 */
+	public static File join(File fileBase, File... elements) {
+		if (fileBase==null) return null;
+		StringBuilder buf = new StringBuilder(fileBase.getPath());
+		for(File elt : elements) {
+			if (!elt.isAbsolute()) {
+				if (buf.length()>=0 && buf.charAt(buf.length()-1)!=File.separatorChar) {
+					buf.append(File.separatorChar);
+				}
+			}
+			buf.append(elt.getPath());
+		}
+		return new File(buf.toString());
+	}
+
+	/** Join the parts of a path and append them to the given URL.
+	 *
+	 * @param urlBase is the url to put as prefix.
+	 * @param elements are the path's elements to join.
+	 * @return the result of the join of the path's elements.
+	 */
+	public static URL join(URL urlBase, String... elements) {
+		if (urlBase==null) return null;
+		StringBuilder buf = new StringBuilder(urlBase.getPath());
+		boolean empty;
+		for(String elt : elements) {
+			empty = (elt==null || elt.length()==0);
+			if (!empty) {
+				assert(elt!=null);
+				if (!elt.startsWith(File.separator) 
+						&& (buf.length()==0
+								|| buf.charAt(buf.length()-1)!=URL_PATH_SEPARATOR_CHAR)) {
+					buf.append(URL_PATH_SEPARATOR_CHAR);
+				}
+				buf.append(elt);
+			}
+		}
+		try {
+			if (isJarURL(urlBase)) {
+				return new URL(
+						urlBase.getProtocol(), 
+						urlBase.getHost(), 
+						urlBase.getPort(),
+						buf.toString());
+			}
+			URI uri = new URI(
+					urlBase.getProtocol(), 
+					urlBase.getUserInfo(), 
+					urlBase.getHost(), 
+					urlBase.getPort(), 
+					decodeHTMLEntities(buf.toString()),
+					decodeHTMLEntities(urlBase.getQuery()),
+					urlBase.getRef());
+			return uri.toURL();
+		}
+		catch (Throwable _) {
+			//
+		}
+		try {
+			return new URL(
+					urlBase.getProtocol(), 
+					urlBase.getHost(), 
+					buf.toString());
+		}
+		catch (Throwable _) {
+			return null;
+		}
+	}
+
+	/** Join the parts of a path and append them to the given URL.
+	 *
+	 * @param urlBase is the url to put as prefix.
+	 * @param elements are the path's elements to join.
+	 * @return the result of the join of the path's elements.
+	 */
+	public static URL join(URL urlBase, File... elements) {
+		if (urlBase==null) return null;
+		StringBuilder buf = new StringBuilder(urlBase.getPath());
+		for(File elt : elements) {
+			if (!elt.isAbsolute()) {
+				if (buf.length()==0 || buf.charAt(buf.length()-1)!=URL_PATH_SEPARATOR_CHAR) {
+					buf.append(URL_PATH_SEPARATOR_CHAR);
+				}
+			}
+			buf.append(getFilePath(elt));
+		}
+		try {
+			if (isJarURL(urlBase)) {
+				return new URL(
+						urlBase.getProtocol(), 
+						urlBase.getHost(), 
+						urlBase.getPort(),
+						buf.toString());
+			}
+			URI uri = new URI(
+					urlBase.getProtocol(), 
+					urlBase.getUserInfo(), 
+					urlBase.getHost(), 
+					urlBase.getPort(), 
+					decodeHTMLEntities(buf.toString()),
+					decodeHTMLEntities(urlBase.getQuery()),
+					urlBase.getRef());
+			return uri.toURL();
+		}
+		catch (Throwable _) {
+			//
+		}
+		try {
+			return new URL(
+					urlBase.getProtocol(), 
+					urlBase.getHost(), 
+					buf.toString());
+		}
+		catch (Throwable _) {
+			return null;
+		}
+	}
+
+	/** Replies if the specified file has the specified extension.
+	 * <p>
+	 * The test is dependent of the case-sensitive attribute of operating system.
+	 * 
+	 * @param filename is the filename to parse
+	 * @param extension is the extension to test.
+	 * @return <code>true</code> if the given filename has the given extension,
+	 * otherwise <code>false</code>
+	 */
+	public static boolean hasExtension(File filename, String extension) {
+		if (filename==null) return false;
+		assert(extension!=null);
+		String extent = extension;
+		if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+			extent = EXTENSION_SEPARATOR+extent;
+		String ext = extension(filename);
+		if (ext==null) return false;
+		if (isCaseSensitiveFilenameSystem())
+			return ext.equals(extent);
+		return ext.equalsIgnoreCase(extent);
+	}
+
+	/** Replies if the specified file has the specified extension.
+	 * <p>
+	 * The test is dependent of the case-sensitive attribute of operating system.
+	 * 
+	 * @param filename is the filename to parse
+	 * @param extension is the extension to test.
+	 * @return <code>true</code> if the given filename has the given extension,
+	 * otherwise <code>false</code>
+	 * @since 7.0
+	 */
+	public static boolean hasExtension(String filename, String extension) {
+		if (filename==null) return false;
+		assert(extension!=null);
+		String extent = extension;
+		if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+			extent = EXTENSION_SEPARATOR+extent;
+		String ext = extension(filename);
+		if (ext==null) return false;
+		if (isCaseSensitiveFilenameSystem())
+			return ext.equals(extent);
+		return ext.equalsIgnoreCase(extent);
+	}
+
+	/** Replies if the specified file has the specified extension.
+	 * <p>
+	 * The test is dependent of the case-sensitive attribute of operating system.
+	 * 
+	 * @param filename is the filename to parse
+	 * @param extension is the extension to test.
+	 * @return <code>true</code> if the given filename has the given extension,
+	 * otherwise <code>false</code>
+	 */
+	public static boolean hasExtension(URL filename, String extension) {
+		if (filename==null) return false;
+		assert(extension!=null);
+		String extent = extension;
+		if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+			extent = EXTENSION_SEPARATOR+extent;
+		String ext = extension(filename);
+		if (ext==null) return false;
+		if (isCaseSensitiveFilenameSystem())
+			return ext.equals(extent);
+		return ext.equalsIgnoreCase(extent);
+	}
+
+	/** Remove the extension from the specified filename.
+	 * 
+	 * @param filename is the filename to parse.
+	 * @return the filename without the extension.
+	 */
+	public static File removeExtension(File filename) {
+		if (filename==null) return null;
+		File dir = filename.getParentFile();
+		String name = filename.getName();
+		int idx = name.lastIndexOf(getFileExtensionCharacter());
+		if (idx<0) return filename;
+		return new File(dir, name.substring(0,idx));
+	}
+
+	/** Remove the extension from the specified filename.
+	 * 
+	 * @param filename is the filename to parse.
+	 * @return the filename without the extension.
+	 */
+	public static URL removeExtension(URL filename) {
+		if (filename==null) return null;
+		String path = filename.getPath();
+		int idx = path.lastIndexOf(URL_PATH_SEPARATOR);
+		StringBuilder buf = new StringBuilder((idx<0) ? "" : decodeHTMLEntities(path.substring(0, idx+1))); //$NON-NLS-1$
+		String largeBasename = decodeHTMLEntities(path.substring(idx+1));
+		idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+		if (idx<0) return filename;
+		buf.append(largeBasename.substring(0, idx));
+		try {
+			if (isJarURL(filename)) {
+				return new URL(
+						filename.getProtocol(), 
+						filename.getHost(), 
+						filename.getPort(),
+						buf.toString());
+			}
+			URI uri = new URI(
+					filename.getProtocol(), 
+					filename.getUserInfo(), 
+					filename.getHost(), 
+					filename.getPort(), 
+					buf.toString(),
+					decodeHTMLEntities(filename.getQuery()),
+					filename.getRef());
+			return uri.toURL();
+		}
+		catch(AssertionError e) {
+			throw e;
+		}
+		catch(Throwable _) {
+			//
+		}
+		try {
+			return new URL(
+					filename.getProtocol(), 
+					filename.getHost(), 
+					buf.toString());
+		}
+		catch(AssertionError e) {
+			throw e;
+		}
+		catch(Throwable _) {
+			return null;
+		}
+	}
+
+	/** Replace the extension of the specified filename by the given extension.
+	 * If the filename has no extension, the specified one will be added.
+	 * 
+	 * @param filename is the filename to parse.
+	 * @param extension is the extension to remove if it is existing.
+	 * @return the filename without the extension.
+	 */
+	public static File replaceExtension(File filename, String extension) {
+		if (filename==null) return null;
+		if (extension==null) return filename;
+		File dir = filename.getParentFile();
+		String name = filename.getName();
+		int idx = name.lastIndexOf(getFileExtensionCharacter());
+		StringBuilder n = new StringBuilder();
+		if (idx<0) {
+			n.append(name);
+		}
+		else {
+			n.append(name.substring(0,idx));
+		}
+		if (!name.endsWith(EXTENSION_SEPARATOR) && !extension.startsWith(EXTENSION_SEPARATOR))
+			n.append(EXTENSION_SEPARATOR);
+		n.append(extension);
+		return new File(dir, n.toString());
+	}
+
+	/** Replace the extension of the specified filename by the given extension.
+	 * If the filename has no extension, the specified one will be added.
+	 * 
+	 * @param filename is the filename to parse.
+	 * @param extension is the extension to remove if it is existing.
+	 * @return the filename without the extension.
+	 */
+	public static URL replaceExtension(URL filename, String extension) {
+		if (filename==null) return null;
+		if (extension==null) return filename;
+		String path = filename.getPath();
+		int idx = path.lastIndexOf(URL_PATH_SEPARATOR);
+		int end = path.length();
+		if (idx==end-1) {
+			end --;
+			idx = path.lastIndexOf(URL_PATH_SEPARATOR, end-1);
+		}
+		StringBuilder buf = new StringBuilder((idx<0) ? "" : decodeHTMLEntities(path.substring(0, idx+1))); //$NON-NLS-1$
+		String largeBasename = decodeHTMLEntities(path.substring(idx+1, end));
+		idx = largeBasename.lastIndexOf(getFileExtensionCharacter());
+		if (idx<0) {
+			buf.append(largeBasename);
+		}
+		else {
+			buf.append(largeBasename.substring(0, idx));
+		}
+		String extent = extension;
+		if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+			extent = EXTENSION_SEPARATOR+extent;
+		buf.append(extent);
+		try {
+			if (isJarURL(filename)) {
+				return new URL(
+						filename.getProtocol(), 
+						filename.getHost(), 
+						filename.getPort(),
+						buf.toString());
+			}
+			URI uri = new URI(
+					filename.getProtocol(), 
+					filename.getUserInfo(), 
+					filename.getHost(), 
+					filename.getPort(), 
+					buf.toString(),
+					encodeHTMLEntities(filename.getQuery()),
+					filename.getRef());
+			return uri.toURL();
+		}
+		catch(AssertionError e) {
+			throw e;
+		}
+		catch(Throwable _) {
+			//
+		}
+		try {
+			return new URL(
+					filename.getProtocol(), 
+					filename.getHost(), 
+					buf.toString());
+		}
+		catch(AssertionError e) {
+			throw e;
+		}
+		catch(Throwable _) {
+			return null;
+		}
+	}
+
+	/** Add the extension of to specified filename.
+	 * If the filename has already the given extension, the filename is not changed.
+	 * If the filename has no extension or an other extension, the specified one is added.
+	 * 
+	 * @param filename is the filename to parse.
+	 * @param extension is the extension to remove if it is existing.
+	 * @return the filename with the extension.
+	 * @since 6.0
+	 */
+	public static File addExtension(File filename, String extension) {
+		if (filename!=null && !hasExtension(filename, extension)) {
+			String extent = extension;
+			if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+				extent = EXTENSION_SEPARATOR+extent;
+			return new File(filename.getParentFile(), filename.getName()+extent);
+		}
+		return filename;
+	}
+
+	/** Add the extension of to specified filename.
+	 * If the filename has already the given extension, the filename is not changed.
+	 * If the filename has no extension or an other extension, the specified one is added.
+	 * 
+	 * @param filename is the filename to parse.
+	 * @param extension is the extension to remove if it is existing.
+	 * @return the filename with the extension.
+	 * @since 6.0
+	 */
+	public static URL addExtension(URL filename, String extension) {
+		if (filename!=null && !hasExtension(filename, extension)) {
+			String basename = largeBasename(filename);
+			URL dirname = dirname(filename);
+			String extent = extension;
+			if (!"".equals(extent) && !extent.startsWith(EXTENSION_SEPARATOR)) //$NON-NLS-1$
+				extent = EXTENSION_SEPARATOR+extent;
+			return join(dirname, basename+extent);
+		}
+		return filename;
+	}
+
+	/** Delete the given directory and all its subdirectories.
+	 * If the given <var>file</var> is a directory, its
+	 * content and the <var>file</var> itself are recursivelly removed. 
+	 * 
+	 * @param file is the file to delete.
+	 * @throws IOException
+	 * @see File#delete() for the deletion on a file only.
+	 * @see File#mkdir() to create a directory.
+	 * @see File#mkdirs() to create a directory and all its parents.
+	 * @since 6.0
+	 */
+	public static void delete(File file) throws IOException {
+		if (file!=null) {
+			LinkedList<File> candidates = new LinkedList<>();
+			candidates.add(file);
+			File f;
+			File[] children;
+			while (!candidates.isEmpty()) {
+				f = candidates.getFirst();
+				if (f.isDirectory()) {
+					children = f.listFiles();
+					if (children!=null && children.length>1) {
+						// Non empty directory
+						for(File c : children) {
+							candidates.push(c);
+						}
+					}
+					else {
+						// empty directory
+						candidates.removeFirst();
+						f.delete();
+					}
+				}
+				else {
+					// not a directory
+					candidates.removeFirst();
+					f.delete();
+				}
+			}
+		}
+	}
+
+	/** Delete the given directory and all its subdirectories when the JVM is exiting.
+	 * If the given <var>file</var> is a directory, its
+	 * content and the <var>file</var> itself are recursivelly removed.
+	 * <p>
+	 * To cancel this action, see {@link #undeleteOnExit(File)}. 
+	 * 
+	 * @param file is the file to delete.
+	 * @throws IOException
+	 * @see File#deleteOnExit() for the deletion on a file only.
+	 * @see File#mkdir() to create a directory.
+	 * @see File#mkdirs() to create a directory and all its parents.
+	 * @since 6.0
+	 */
+	public static void deleteOnExit(File file) throws IOException {
+		if (file!=null) {
+			deleteOnExitHook.add(file);
+		}
+	}
+
+	/** Cancel the deletion of the given directory and all its subdirectories when the JVM is exiting.
+	 * 
+	 * @param file is the file to undelete.
+	 * @throws IOException
+	 * @see #deleteOnExit(File)
+	 * @see File#deleteOnExit() for the deletion on a file only.
+	 * @see File#mkdir() to create a directory.
+	 * @see File#mkdirs() to create a directory and all its parents.
+	 * @since 6.0
+	 */
+	public static void undeleteOnExit(File file) throws IOException {
+		if (file!=null) {
+			deleteOnExitHook.remove(file);
+		}
+	}
+
+	/** Copy the first file into the second file.
+	 * <p>
+	 * The content of the second file will be lost.
+	 * This copy function allows to do a copy between two different
+	 * partitions.
+	 * 
+	 * @param in is the file to copy.
+	 * @param out is the target file
+	 * @throws IOException in case of error.
+	 * @see #fileCopy(URL, File)
+	 * @deprecated {@link #copy(File, File)}
+	 */
+	@Deprecated
+	public static void fileCopy(File in, File out) throws IOException {
+		copy(in, out);
+	}
+
+	/** Copy the first file into the second file.
+	 * <p>
+	 * The content of the second file will be lost.
+	 * This copy function allows to do a copy between two different
+	 * partitions.
+	 * <p>
+	 * If the <var>out</var> parameter is a directory, the output file
+	 * is a file with the same basename as the input and inside
+	 * the <var>ou</var> directory.
+	 * 
+	 * @param in is the file to copy.
+	 * @param out is the target file
+	 * @throws IOException in case of error.
+	 * @see #copy(URL, File)
+	 * @since 6.0
+	 */
+	public static void copy(File in, File out) throws IOException {
+		assert(in!=null);
+		assert(out!=null);
+		
+		File outFile = out;
+		if (out.isDirectory()) {
+			outFile = new File(out, largeBasename(in));
+		}
+		
+		try (
+				FileInputStream fis = new FileInputStream(in);
+				FileOutputStream fos = new FileOutputStream(outFile)) {
+			copy(fis, (int)in.length(), fos);
+		}
+	}
+
+	/** Copy the first file into the second file.
+	 * <p>
+	 * The content of the second file will be lost.
+	 * This copy function allows to do a copy between two different
+	 * partitions.
+	 * 
+	 * @param in is the file to copy.
+	 * @param out is the target file
+	 * @throws IOException in case of error.
+	 * @see #fileCopy(File, File)
+	 * @deprecated {@link #copy(URL, File)}
+	 */
+	@Deprecated
+	public static void fileCopy(URL in, File out) throws IOException {
+		copy(in, out);
+	}
+
+	/** Copy the first file into the second file.
+	 * <p>
+	 * The content of the second file will be lost.
+	 * This copy function allows to do a copy between two different
+	 * partitions.
+	 * 
+	 * @param in is the file to copy.
+	 * @param out is the target file
+	 * @throws IOException in case of error.
+	 * @see #copy(File, File)
+	 * @since 6.0
+	 */
+	public static void copy(URL in, File out) throws IOException {
+		assert(in!=null);
+		assert(out!=null);
+
+		File outFile = out;
+		if (out.isDirectory()) {
+			outFile = new File(out, largeBasename(in));
+		}
+		
+		URLConnection connection = in.openConnection();
+		try (
+				FileOutputStream fos = new FileOutputStream(outFile)) {
+			copy(
+				connection.getInputStream(),
+				connection.getContentLength(),
+				fos);
+		}
+	}
+
+	/** Copy the first file into the second file.
+	 * <p>
+	 * The content of the second file will be lost.
+	 * This copy function allows to do a copy between two different
+	 * partitions.
+	 * 
+	 * @param in is the input stream to read.
+	 * @param inSize is the total size of the input stream.
+	 * @param out is the output stream.
+	 * @throws IOException
+	 * @since 6.2
+	 */
+	public static void copy(InputStream in, int inSize, FileOutputStream out) throws IOException {
+		assert(in!=null);
+		assert(out!=null);
+		try (
+				ReadableByteChannel inChannel = Channels.newChannel(in);
+				FileChannel outChannel = out.getChannel()) {
+			int size = inSize;
+			// apparently has trouble copying large files on Windows
+			if (size<0 || OperatingSystem.WIN.isCurrentOS()) {
+				// magic number for Windows, 64Mb - 32Kb
+				int maxCount = (64 * 1024 * 1024) - (32 * 1024);
+				long position = 0;
+				long copied = 1;
+				while ( (size>=0 && position<size) || (size<0 && copied>0)) {
+					copied = outChannel.transferFrom(inChannel, position, maxCount);
+					position += copied;
+				}
+			}
+			else {
+				outChannel.transferFrom(inChannel, 0, size);
+			}
+		}
+	}
+	
+	/** Replies the user home directory.
+	 *
+	 * @return the home directory of the current user.
+	 * @throws FileNotFoundException
+	 */
+	public static File getUserHomeDirectory() throws FileNotFoundException {
+		String userHome = System.getProperty("user.home"); //$NON-NLS-1$
+		if (userHome!=null && !userHome.isEmpty()) {
+			File file = new File(userHome);
+			if (file.isDirectory()) return file;
+		}
+		if (OperatingSystem.ANDROID.isCurrentOS()) {
+			return join(File.listRoots()[0], Android.HOME_DIRECTORY);
+		}
+		throw new FileNotFoundException();
+	}
+
+	/** Replies the user home directory.
+	 * 
+	 * @return the home directory of the current user.
+	 */
+	public static String getUserHomeDirectoryName() {
+		String userHome = System.getProperty("user.home"); //$NON-NLS-1$
+		if ((userHome==null || userHome.isEmpty()) && (OperatingSystem.ANDROID.isCurrentOS())) {
+			return join(File.listRoots()[0], Android.HOME_DIRECTORY).toString();
+		}
+		return userHome;
+	}
+
+	/** Replies the user configuration directory for the specified software.
+	 * <p>
+	 * On Unix operating systems, the user directory for a
+	 * software is by default {@code $HOME/.software} where {@code software}
+	 * is the given parameter (case-sensitive). On Windows&reg; operating systems, the user
+	 * directory for a software is by default
+	 * {@code C:<span>\</span>Documents and Settings<span>\</span>userName<span>\</span>Local Settings<span>\</span>Application Data<span>\</span>software}
+	 * where {@code userName} is the login of the current user and {@code software}
+	 * is the given parameter (case-insensitive). 
+	 *
+	 * @param software is the name of the concerned software.
+	 * @return the configuration directory of the software for the current user.
+	 */
+	public static File getUserConfigurationDirectoryFor(String software) {
+		if (software==null || "".equals(software)) //$NON-NLS-1$
+			throw new IllegalArgumentException();
+		try {
+			File userHome = getUserHomeDirectory();
+			OperatingSystem os = OperatingSystem.getCurrentOS();
+			if (os==OperatingSystem.ANDROID) {
+				return join(userHome, "Android", Android.DATA_DIRECTORY,  //$NON-NLS-1$
+						Android.makeAndroidApplicationName(software));
+			}
+			else if (os.isUnixCompliant()) {
+				return new File(new File(userHome, ".config"), software); //$NON-NLS-1$
+			}
+			else if (os==OperatingSystem.WIN) {
+				String userName = System.getProperty("user.name"); //$NON-NLS-1$
+				if (userName!=null && !"".equals(userName)) { //$NON-NLS-1$
+					return join(
+							new File("C:"),  //$NON-NLS-1$
+							"Documents and Settings", //$NON-NLS-1$
+							userName,
+							"Local Settings","Application Data",  //$NON-NLS-1$//$NON-NLS-2$
+							software);
+				}
+			}
+			return new File(userHome,software);
+		}
+		catch(FileNotFoundException _) {
+			//
+		}
+		return null;
+	}
+
+	/** Replies the user configuration directory for the specified software.
+	 * <p>
+	 * On Unix operating systems, the user directory for a
+	 * software is by default {@code $HOME/.software} where {@code software}
+	 * is the given parameter (case-sensitive). On Windows&reg; operating systems, the user
+	 * directory for a software is by default
+	 * {@code C:<span>\</span>Documents and Settings<span>\</span>userName<span>\</span>Local Settings<span>\</span>Application Data<span>\</span>software}
+	 * where {@code userName} is the login of the current user and {@code software}
+	 * is the given parameter (case-insensitive). 
+	 * 
+	 * @param software is the name of the concerned software.
+	 * @return the configuration directory of the software for the current user.
+	 */
+	public static String getUserConfigurationDirectoryNameFor(String software) {
+		File directory = getUserConfigurationDirectoryFor(software);
+		if (directory!=null) return directory.getAbsolutePath();
+		return null;
+	}
+
+	/** Replies the system configuration directory for the specified software.
+	 * <p>
+	 * On Unix operating systems, the system directory for a
+	 * software is by default {@code /etc/software} where {@code software}
+	 * is the given parameter (case-sensitive). On Windows&reg; operating systems, the user
+	 * directory for a software is by default
+	 * {@code C:<span>\</span>Program Files<span>\</span>software}
+	 * where {@code software} is the given parameter (case-insensitive). 
+	 *
+	 * @param software is the name of the concerned software.
+	 * @return the configuration directory of the software for the current user.
+	 */
+	public static File getSystemConfigurationDirectoryFor(String software) {
+		if (software==null || "".equals(software)) //$NON-NLS-1$
+			throw new IllegalArgumentException();
+		OperatingSystem os = OperatingSystem.getCurrentOS();
+		if (os==OperatingSystem.ANDROID) {
+			return join(File.listRoots()[0], Android.CONFIGURATION_DIRECTORY,
+					Android.makeAndroidApplicationName(software));
+		}
+		else if (os.isUnixCompliant()) {
+			File[] roots = File.listRoots();
+			return join(roots[0],"etc", software); //$NON-NLS-1$
+		}
+		else if (os==OperatingSystem.WIN) {
+			File pfDirectory;
+			for(File root : File.listRoots()) {
+				pfDirectory = new File(root, "Program Files"); //$NON-NLS-1$
+				if (pfDirectory.isDirectory()) {
+					return new File(root, software);
+				}
+			}
+		}
+		return null;
+	}
+
+	/** Replies the user configuration directory for the specified software.
+	 * <p>
+	 * On Unix operating systems, the system directory for a
+	 * software is by default {@code /etc/software} where {@code software}
+	 * is the given parameter (case-sensitive). On Windows&reg; operating systems, the user
+	 * directory for a software is by default
+	 * {@code C:<span>\</span>Program Files<span>\</span>software}
+	 * where {@code software} is the given parameter (case-insensitive). 
+	 * 
+	 * @param software is the name of the concerned software.
+	 * @return the configuration directory of the software for the current user.
+	 */
+	public static String getSystemConfigurationDirectoryNameFor(String software) {
+		File directory = getSystemConfigurationDirectoryFor(software);
+		if (directory!=null) return directory.getAbsolutePath();
+		return null;
+	}
+
+	/** Replies the system shared library directory for the specified software.
+	 * <p>
+	 * On Unix operating systems, the system directory for a
+	 * software is by default {@code /usr/lib/software} where {@code software}
+	 * is the given parameter (case-sensitive). On Windows&reg; operating systems, the user
+	 * directory for a software is by default
+	 * {@code C:<span>\</span>Program Files<span>\</span>software}
+	 * where {@code software} is the given parameter (case-insensitive). 
+	 *
+	 * @param software is the name of the concerned software.
+	 * @return the configuration directory of the software for the current user.
+	 */
+	public static File getSystemSharedLibraryDirectoryFor(String software) {
+		if (software==null || "".equals(software)) //$NON-NLS-1$
+			throw new IllegalArgumentException();
+		OperatingSystem os = OperatingSystem.getCurrentOS();
+		if (os==OperatingSystem.ANDROID) {
+			return join(File.listRoots()[0], Android.DATA_DIRECTORY,
+					Android.makeAndroidApplicationName(software));
+		}
+		else if (os.isUnixCompliant()) {
+			File[] roots = File.listRoots();
+			return join(roots[0],"usr","lib", software); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		else if (os==OperatingSystem.WIN) {
+			File pfDirectory;
+			for(File root : File.listRoots()) {
+				pfDirectory = new File(root, "Program Files"); //$NON-NLS-1$
+				if (pfDirectory.isDirectory()) {
+					return new File(root, software);
+				}
+			}
+		}
+		return null;
+	}
+
+	/** Replies the system shared library directory for the specified software.
+	 * <p>
+	 * On Unix operating systems, the system directory for a
+	 * software is by default {@code /usr/lib/software} where {@code software}
+	 * is the given parameter (case-sensitive). On Windows&reg; operating systems, the user
+	 * directory for a software is by default
+	 * {@code C:<span>\</span>Program Files<span>\</span>software}
+	 * where {@code software} is the given parameter (case-insensitive). 
+	 *
+	 * @param software is the name of the concerned software.
+	 * @return the configuration directory of the software for the current user.
+	 */
+	public static String getSystemSharedLibraryDirectoryNameFor(String software) {
+		File f = getSystemSharedLibraryDirectoryFor(software);
+		if (f==null) return null;
+		return f.getAbsolutePath();
+	}
+
+	/** Convert an URL which represents a local file into a File.
+	 * 
+	 * @param url is the URL to convert.
+	 * @return the file.
+	 * @throws IllegalArgumentException is the URL was malformed.
+	 * @deprecated {@link #convertURLToFile(URL)}
+	 */
+	@Deprecated
+	public static File convertUrlToFile(URL url) {
+		return convertURLToFile(url);
+	}
+
+	/** Convert an URL which represents a local file or a resource into a File.
+	 * 
+	 * @param url is the URL to convert.
+	 * @return the file.
+	 * @throws IllegalArgumentException is the URL was malformed.
+	 */
+	public static File convertURLToFile(URL url) {
+		URL theUrl = url;
+		if (theUrl==null) return null;
+		if (URISchemeType.RESOURCE.isURL(theUrl)) {
+			theUrl = Resources.getResource(decodeHTMLEntities(theUrl.getFile()));
+			if (theUrl==null) theUrl = url;
+		}
+		URI uri;
+		try {
+			// this is the step that can fail, and so
+			// it should be this step that should be fixed
+			uri = theUrl.toURI();
+		}
+		catch (URISyntaxException e) {
+			// OK if we are here, then obviously the URL did
+			// not comply with RFC 2396. This can only
+			// happen if we have illegal unescaped characters.
+			// If we have one unescaped character, then
+			// the only automated fix we can apply, is to assume
+			// all characters are unescaped.
+			// If we want to construct a URI from unescaped
+			// characters, then we have to use the component
+			// constructors:
+			try {
+				uri = new URI(theUrl.getProtocol(), theUrl.getUserInfo(), theUrl
+						.getHost(), theUrl.getPort(), 
+						decodeHTMLEntities(theUrl.getPath()),
+						decodeHTMLEntities(theUrl.getQuery()),
+						theUrl.getRef());
+			}
+			catch (URISyntaxException e1) {
+				// The URL is broken beyond automatic repair
+				throw new IllegalArgumentException("broken URL: " + theUrl); //$NON-NLS-1$
+			}
+
+		}
+		if (uri!=null && URISchemeType.FILE.isURI(uri)) {
+			String auth = uri.getAuthority();
+			String path = uri.getPath();
+			if (path==null) path = uri.getRawPath();
+			if (path==null) path = uri.getSchemeSpecificPart();
+			if (path==null) path = uri.getRawSchemeSpecificPart();
+			if (path!=null) {
+				if (auth==null || "".equals(auth)) { //$NON-NLS-1$
+					// absolute filename in URI
+					return new File(decodeHTMLEntities(path));
+				}
+				// relative filename in URI, extract it directly
+				return new File(decodeHTMLEntities(auth+path));
+			}
+		}
+		throw new IllegalArgumentException("not a file URL: "+theUrl); //$NON-NLS-1$
+	}
+
+	/** Convert a string to an URL according to several rules.
+	 * <p>
+	 * The rules are (the first succeeded is replied):
+	 * <ul>
+	 * <li>if <var>urlDescription</var> is <code>null</code> or empty, return <code>null</code>;</li>
+	 * <li>try to build an {@link URL} with <var>urlDescription</var> as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code> and 
+	 * <var>urlDescription</var> starts with {@code "resource:"}, call
+	 * {@link Resources#getResource(String)} with the rest of the string as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code>, call
+	 * {@link Resources#getResource(String)} with the <var>urlDescription</var> as
+	 * parameter;</li>
+	 * <li>assuming that the <var>urlDescription</var> is
+	 * a filename, call {@link File#toURI()} to retreive an URI and then
+	 * {@link URI#toURL()};</li>
+	 * <li>If everything else failed, return <code>null</code>.</li>
+	 * </ul>
+	 * 
+	 * @param urlDescription is a string which is describing an URL.
+	 * @param allowResourceSearch indicates if the convertion must take into account the Java resources.
+	 * @return the URL.
+	 * @throws IllegalArgumentException is the string could not be formatted to URL.
+	 * @see Resources#getResource(String)
+	 * @deprecated see {@link #convertStringToURL(String, boolean)}
+	 */
+	@Deprecated
+	public static URL convertStringToUrl(String urlDescription, boolean allowResourceSearch) {
+		return convertStringToURL(urlDescription, allowResourceSearch, true, true);
+	}
+
+	/** Convert a string to an URL according to several rules.
+	 * <p>
+	 * The rules are (the first succeeded is replied):
+	 * <ul>
+	 * <li>if <var>urlDescription</var> is <code>null</code> or empty, return <code>null</code>;</li>
+	 * <li>try to build an {@link URL} with <var>urlDescription</var> as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code> and 
+	 * <var>urlDescription</var> starts with {@code "resource:"}, call
+	 * {@link Resources#getResource(String)} with the rest of the string as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code>, call
+	 * {@link Resources#getResource(String)} with the <var>urlDescription</var> as
+	 * parameter;</li>
+	 * <li>assuming that the <var>urlDescription</var> is
+	 * a filename, call {@link File#toURI()} to retreive an URI and then
+	 * {@link URI#toURL()};</li>
+	 * <li>If everything else failed, return <code>null</code>.</li>
+	 * </ul>
+	 * 
+	 * @param urlDescription is a string which is describing an URL.
+	 * @param allowResourceSearch indicates if the convertion must take into account the Java resources.
+	 * @return the URL.
+	 * @throws IllegalArgumentException is the string could not be formatted to URL.
+	 * @see Resources#getResource(String)
+	 */
+	public static URL convertStringToURL(String urlDescription, boolean allowResourceSearch) {
+		return convertStringToURL(urlDescription, allowResourceSearch, true, true);
+	}
+
+	/** Convert a string to an URL according to several rules.
+	 * <p>
+	 * The rules are (the first succeeded is replied):
+	 * <ul>
+	 * <li>if <var>urlDescription</var> is <code>null</code> or empty, return <code>null</code>;</li>
+	 * <li>try to build an {@link URL} with <var>urlDescription</var> as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code> and 
+	 * <var>urlDescription</var> starts with {@code "resource:"}, call
+	 * {@link Resources#getResource(String)} with the rest of the string as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code>, call
+	 * {@link Resources#getResource(String)} with the <var>urlDescription</var> as
+	 * parameter;</li>
+	 * <li>if <var>repliesFileURL</var> is <code>true</code> and 
+	 * assuming that the <var>urlDescription</var> is
+	 * a filename, call {@link File#toURI()} to retreive an URI and then
+	 * {@link URI#toURL()};</li>
+	 * <li>If everything else failed, return <code>null</code>.</li>
+	 * </ul>
+	 * 
+	 * @param urlDescription is a string which is describing an URL.
+	 * @param allowResourceSearch indicates if the convertion must take into account the Java resources.
+	 * @param repliesFileURL indicates if urlDescription is allowed to be a filename.
+	 * @return the URL.
+	 * @throws IllegalArgumentException is the string could not be formatted to URL.
+	 * @see Resources#getResource(String)
+	 * @deprecated {@link #convertStringToURL(String, boolean, boolean)}
+	 */
+	@Deprecated
+	public static URL convertStringToUrl(String urlDescription, boolean allowResourceSearch, boolean repliesFileURL) {
+		return convertStringToURL(urlDescription, allowResourceSearch, repliesFileURL, true);
+	}
+
+	/** Convert a string to an URL according to several rules.
+	 * <p>
+	 * The rules are (the first succeeded is replied):
+	 * <ul>
+	 * <li>if <var>urlDescription</var> is <code>null</code> or empty, return <code>null</code>;</li>
+	 * <li>try to build an {@link URL} with <var>urlDescription</var> as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code> and 
+	 * <var>urlDescription</var> starts with {@code "resource:"}, call
+	 * {@link Resources#getResource(String)} with the rest of the string as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code>, call
+	 * {@link Resources#getResource(String)} with the <var>urlDescription</var> as
+	 * parameter;</li>
+	 * <li>if <var>repliesFileURL</var> is <code>true</code> and 
+	 * assuming that the <var>urlDescription</var> is
+	 * a filename, call {@link File#toURI()} to retreive an URI and then
+	 * {@link URI#toURL()};</li>
+	 * <li>If everything else failed, return <code>null</code>.</li>
+	 * </ul>
+	 * 
+	 * @param urlDescription is a string which is describing an URL.
+	 * @param allowResourceSearch indicates if the convertion must take into account the Java resources.
+	 * @param repliesFileURL indicates if urlDescription is allowed to be a filename.
+	 * @return the URL.
+	 * @throws IllegalArgumentException is the string could not be formatted to URL.
+	 * @see Resources#getResource(String)
+	 */
+	public static URL convertStringToURL(String urlDescription, boolean allowResourceSearch, boolean repliesFileURL) {
+		return convertStringToURL(urlDescription, allowResourceSearch, repliesFileURL, true);
+	}		
+
+	/** Convert a string to an URL according to several rules.
+	 * <p>
+	 * The rules are (the first succeeded is replied):
+	 * <ul>
+	 * <li>if <var>urlDescription</var> is <code>null</code> or empty, return <code>null</code>;</li>
+	 * <li>try to build an {@link URL} with <var>urlDescription</var> as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code> and 
+	 * <var>urlDescription</var> starts with {@code "resource:"}, call
+	 * {@link Resources#getResource(String)} with the rest of the string as parameter;</li>
+	 * <li>if <var>allowResourceSearch</var> is <code>true</code>, call
+	 * {@link Resources#getResource(String)} with the <var>urlDescription</var> as
+	 * parameter;</li>
+	 * <li>if <var>repliesFileURL</var> is <code>true</code> and 
+	 * assuming that the <var>urlDescription</var> is
+	 * a filename, call {@link File#toURI()} to retreive an URI and then
+	 * {@link URI#toURL()};</li>
+	 * <li>If everything else failed, return <code>null</code>.</li>
+	 * </ul>
+	 * 
+	 * @param urlDescription is a string which is describing an URL.
+	 * @param allowResourceSearch indicates if the convertion must take into account the Java resources.
+	 * @param repliesFileURL indicates if urlDescription is allowed to be a filename.
+	 * @param supportWindowsPaths indicates if Windows paths should be treated in particular way.
+	 * @return the URL.
+	 * @throws IllegalArgumentException is the string could not be formatted to URL.
+	 * @see Resources#getResource(String)
+	 */
+	static URL convertStringToURL(String urlDescription, boolean allowResourceSearch, boolean repliesFileURL, boolean supportWindowsPaths) {
+		URL url = null;
+
+		if (urlDescription!=null && urlDescription.length()>0)  {
+
+			if (supportWindowsPaths && isWindowsNativeFilename(urlDescription)) {
+				File f = normalizeWindowsNativeFilename(urlDescription);
+				if (f!=null) return convertFileToURL(f);
+			}
+
+			if (URISchemeType.RESOURCE.isScheme(urlDescription)) {
+				if (allowResourceSearch) {
+					String resourceName = urlDescription.substring(9);
+					url = Resources.getResource(resourceName);
+				}
+			}
+			else if (URISchemeType.FILE.isScheme(urlDescription)) {
+				File file = new File(URISchemeType.FILE.removeScheme(urlDescription));
+				try {
+					url = new URL(URISchemeType.FILE.name(), "", //$NON-NLS-1$
+							getFilePath(file));
+				}
+				catch (MalformedURLException e) {
+					//
+				}
+			}
+			else {
+				try {
+					url = new URL(urlDescription);
+				}
+				catch (MalformedURLException _) {
+					// ignore error
+				}
+			}
+
+			if (url==null) {
+				if (allowResourceSearch) {
+					url = Resources.getResource(urlDescription);
+				}
+
+				if (url==null && URISchemeType.RESOURCE.isScheme(urlDescription)) {
+					return null;
+				}
+
+				if (url==null && repliesFileURL) {
+					String urlPart = URISchemeType.removeAnyScheme(urlDescription);
+					// Try to parse a malformed JAR url:
+					// jar:{malformed-url}!/{entry}
+					if (URISchemeType.JAR.isScheme(urlDescription)) {
+						int idx = urlPart.indexOf(JAR_URL_FILE_ROOT);
+						if (idx>0) {
+							URL jarURL = convertStringToURL(urlPart.substring(0, idx), allowResourceSearch);
+							if (jarURL!=null) {
+								try {
+									url = toJarURL(jarURL, urlPart.substring(idx+2));
+								}
+								catch (MalformedURLException _) {
+									//
+								}
+							}
+						}
+					}
+
+					// Standard local file
+					if (url==null) {
+						try {
+							File file = new File(urlPart);
+							url = new URL(URISchemeType.FILE.name(), "", //$NON-NLS-1$ 
+									getFilePath(file));
+						}
+						catch (MalformedURLException e) {
+							// ignore error
+						}
+					}
+				}
+			}
+		}
+
+		return url;
+	}
+
+	/**
+	 * Make the given filename absolute from the given root if it is not already absolute.
+	 * <p>
+	 * <table border="1" width="100%">
+	 * <thead>
+	 * <tr>
+	 * <th><var>filename</var></th><th><var>current</var></th><th>Result</th>
+	 * </tr>
+	 * </thead>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>/path/to/file</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>path/to/file</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>/myroot/path/to/file</code></td>
+	 * </tr>
+	 * </table>
+	 *
+	 * @param filename is the name to make absolute.
+	 * @param current is the current directory which permits to make absolute.
+	 * @return an absolute filename.
+	 */
+	public static File makeAbsolute(File filename, File current) {
+		if (filename==null) return null;
+		if (current!=null && !filename.isAbsolute()) {
+			try {
+				return new File(current.getCanonicalFile(), filename.getPath());
+			}
+			catch(IOException _) {
+				return new File(current.getAbsoluteFile(), filename.getPath());
+			}
+		}
+		return filename;
+	}
+
+	/** Replies if the given URL is using a protocol which could be map to files.
+	 * 
+	 * @param url
+	 * @return <code>true</code> if the given url is a "file", "http", 
+	 * "https", "ftp", "ssh", "jar" or "resource", otherwise <code>false</code>.
+	 * @deprecated see {@link URISchemeType#isFileBasedScheme()} 
+	 */
+	@Deprecated
+	public static boolean isFileBasedURL(URL url) {
+		if (url!=null) {
+			return isFileBasedScheme(URISchemeType.getSchemeType(url));
+		}
+		return false;
+	}
+
+	/** Replies if the given URL scheme is using a protocol which could be map to files.
+	 * 
+	 * @param scheme
+	 * @return <code>true</code> if the given scheme is a "file", "http", 
+	 * "https", "ftp", "ssh", "jar" or "resource", otherwise <code>false</code>.
+	 * @since 5.0
+	 * @deprecated see {@link URISchemeType#isFileBasedScheme()}
+	 */
+	@Deprecated
+	public static boolean isFileBasedScheme(URISchemeType scheme) {
+		if (scheme!=null) {
+			return scheme.isFileBasedScheme();
+		}
+		return false;
+	}
+
+	/**
+	 * Make the given filename absolute from the given root if it is not already absolute. 
+	 * <p>
+	 * <table border="1" width="100%">
+	 * <thead>
+	 * <tr>
+	 * <th><var>filename</var></th><th><var>current</var></th><th>Result</th>
+	 * </tr>
+	 * </thead>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>file:/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>file:path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>file:path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>file:/path/to/file</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>file:path/to/file</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>file:/myroot/path/to/file</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>http://host.com/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>http://host.com/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>http://host.com/path/to/file</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>http://host.com/path/to/file</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>ftp://host.com/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>ftp://host.com/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>ftp://host.com/path/to/file</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>ftp://host.com/path/to/file</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>ssh://host.com/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>ssh://host.com/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>ssh://host.com/path/to/file</code></td>
+	 * <td><code>/myroot</code></td>
+	 * <td><code>ssh://host.com/path/to/file</code></td>
+	 * </tr>
+	 * </table>
+	 *
+	 * @param filename is the name to make absolute.
+	 * @param current is the current directory which permits to make absolute.
+	 * @return an absolute filename.
+	 */
+	public static URL makeAbsolute(URL filename, File current) {
+		try {
+			return makeAbsolute(filename, current==null ? null : current.toURI().toURL());
+		}
+		catch(MalformedURLException _) {
+			//
+		}
+		return filename;
+	}
+
+	/**
+	 * Make the given filename absolute from the given root if it is not already absolute. 
+	 * <p>
+	 * <table border="1" width="100%">
+	 * <thead>
+	 * <tr>
+	 * <th><var>filename</var></th><th><var>current</var></th><th>Result</th>
+	 * </tr>
+	 * </thead>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>file:path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>file:path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>file:path/to/file</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>file:/myroot/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>file:path/to/file</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>http://host.com/myroot/path/to/file</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>file:/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>file:/path/to/file</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>file:/path/to/file</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>http://host2.com/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>http://host2.com/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>http://host2.com/path/to/file</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>http://host2.com/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>http://host2.com/path/to/file</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>http://host2.com/path/to/file</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>ftp://host2.com/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>ftp://host2.com/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>ftp://host2.com/path/to/file</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>ftp://host2.com/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>ftp://host2.com/path/to/file</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>ftp://host2.com/path/to/file</code></td>
+	 * </tr>
+	 * </table>
+	 *
+	 * @param filename is the name to make absolute.
+	 * @param current is the current directory which permits to make absolute.
+	 * @return an absolute filename.
+	 */
+	public static URL makeAbsolute(URL filename, URL current) {
+		if (filename==null) return null;
+		URISchemeType scheme = URISchemeType.getSchemeType(filename);
+		switch(scheme) {
+		case JAR:
+			try {
+				URL jarUrl = getJarURL(filename);
+				jarUrl = makeAbsolute(jarUrl, current);
+				File jarFile = getJarFile(filename);
+				return toJarURL(jarUrl, jarFile);
+			}
+			catch(MalformedURLException _) {
+				// Ignore error
+			}
+			break;
+		case FILE:
+		{
+			File f = new File(filename.getFile());
+			if (!f.isAbsolute()) {
+				if (current!=null) {
+					return join(current, f);
+				}
+			}
+		}
+		break;
+		default:
+			// do not change the URL
+		}
+		return filename;
+	}
+
+	/**
+	 * Make the given filename absolute from the given root if it is not already absolute. 
+	 * <p>
+	 * <table border="1" width="100%">
+	 * <thead>
+	 * <tr>
+	 * <th><var>filename</var></th><th><var>current</var></th><th>Result</th>
+	 * </tr>
+	 * </thead>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>null</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>null</code></td>
+	 * </tr>
+	 * 
+	 * <tr>
+	 * <td><code>path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>file:path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>path/to/file</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>file:/myroot/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>path/to/file</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>http://host.com/myroot/path/to/file</code></td>
+	 * </tr>
+	 * 
+	 * 
+	 * <tr>
+	 * <td><code>/path/to/file</code></td>
+	 * <td><code>null</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>/path/to/file</code></td>
+	 * <td><code>file:/myroot</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td><code>/path/to/file</code></td>
+	 * <td><code>http://host.com/myroot</code></td>
+	 * <td><code>file:/path/to/file</code></td>
+	 * </tr>
+	 * </table>
+	 *
+	 * @param filename is the name to make absolute.
+	 * @param current is the current directory which permits to make absolute.
+	 * @return an absolute filename.
+	 * @since 5.0
+	 */
+	public static URL makeAbsolute(File filename, URL current) {
+		if (filename!=null) {
+			if (!filename.isAbsolute() && current!=null) {
+				return join(current, filename);
+			}
+			try {
+				return new URL(URISchemeType.FILE.toString()+
+						getFilePath(filename));
+			}
+			catch (MalformedURLException _) {
+				// ignore error
+			}
+		}
+		return null;
+	}
+
+	/** Replies the parent URL for the given URL.
+	 * 
+	 * @param url
+	 * @return the parent URL
+	 * @throws MalformedURLException 
+	 */
+	public static URL getParentURL(URL url) throws MalformedURLException {
+		if (url==null) return url;
+		String path = url.getPath();
+		String prefix, parentStr;
+
+		switch(URISchemeType.getSchemeType(url)) {
+		case JAR:
+		{
+			int index = path.indexOf(JAR_URL_FILE_ROOT);
+			assert(index>0);
+			prefix = path.substring(0,index+1);
+			path = path.substring(index+1);
+			parentStr = URL_PATH_SEPARATOR;
+		}
+		break;
+		case FILE:
+		{
+			prefix = null;
+			parentStr = ".."+URL_PATH_SEPARATOR; //$NON-NLS-1$
+		}
+		break;
+		default:
+		{
+			prefix = null;
+			parentStr = URL_PATH_SEPARATOR;
+		}
+		}
+
+		if (path==null || "".equals(path)) path = parentStr; //$NON-NLS-1$
+		int index = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR);
+		if (index==-1) path = parentStr;
+		else if (index==path.length()-1) {
+			index = path.lastIndexOf(URL_PATH_SEPARATOR_CHAR, index-1);
+			if (index==-1) path = parentStr;
+			else path = path.substring(0, index+1);
+		}
+		else path = path.substring(0, index+1);
+
+		if (prefix!=null)  path = prefix + path;
+
+		return new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+	}
+
+	/** Test if the given filename is a local filename and extract
+	 * the path component.
+	 * 
+	 * @param filename
+	 * @return the path
+	 */
+	private static String extractLocalPath(String filename) {
+		if (filename==null ) return null;
+		String fn = filename.toUpperCase();
+		if (fn.startsWith("FILE://")) //$NON-NLS-1$
+			fn = filename.substring(7);
+		else if (fn.startsWith("FILE:")) //$NON-NLS-1$
+			fn = filename.substring(5);
+		else
+			fn = filename;
+		return fn;
+	}
+
+	/** Replies if the given string contains a Windows&reg; native long filename.
+	 * <p>
+	 * Long filenames (LFN), spelled "long file names" by Microsoft Corporation, 
+	 * are Microsoft's way of implementing filenames longer than the 8.3, 
+	 * or short-filename, naming scheme used in Microsoft DOS in their modern 
+	 * FAT and NTFS filesystems. Because these filenames can be longer than the 
+	 * 8.3 filename, they can be more descriptive. Another advantage of this 
+	 * scheme is that it allows for use of *nix files ending in (e.g. .jpeg, 
+	 * .tiff, .html, and .xhtml) rather than specialized shortened names 
+	 * (e.g. .jpg, .tif, .htm, .xht).
+	 * <p>
+	 * The long filename system allows a maximum length of 255 UTF-16 characters,
+	 * including spaces and non-alphanumeric characters; excluding the following 
+	 * characters, which have special meaning within the command interpreter or 
+	 * the operating system kernel: <code>\</code> <code>/</code> <code>:</code>
+	 * <code>*</code> <code>?</code> <code>"</code> <code>&lt;</code>
+	 * <code>&gt;</code> <code>|</code>
+	 * 
+	 * @param filename
+	 * @return <code>true</code> if the given filename is a long filename,
+	 * otherwise <code>false</code>
+	 * @see #normalizeWindowsNativeFilename(String)
+	 */
+	public static boolean isWindowsNativeFilename(String filename) {
+		String fn = extractLocalPath(filename);
+		if (fn==null || fn.length()==0) return false;
+		Pattern pattern = Pattern.compile(WINDOW_NATIVE_FILENAME_PATTERN);
+		Matcher matcher = pattern.matcher(fn);
+		return matcher.matches();
+	}
+
+	/** Normalize the given string contains a Windows&reg; native long filename
+	 * and replies a Java-standard version.
+	 * <p>
+	 * Long filenames (LFN), spelled "long file names" by Microsoft Corporation, 
+	 * are Microsoft's way of implementing filenames longer than the 8.3, 
+	 * or short-filename, naming scheme used in Microsoft DOS in their modern 
+	 * FAT and NTFS filesystems. Because these filenames can be longer than the 
+	 * 8.3 filename, they can be more descriptive. Another advantage of this 
+	 * scheme is that it allows for use of *nix files ending in (e.g. .jpeg, 
+	 * .tiff, .html, and .xhtml) rather than specialized shortened names 
+	 * (e.g. .jpg, .tif, .htm, .xht).
+	 * <p>
+	 * The long filename system allows a maximum length of 255 UTF-16 characters,
+	 * including spaces and non-alphanumeric characters; excluding the following 
+	 * characters, which have special meaning within the command interpreter or 
+	 * the operating system kernel: <code>\</code> <code>/</code> <code>:</code>
+	 * <code>*</code> <code>?</code> <code>"</code> <code>&lt;</code>
+	 * <code>&gt;</code> <code>|</code>
+	 * 
+	 * @param filename
+	 * @return the normalized path or <code>null</code> if not a windows native path.
+	 * @see #isWindowsNativeFilename(String)
+	 */
+	public static File normalizeWindowsNativeFilename(String filename) {
+		String fn = extractLocalPath(filename);
+		if (fn!=null && fn.length()>0) {
+			Pattern pattern = Pattern.compile(WINDOW_NATIVE_FILENAME_PATTERN);
+			Matcher matcher = pattern.matcher(fn);
+			if (matcher.find()) {
+				return new File(fn.replace('\\', File.separatorChar));
+			}
+		}
+		return null;
+	}
+
+	/** Replies an URL for the given file and translate it into a
+	 * resource URL if the given file is inside the classpath.
+	 * 
+	 * @param file is the filename to translate.
+	 * @return the URL which is corresponding to file, or <code>null</code> if 
+	 * the url cannot be computed.
+	 */
+	public static URL convertFileToURL(File file) {
+		if (file==null) return null;
+		try {
+			File f = file;
+			if (isWindowsNativeFilename(file.toString())) {
+				f = normalizeWindowsNativeFilename(file.toString());
+				if (f==null) f = file;
+			}
+			URL url = f.toURI().toURL();
+			return toShortestURL(url);
+		}
+		catch (MalformedURLException e) {
+			return null;
+		}
+	}
+
+	/** Replies an URL for the given url and translate it into a
+	 * resource URL if the given file is inside the classpath.
+	 * 
+	 * @param url is the URL to make shortest.
+	 * @return the URL which is corresponding to file, or <code>null</code> if 
+	 * the url cannot be computed.
+	 * @since 4.0
+	 */
+	public static URL toShortestURL(URL url) {
+		if (url==null) return null;
+		String s = url.toExternalForm().replaceAll("/$", "");  //$NON-NLS-1$//$NON-NLS-2$
+		String sp;
+		Iterator<URL> classpath = ClasspathUtil.getClasspath();
+		URL path;
+
+		while (classpath.hasNext()) {
+			path = classpath.next();
+			sp = path.toExternalForm().replaceAll("/$", "");  //$NON-NLS-1$//$NON-NLS-2$
+			if (s.startsWith(sp)) {
+				StringBuilder buffer = new StringBuilder("resource:"); //$NON-NLS-1$
+				buffer.append(s.substring(sp.length()).replaceAll("^/", ""));  //$NON-NLS-1$//$NON-NLS-2$
+				try {
+					return new URL(buffer.toString());
+				}
+				catch (MalformedURLException e) {
+					//
+				}
+			}
+		}
+
+		return url;
+	}
+
+	/**
+	 * Make the given filename relative to the given root path.
+	 *
+	 * @param filenameToMakeRelative is the name to make relative.
+	 * @param rootPath is the root path from which the relative path will be set.
+	 * @return a relative filename.
+	 * @throws IOException when is is impossible to retreive canonical paths.
+	 */
+	public static File makeRelative(File filenameToMakeRelative, File rootPath) throws IOException {
+		return makeRelative(filenameToMakeRelative, rootPath, true);
+	}
+	
+	/**
+	 * Make the given filename relative to the given root path.
+	 *
+	 * @param filenameToMakeRelative is the name to make relative.
+	 * @param rootPath is the root path from which the relative path will be set.
+	 * @param appendCurrentDirectorySymbol indicates if "./" should be append at the
+	 * begining of the relative filename.
+	 * @return a relative filename.
+	 * @throws IOException when is is impossible to retreive canonical paths.
+	 */
+	private static File makeRelative(File filenameToMakeRelative, File rootPath, boolean appendCurrentDirectorySymbol) throws IOException {
+
+		if (filenameToMakeRelative==null || rootPath==null)
+			throw new IllegalArgumentException();
+
+		if (!filenameToMakeRelative.isAbsolute()) return filenameToMakeRelative;
+		if (!rootPath.isAbsolute()) return filenameToMakeRelative;
+
+		File root = rootPath.getCanonicalFile();
+		File dir = filenameToMakeRelative.getParentFile().getCanonicalFile();
+
+		String[] parts1 = split(dir);
+		String[] parts2 = split(root);
+
+		String relPath = makeRelative(parts1, parts2, filenameToMakeRelative.getName());
+
+		if (appendCurrentDirectorySymbol)
+			return new File(CURRENT_DIRECTORY, relPath);
+		return new File(relPath);
+	}
+
+	/**
+	 * Make the given filename relative to the given root path.
+	 *
+	 * @param filenameToMakeRelative is the name to make relative.
+	 * @param rootPath is the root path from which the relative path will be set.
+	 * @return a relative filename.
+	 * @throws IOException when is is impossible to retreive canonical paths.
+	 * @since 6.0
+	 */
+	public static File makeRelative(File filenameToMakeRelative, URL rootPath) throws IOException {
+		if (filenameToMakeRelative==null || rootPath==null)
+			throw new IllegalArgumentException();
+
+		if (!filenameToMakeRelative.isAbsolute()) return filenameToMakeRelative;
+
+		File dir = filenameToMakeRelative.getParentFile().getCanonicalFile();
+
+		String[] parts1 = split(dir);
+		String[] parts2 = split(rootPath);
+
+		String relPath = makeRelative(parts1, parts2, filenameToMakeRelative.getName());
+
+		return new File(CURRENT_DIRECTORY, relPath);
+	}
+
+	/**
+	 * Make the given filename relative to the given root path.
+	 *
+	 * @param filenameToMakeRelative is the name to make relative.
+	 * @param rootPath is the root path from which the relative path will be set.
+	 * @return a relative filename.
+	 * @throws IOException when is is impossible to retreive canonical paths.
+	 * @since 6.0
+	 */
+	public static File makeRelative(URL filenameToMakeRelative, URL rootPath) throws IOException {
+		if (filenameToMakeRelative==null || rootPath==null)
+			throw new IllegalArgumentException();
+
+		String basename = largeBasename(filenameToMakeRelative);
+		URL dir = dirname(filenameToMakeRelative);
+
+		String[] parts1 = split(dir);
+		String[] parts2 = split(rootPath);
+
+		String relPath = makeRelative(parts1, parts2, basename);
+
+		return new File(CURRENT_DIRECTORY, relPath);
+	}
+
+	private static String makeRelative(String[] parts1, String[] parts2, String basename) {
+		int firstDiff = -1;
+
+		for(int i=0; firstDiff<0 && i<parts1.length && i<parts2.length; i++) {
+			if (!parts1[i].equals(parts2[i])) {
+				firstDiff = i;
+			}
+		}
+
+		StringBuilder result = new StringBuilder();
+		if (firstDiff<0) {
+			firstDiff = Math.min(parts1.length, parts2.length);
+		}
+
+		for(int i=firstDiff; i<parts2.length; i++) {
+			if (result.length()>0) result.append(File.separator);
+			result.append(PARENT_DIRECTORY);
+		}
+
+		for(int i=firstDiff; i<parts1.length; i++) {
+			if (result.length()>0) result.append(File.separator);
+			result.append(parts1[i]);
+		}
+
+		if (result.length()>0) result.append(File.separator);
+		result.append(basename);
+
+		return result.toString();
+	}
+
+	/**
+	 * <p>
+	 * A canonical pathname is both absolute and unique.  This method maps 
+	 * the pathname to its unique form.  This typically involves removing redundant names
+	 * such as <tt>"."</tt> and <tt>".."</tt> from the pathname.
+	 * 
+	 * @param url is the URL to make canonical
+	 * @return the canonical form of the given URL.
+	 * @since 6.0
+	 */
+	public static URL makeCanonicalURL(URL url) {
+		if (url!=null) {
+			String[] pathComponents = url.getPath().split(Pattern.quote(URL_PATH_SEPARATOR));
+
+			List<String> canonicalPath = new LinkedList<>();
+			for(String component : pathComponents) {
+				if (!CURRENT_DIRECTORY.equals(component)) {
+					if (PARENT_DIRECTORY.equals(component)) {
+						if (!canonicalPath.isEmpty()) {
+							canonicalPath.remove(canonicalPath.size()-1);
+						}
+						else {
+							canonicalPath.add(component);
+						}
+					}
+					else {
+						canonicalPath.add(component);
+					}
+				}
+			}
+
+			StringBuilder newPathBuffer = new StringBuilder();
+			boolean isFirst = true;
+			for(String component : canonicalPath) {
+				if (!isFirst) {
+					newPathBuffer.append(URL_PATH_SEPARATOR_CHAR);
+				}
+				else {
+					isFirst = false;
+				}
+				newPathBuffer.append(component);
+			}
+
+			try {
+				URI uri = new URI(
+						url.getProtocol(), 
+						url.getUserInfo(),
+						url.getHost(),
+						url.getPort(), 
+						newPathBuffer.toString(),
+						url.getQuery(),
+						url.getRef());
+				return uri.toURL();
+			}
+			catch (MalformedURLException _) {
+				//
+			}
+			catch (URISyntaxException _) {
+				//
+			}
+
+			try {
+				return new URL(
+						url.getProtocol(), 
+						url.getHost(), 
+						newPathBuffer.toString());
+			}
+			catch (Throwable _) {
+				//
+			}
+		}
+		return url;
+	}
+	
+	private static String fileToURL(File file) {
+		return file.getPath().replace(File.separatorChar, '/');
+	}
+
+	/**
+	 * Create a zip file from the given input file.
+	 * If the input file is a directory, the content of the directory is zipped.
+	 * If the input file is a standard file, it is zipped.
+	 * 
+	 * @param input
+	 * @param output
+	 * @throws IOException
+	 * @since 6.2
+	 */
+	public static void zipFile(File input, OutputStream output) throws IOException {
+		ZipOutputStream zos = null;
+		try {
+			zos = new ZipOutputStream(output);
+
+			if (input==null) return;
+
+			LinkedList<File> candidates = new LinkedList<>();
+			candidates.add(input);
+
+			byte[] buffer = new byte[2048];
+			int len;
+			File file, relativeFile;
+			String zipFilename;
+
+			File rootDirectory = (input.isDirectory()) ? input : input.getParentFile();
+
+			while (!candidates.isEmpty()) {
+				file = candidates.removeFirst();
+				assert(file!=null);
+				
+				if (file.getAbsoluteFile().equals(rootDirectory.getAbsoluteFile()))
+					relativeFile = null;
+				else
+					relativeFile = makeRelative(file, rootDirectory, false);
+				
+				if (file.isDirectory()) {
+					if (relativeFile!=null) {
+						zipFilename = fileToURL(relativeFile)+"/"; //$NON-NLS-1$
+						ZipEntry zipEntry = new ZipEntry(zipFilename);
+						zos.putNextEntry(zipEntry);
+						zos.closeEntry();
+					}
+					candidates.addAll(Arrays.asList(file.listFiles()));
+				}
+				else if (relativeFile!=null) {
+					try (FileInputStream fis = new FileInputStream(file)) {
+						zipFilename = fileToURL(relativeFile);
+						ZipEntry zipEntry = new ZipEntry(zipFilename);
+						zos.putNextEntry(zipEntry);
+						while ((len=fis.read(buffer))>0) {
+							zos.write(buffer, 0, len);
+						}
+						zos.closeEntry();
+					}
+				}
+			}
+		}
+		finally {
+			if (zos!=null) zos.close();
+		}
+	}
+
+	/**
+	 * Unzip the given stream and write out the file in the output.
+	 * If the input file is a directory, the content of the directory is zipped.
+	 * If the input file is a standard file, it is zipped.
+	 * 
+	 * @param input
+	 * @param output
+	 * @throws IOException
+	 * @since 6.2
+	 */
+	public static void unzipFile(InputStream input, File output) throws IOException {
+		if (output==null) return;
+		output.mkdirs();
+		if (!output.isDirectory()) throw new IOException("not a directory: "+output); //$NON-NLS-1$
+		ZipInputStream zis = null;
+		try {
+			byte[] buffer = new byte[2048];
+			int len;
+			
+			zis = new ZipInputStream(input);
+			ZipEntry zipEntry = zis.getNextEntry();
+			while (zipEntry!=null) {
+				String name = zipEntry.getName();
+				File outFile = new File(output,name).getCanonicalFile();
+				if (zipEntry.isDirectory()) {
+					outFile.mkdirs();
+				}
+				else {
+					outFile.getParentFile().mkdirs();
+					try (FileOutputStream fos = new FileOutputStream(outFile)) {
+						while ((len=zis.read(buffer))>0) {
+							fos.write(buffer, 0, len);
+						}
+					}
+				}
+				zipEntry = zis.getNextEntry();
+			}
+		}
+		finally {
+			if (zis!=null) zis.close();
+		}
+	}
+
+	/**
+	 * Create a zip file from the given input file.
+	 * 
+	 * @param input
+	 * @param output
+	 * @throws IOException
+	 * @since 6.2
+	 */
+	public static void zipFile(File input, File output) throws IOException {
+		try (FileOutputStream fos = new FileOutputStream(output)) {
+			zipFile(input, fos);
+		}
+	}
+
+	/**
+	 * Unzip a file into the output directory.
+	 * 
+	 * @param input
+	 * @param output
+	 * @throws IOException
+	 * @since 6.2
+	 */
+	public static void unzipFile(File input, File output) throws IOException {
+		try (FileInputStream fis = new FileInputStream(input)) {
+			unzipFile(fis, output);
+		}
+	}
+
+	/** Create an empty directory in the default temporary-file directory, using
+	 * the given prefix and suffix to generate its name.  Invoking this method
+	 * is equivalent to invoking <code>{@link #createTempDirectory(java.lang.String,
+	 * java.lang.String, java.io.File)
+	 * createTempDirectory(prefix,&nbsp;suffix,&nbsp;null)}</code>.
+	 *
+	 * @param  prefix is the prefix string to be used in generating the file's
+	 *                    name; must be at least three characters long
+	 *
+	 * @param  suffix is the suffix string to be used in generating the file's
+	 *                    name; may be <code>null</code>, in which case the
+	 *                    suffix <code>".tmp"</code> will be used
+	 * @return  An abstract pathname denoting a newly-created empty file
+	 * @throws  IllegalArgumentException
+	 *          If the <code>prefix</code> argument contains fewer than three
+	 *          characters
+	 * @throws  IOException  If a file could not be created
+	 * @throws  SecurityException
+	 *          If a security manager exists and its <code>{@link
+	 *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
+	 *          method does not allow a file to be created
+	 * @since 6.2
+	 */
+	public static File createTempDirectory(String prefix, String suffix) throws IOException {
+		return createTempDirectory(prefix, suffix, null);
+	}
+
+	/** Creates a new empty directory in the specified directory, using the
+     * given prefix and suffix strings to generate its name.  If this method
+     * returns successfully then it is guaranteed that:
+     * <ol>
+     * <li> The directory denoted by the returned abstract pathname did not exist
+     *      before this method was invoked, and
+     * <li> Neither this method nor any of its variants will return the same
+     *      abstract pathname again in the current invocation of the virtual
+     *      machine.
+     * </ol>
+     * <p>
+     * This method provides only part of a temporary-file facility.  To arrange
+     * for a file created by this method to be deleted automatically, use the
+     * <code>{@link #deleteOnExit}</code> method.
+     *
+     * <p> The <code>prefix</code> argument must be at least three characters
+     * long.  It is recommended that the prefix be a short, meaningful string
+     * such as <code>"hjb"</code> or <code>"mail"</code>.  The
+     * <code>suffix</code> argument may be <code>null</code>, in which case the
+     * suffix <code>".tmp"</code> will be used.
+     *
+     * <p> To create the new directory, the prefix and the suffix may first be
+     * adjusted to fit the limitations of the underlying platform.  If the
+     * prefix is too long then it will be truncated, but its first three
+     * characters will always be preserved.  If the suffix is too long then it
+     * too will be truncated, but if it begins with a period character
+     * (<code>'.'</code>) then the period and the first three characters
+     * following it will always be preserved.  Once these adjustments have been
+     * made the name of the new file will be generated by concatenating the
+     * prefix, five or more internally-generated characters, and the suffix.
+     *
+     * <p> If the <code>directory</code> argument is <code>null</code> then the
+     * system-dependent default temporary-file directory will be used.  The
+     * default temporary-file directory is specified by the system property
+     * <code>java.io.tmpdir</code>.  On UNIX systems the default value of this
+     * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on
+     * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>.  A different
+     * value may be given to this system property when the Java virtual machine
+     * is invoked, but programmatic changes to this property are not guaranteed
+     * to have any effect upon the temporary directory used by this method.
+	 *
+	 * @param  prefix is the prefix string to be used in generating the file's
+	 *                    name; must be at least three characters long
+	 *
+	 * @param  suffix is the suffix string to be used in generating the file's
+	 *                    name; may be <code>null</code>, in which case the
+	 *                    suffix <code>".tmp"</code> will be used
+	 * @param  directory is the directory in which the file is to be created, or
+	 *                    <code>null</code> if the default temporary-file
+	 *                    directory is to be used
+	 * @return  An abstract pathname denoting a newly-created empty file
+	 * @throws  IllegalArgumentException
+	 *          If the <code>prefix</code> argument contains fewer than three
+	 *          characters
+	 * @throws  IOException  If a file could not be created
+	 * @throws  SecurityException
+	 *          If a security manager exists and its <code>{@link
+	 *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
+	 *          method does not allow a file to be created
+	 * @since 6.2
+	 */
+	public static File createTempDirectory(String prefix, String suffix, File directory) throws IOException {
+		if (prefix == null) throw new NullPointerException();
+		if (prefix.length() < 3)
+			throw new IllegalArgumentException("Prefix string too short"); //$NON-NLS-1$
+		String s = (suffix == null) ? ".tmp" : suffix; //$NON-NLS-1$
+		File targetDirectory;
+		if (directory == null) {
+			targetDirectory = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
+		}
+		else {
+			targetDirectory = directory;
+		}
+		File f;
+		do {
+			long n = RANDOM.nextLong();
+			if (n == Long.MIN_VALUE) {
+				n = 0;      // corner case
+			}
+			else {
+				n = Math.abs(n);
+			}
+			StringBuilder buffer = new StringBuilder();
+			buffer.append(prefix);
+			buffer.append(Long.toString(n));
+			buffer.append(s);
+			f = new File(targetDirectory, buffer.toString());
+		} 
+		while (!f.mkdirs());
+		return f;
+	}
+
+    /** Hook to recursively delete files on JVM exit. 
+	 * 
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 * @since 6.0
+	 */
+	private static class DeleteOnExitHook extends Thread {
+
+		private List<File> filesToDelete = null;
+
+		public DeleteOnExitHook() {
+			setName("DeleteOnExitHook"); //$NON-NLS-1$
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void run() {
+			synchronized(this) {
+				if (this.filesToDelete!=null) {
+					for(File f : this.filesToDelete) {
+						try {
+							delete(f);
+						}
+						catch(IOException e) {
+							// Ignore error
+						}
+					}
+					this.filesToDelete.clear();
+					this.filesToDelete = null;
+				}
+			}
+		}
+
+		/** Add a file to delete.
+		 * 
+		 * @param file
+		 */
+		public void add(File file) {
+			assert(file!=null);
+			synchronized(this) {
+				if (this.filesToDelete==null) {
+					this.filesToDelete = new LinkedList<>();
+					Runtime.getRuntime().addShutdownHook(this);
+				}
+				this.filesToDelete.add(file);
+			}
+		}
+
+		/** Remove a file to delete.
+		 * 
+		 * @param file
+		 */
+		public void remove(File file) {
+			synchronized(this) {
+				if (this.filesToDelete!=null) {
+					this.filesToDelete.remove(file);
+					if (this.filesToDelete.isEmpty()) {
+						this.filesToDelete = null;
+						Runtime.getRuntime().removeShutdownHook(this);
+					}
+				}
+			}
+		}
+
+	}
+
+}
+


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/FileSystem.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/LibraryLoader.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/LibraryLoader.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/LibraryLoader.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,427 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2009 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+/**
+ * This class provides more generic means for loading
+ * dynamical libraries.
+ * <p>
+ * The library loader may be enabled or not.
+ * When library loader is enable, it is able to
+ * retreive and load native libraries. When it is
+ * disable, it ignore all the loading queries. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class LibraryLoader {
+
+	private static volatile boolean DISABLE = false;
+	
+	/** Replies if this library loader is enable.
+	 * <p>
+	 * The library loader is able to load native libraries
+	 * when it is enable. Otherwise it ignore all the loading
+	 * queries.
+	 *
+	 * @return <code>true</code> if the library loader is enable,
+	 * otherwise <code>false</code>
+	 * @since 5.0
+	 */
+	public static boolean isEnable() {
+		return !DISABLE;
+	}
+	
+	/** Replies if this library loader is enable.
+	 * <p>
+	 * The library loader is able to load native libraries
+	 * when it is enable. Otherwise it ignore all the loading
+	 * queries.
+	 *
+	 * @param enable is <code>true</code> to allow this loader
+	 * to retreive native libraries, or <code>false</code> to
+	 * ignore all the loading queries.
+	 * @since 5.0
+	 */
+	public static void setEnable(boolean enable) {
+		DISABLE = !enable;
+	}
+
+	/**
+     * Loads a code file with the specified filename from the local file
+     * system as a dynamic library. The filename
+     * argument must be a complete path name.
+     * <p>
+     * The call <code>LibraryLoader.load(name)</code> is effectively equivalent
+     * to the call:
+     * <blockquote><pre>
+     * System.load(name)
+     * </pre></blockquote>
+     *
+     * @param filename is the file to load.
+     * @throws  SecurityException if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @throws  UnsatisfiedLinkError if the file does not exist.
+     * @throws  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#load(java.lang.String)
+     */
+    public static void load(String filename) {
+    	// Silently ignore loading query
+    	if (DISABLE) return;
+    	Runtime.getRuntime().load(filename);
+    }
+
+    /**
+     * Loads the system library specified by the <code>libname</code>
+     * argument. The manner in which a library name is mapped to the
+     * actual system library is system dependent.
+     * <p>
+     * The call <code>LibraryLoader.loadLibrary(name)</code> is effectively
+     * equivalent to the call
+     * <blockquote><pre>
+     * System.loadLibrary(name)
+     * </pre></blockquote>
+     *
+     * @param      libname   the name of the library.
+     * @throws  SecurityException  if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @throws  UnsatisfiedLinkError  if the library does not exist.
+     * @throws  NullPointerException if <code>libname</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#loadLibrary(java.lang.String)
+     */
+    public static void loadLibrary(String libname) {
+    	// Silently ignore loading query
+    	if (DISABLE) return;
+    	Runtime.getRuntime().loadLibrary(libname);
+    }
+
+    /**
+     * Loads a code file with the specified filename from the local file
+     * system as a dynamic library. The filename
+     * argument must be a complete path name.
+     * <p>
+     * The call <code>LibraryLoader.load(name)</code> is effectively equivalent
+     * to the call:
+     * <blockquote><pre>
+     * System.load(name.getAbsolutePath())
+     * </pre></blockquote>
+     *
+     * @param filename is the file to load.
+     * @throws  SecurityException if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @throws  UnsatisfiedLinkError if the file does not exist.
+     * @throws  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#load(java.lang.String)
+     */
+    public static void load(File filename) {
+    	// Silently ignore loading query
+    	if (DISABLE) return;
+    	Runtime.getRuntime().load(filename.getAbsolutePath());
+    }
+
+    /** Replies the URL for the specified library.
+     * 
+     * @param libName is the name of the library
+     * @return the URL where the specified library was located. 
+     */
+    public static URL findLibraryURL(String libName) {
+        return findLibraryURL(null,libName,null,null);
+    }
+    
+    /** Replies the URL for the specified library.
+     * <p>
+     * The call <code>LibraryLoader.findLibraryURL(path,name)</code> is effectively equivalent
+     * to the call:
+     * <blockquote><pre>
+     * getClassLoader().getResource(path+System.mapLibraryName(name))
+     * </pre></blockquote>
+     * 
+     * @param path is the resource's path where the library was located.
+     * @param libName is the name of the library
+     * @return the URL where the specified library was located. 
+     */
+    public static URL findLibraryURL(String path, String libName) {
+    	return findLibraryURL(path, libName, null, null);
+    }
+    
+    private static URL findLibraryURL(String path, String libName, String platform, String arch) {
+        ClassLoader cl = ClassLoaderFinder.findClassLoader();
+        assert(cl!=null);
+        String resourcePath = path;
+        if (resourcePath==null) resourcePath = ""; //$NON-NLS-1$
+        else if ((resourcePath.length()>0)&&(!resourcePath.endsWith("/"))) { //$NON-NLS-1$
+        	resourcePath += "/"; //$NON-NLS-1$
+        }
+        // Find the 64bits version of the DLL
+        String realLibName;
+        if (platform!=null) {
+        	StringBuilder buf = new StringBuilder(libName);
+        	buf.append("-"); //$NON-NLS-1$
+        	buf.append(platform);
+        	if (arch!=null) buf.append(arch);
+        	realLibName = System.mapLibraryName(buf.toString());
+        	int idx = realLibName.indexOf(libName);
+        	if (idx>0) realLibName = realLibName.substring(idx);
+        }
+        else {
+        	StringBuilder buf = new StringBuilder(libName);
+        	if (arch!=null) buf.append(arch);
+        	realLibName = System.mapLibraryName(buf.toString());
+        }
+        URL libRes = Resources.getResource(cl, resourcePath+realLibName);
+        if (libRes!=null) return libRes;
+        return Resources.getResource(cl,realLibName);
+    }
+
+    /**
+     * Loads a code file with the specified filename from the local file
+     * system as a dynamic library. The filename
+     * argument must be a complete path name.
+     *
+     * @param filename is the file to load.
+     * @throws IOException 
+     * @throws  SecurityException if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @throws  UnsatisfiedLinkError if the file does not exist.
+     * @throws  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#load(java.lang.String)
+     */
+    public static void load(URL filename) throws IOException {
+    	// Silently ignore loading query
+    	if (DISABLE) return;
+    	
+        if (URISchemeType.FILE.isURL(filename)) {
+        	try {
+        		load(new File(filename.toURI()));
+        	} 
+        	catch (URISyntaxException e) {
+        		throw new FileNotFoundException(filename.toExternalForm());
+        	}
+        }
+        else {
+    	  // Create a tmp file to receive the library code.
+    	  String libName = System.mapLibraryName("javaDynLib"); //$NON-NLS-1$
+    	  String suffix = ".dll"; //$NON-NLS-1$
+    	  String prefix = "javaDynLib"; //$NON-NLS-1$
+    	  int pos = libName.lastIndexOf('.');
+    	  if (pos>=0) {
+    		  suffix = libName.substring(pos);
+    		  prefix = libName.substring(0,pos);
+    	  }
+    	  File f = File.createTempFile(prefix,suffix);
+    	  
+    	  // Copy the library code into the local file  	    	  
+    	  try (
+    			  FileOutputStream outs = new FileOutputStream(f);
+    			  InputStream ins = filename.openStream()) {
+	    	  byte[] buffer = new byte[2048];
+	    	  int lu;
+	    	  while ((lu=ins.read(buffer))>0) {
+	    		  outs.write(buffer,0,lu);
+	    	  }
+    	  }
+
+    	  // Load the library from the local file
+    	  load(f);
+    	  
+    	  // Delete local file
+    	  f.deleteOnExit();
+        }
+    }
+    
+    /**
+     * Search and load the dynamic library which is fitting the
+     * current operating system (32 or 64bits operating system...).
+     * A 64 bits library is assumed to be named <code>libname64.dll</code>
+     * on Windows&reg; and <code>liblibname64.so</code> on Unix.
+     * A 32 bits library is assumed to be named <code>libname32.dll</code>
+     * on Windows&reg; and <code>liblibname32.so</code> on Unix.
+     * A library which could be ran either on 32 and 64 platforms is assumed
+     * to be named <code>libname.dll</code> on Windows&reg; and
+     * <code>liblibname.so</code> on Unix.
+     *
+     * @param libname is the name of the library.
+     * @throws IOException 
+     * @throws  SecurityException if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @throws  UnsatisfiedLinkError if the file does not exist.
+     * @throws  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#load(java.lang.String)
+     */
+    public static void loadPlatformDependentLibrary(String libname) throws IOException {
+    	loadPlatformDependentLibrary(null,libname);
+    }
+
+	/** Replies the data model of the current operating system: 32 or 64 bits.
+	 * 
+	 * @return the integer which is corresponding to the data model, or <code>0</code> if
+	 * it could not be determined.
+	 */
+	static int getOperatingSystemArchitectureDataModel() {
+		String arch = System.getProperty("sun.arch.data.model"); //$NON-NLS-1$
+		if (arch!=null) {
+			try {
+				return Integer.parseInt(arch); 
+			}
+			catch(AssertionError e) {
+				throw e;
+			}
+			catch(Throwable _) {
+				//
+			}
+		}
+		return 0;
+	}
+
+    /**
+     * Search and load the dynamic library which is fitting the
+     * current operating system (32 or 64bits operating system...).
+     * A 64 bits library is assumed to be named <code>libname64.dll</code>
+     * on Windows&reg; and <code>liblibname64.so</code> on Unix.
+     * A 32 bits library is assumed to be named <code>libname32.dll</code>
+     * on Windows&reg; and <code>liblibname32.so</code> on Unix.
+     * A library which could be ran either on 32 and 64 platforms is assumed
+     * to be named <code>libname.dll</code> on Windows&reg; and
+     * <code>liblibname.so</code> on Unix.
+     *
+     * @param path is the resource's path where the library was located.
+     * @param libname is the name of the library.
+     * @throws IOException 
+     * @throws  SecurityException if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @throws  UnsatisfiedLinkError if the file does not exist.
+     * @throws  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#load(java.lang.String)
+     */
+    public static void loadPlatformDependentLibrary(String path, String libname) throws IOException {
+    	loadPlatformDependentLibrary(libname, null, path);
+    }
+    
+    private static URL getPlatformDependentLibrary(String[] paths, String libname, String platform) {
+    	URL url;
+    	int dataModel = getOperatingSystemArchitectureDataModel();
+    	for(String path : paths) {
+	    	// Load the 64 library
+	    	if (dataModel==64) {
+	    		url = findLibraryURL(path, libname, platform, "64"); //$NON-NLS-1$
+	    		if (url!=null) return url;
+	    	}
+	    	// Load the 32 library
+	    	else if (dataModel==32) {
+	    		url = findLibraryURL(path, libname, platform, "32"); //$NON-NLS-1$
+	    		if (url!=null) return url;
+	    	}
+	    	// Load the multi-platform library
+			url = findLibraryURL(path, libname, platform, null);
+			if (url!=null) return url;
+    	}
+    	return null;
+    }
+
+    /**
+     * Search and load the dynamic library which is fitting the
+     * current operating system (32 or 64bits operating system...).
+     * A 64 bits library is assumed to be named <code>libname64.dll</code>
+     * on Windows&reg; and <code>liblibname64.so</code> on Unix.
+     * A 32 bits library is assumed to be named <code>libname32.dll</code>
+     * on Windows&reg; and <code>liblibname32.so</code> on Unix.
+     * A library which could be ran either on 32 and 64 platforms is assumed
+     * to be named <code>libname.dll</code> on Windows&reg; and
+     * <code>liblibname.so</code> on Unix.
+     *
+     * @param libname is the name of the library.
+     * @param platform is the name of the current OS platform.
+     * @param paths are the resource's paths where the library was located.
+     * @throws IOException 
+     * @throws  SecurityException if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @throws  UnsatisfiedLinkError if the file does not exist.
+     * @throws  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#load(java.lang.String)
+     */
+    static void loadPlatformDependentLibrary(String libname, String platform, String... paths) throws IOException {    
+    	URL url;
+    	// Package version (according to Maven module)
+    	url = getPlatformDependentLibrary(paths, libname, null);
+    	if (url!=null) {
+			try {
+				load(url);
+				// library loaded
+				return;
+			}
+			catch(AssertionError e) {
+				throw e;
+			}
+			catch(Throwable e) {
+				System.err.println("could not load "+url); //$NON-NLS-1$
+				e.printStackTrace();
+			}
+    	}
+    	// Eclipse version  (according to Maven module)
+    	if (platform!=null) {
+        	url = getPlatformDependentLibrary(paths, libname, platform);
+        	if (url!=null) {
+    			try {
+    				load(url);
+    				// library loaded
+    				return;
+    			}
+				catch(AssertionError e) {
+					throw e;
+				}
+    			catch(Throwable e) {
+    				System.err.println("could not load "+url); //$NON-NLS-1$
+    				e.printStackTrace();
+    			}
+        	}
+    	}
+    	
+		// System-based loading
+		loadLibrary(libname);
+    }
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/LibraryLoader.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/MACNumber.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/MACNumber.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/MACNumber.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,384 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2010 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/** A MACNumber is the unique number associated to a network interface.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @see NetworkInterface
+ * @since 4.2
+ */
+public final class MACNumber {
+	
+	/**
+	 * Character that is used as separator inside MAC addresses.
+	 */
+	public static final char MACNUMBER_SEPARATOR = '/';
+
+	/** Parse the specified string an repleis the corresponding MAC numbers.
+	 * 
+	 * @param addresses is the string to parse
+	 * @return a list of addresses.
+	 * @throws IllegalArgumentException is the argument has not the right syntax. 
+	 */
+	public static MACNumber[] parse(String addresses) {
+		if ((addresses==null)||("".equals(addresses))) return new MACNumber[0]; //$NON-NLS-1$
+		String[] adrs = addresses.split(Pattern.quote(Character.toString(MACNUMBER_SEPARATOR)));
+		ArrayList<MACNumber> list = new ArrayList<>();
+		for (String adr : adrs) {
+			list.add(new MACNumber(adr));
+		}
+		MACNumber[] tab = new MACNumber[list.size()];
+		list.toArray(tab);
+		list.clear();
+		return tab;
+	}
+
+	/** Parse the specified string an repleis the corresponding MAC numbers.
+	 * 
+	 * @param addresses is the string to parse
+	 * @return a list of addresses.
+	 * @throws IllegalArgumentException is the argument has not the right syntax. 
+	 */
+	public static String[] parseAsString(String addresses) {
+		if ((addresses==null)||("".equals(addresses))) return new String[0]; //$NON-NLS-1$
+		String[] adrs = addresses.split(Pattern.quote(Character.toString(MACNUMBER_SEPARATOR)));
+		ArrayList<String> list = new ArrayList<>();
+		for (String adr : adrs) {
+			list.add(new MACNumber(adr).toString());
+		}
+		String[] tab = new String[list.size()];
+		list.toArray(tab);
+		list.clear();
+		return tab;
+	}
+
+	/** Join the specified MAC numbers to reply a string.
+	 * 
+	 * @param addresses is the list of mac addresses to join.
+	 * @return the joined string. 
+	 */
+	public static String join(MACNumber... addresses) {
+		if ((addresses==null)||(addresses.length==0)) return null;
+		StringBuilder buf = new StringBuilder();
+		for (MACNumber number : addresses) {
+			if (buf.length()>0) buf.append(MACNUMBER_SEPARATOR);
+			buf.append(number);
+		}
+		return buf.toString();
+	}
+
+	/** Get all of the ethernet addresses associated with the local machine.
+	 * <p>
+	 * This method will try and find ALL of the ethernet adapters
+	 * which are currently available on the system. This is heavily OS
+	 * dependent and may not be supported on all platforms. When not
+	 * supported, you should still get back a collection with the {@link
+	 * #getPrimaryAdapter primary adapter} in it.
+	 *
+	 * @return the list of MAC numbers associated to the physical devices.
+	 * @see #getPrimaryAdapter
+	 */
+	public static Collection<MACNumber> getAllAdapters() {
+		List<MACNumber> av = new ArrayList<>();
+		try {
+			Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+			if (interfaces!=null) {
+				NetworkInterface inter;
+				while (interfaces.hasMoreElements()) {
+					inter = interfaces.nextElement();
+					try {
+						byte[] addr = inter.getHardwareAddress();
+						if (addr!=null) av.add(new MACNumber(addr));
+					}
+					catch(SocketException _) {
+						//
+					}
+				}
+			}
+		}
+		catch(SocketException _) {
+			//
+		}
+		return av;
+	}
+
+	/** Get all of the internet address and ethernet address mappings
+	 * on the local machine.
+	 * <p>
+	 * This method will try and find ALL of the ethernet adapters
+	 * which are currently available on the system. This is heavily OS
+	 * dependent and may not be supported on all platforms. When not
+	 * supported, you should still get back a collection with the {@link
+	 * #getPrimaryAdapterAddresses primary adapter} in it.
+	 *
+	 * @return the map internet address and ethernet address mapping.
+	 * @see #getPrimaryAdapterAddresses
+	 */
+	public static Map<InetAddress, MACNumber> getAllMappings() {
+		Map<InetAddress,MACNumber> av = new HashMap<>();
+		try {
+			Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+			if (interfaces!=null) {
+				NetworkInterface inter;
+				MACNumber mac;
+				InetAddress inet;
+				while (interfaces.hasMoreElements()) {
+					inter = interfaces.nextElement();
+					try {
+						byte[] addr = inter.getHardwareAddress();
+						if (addr!=null) {
+							mac = new MACNumber(addr);
+							Enumeration<InetAddress> inets = inter.getInetAddresses();
+							while (inets.hasMoreElements()) {
+								inet = inets.nextElement();
+								av.put(inet, mac);
+							}
+						}
+					}
+					catch(SocketException _) {
+						//
+					}
+				}
+			}
+		}
+		catch(SocketException _) {
+			//
+		}
+		return av;
+	}
+
+	/** Try to determine the primary ethernet address of the machine.
+	 * 
+	 * @return the primary MACNumber or <code>null</code>
+	 */
+	public static MACNumber getPrimaryAdapter() {
+		try {
+			Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+			if (interfaces!=null) {
+				NetworkInterface inter;
+				while (interfaces.hasMoreElements()) {
+					inter = interfaces.nextElement();
+					try {
+						byte[] addr = inter.getHardwareAddress();
+						if (addr!=null) return new MACNumber(addr);
+					}
+					catch(SocketException _) {
+						//
+					}
+				}
+			}
+		}
+		catch(SocketException _) {
+			//
+		}
+		return null;
+	}
+
+	/** Try to determine the primary ethernet address of the machine and
+	 * replies the associated internet addresses.
+	 * 
+	 * @return the internet addresses of the primary network interface.
+	 */
+	public static Collection<InetAddress> getPrimaryAdapterAddresses() {
+		try {
+			Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+			if (interfaces!=null) {
+				NetworkInterface inter;
+				while (interfaces.hasMoreElements()) {
+					inter = interfaces.nextElement();
+					try {
+						byte[] addr = inter.getHardwareAddress();
+						if (addr!=null) {
+							Collection<InetAddress> inetList = new ArrayList<>();
+							Enumeration<InetAddress> inets = inter.getInetAddresses();
+							while (inets.hasMoreElements()) {
+								inetList.add(inets.nextElement());
+							}
+							
+							return inetList;
+						}
+					}
+					catch(SocketException _) {
+						//
+					}
+				}
+			}
+		}
+		catch(SocketException _) {
+			//
+		}
+		return null;
+	}
+
+	/** Constant ethernet address object which has the "null address".
+	 * 
+	 * <p>This constant can be used when you want a non-null
+	 * MACAddress object reference, but want a invalid (or null)
+	 * MAC address contained.
+	 * 
+	 * @see #isNull()
+	 */
+	public static final MACNumber NULL = new MACNumber();
+
+	/**
+	 * Content of the MAC address.
+	 */
+	private final byte[] bytes;
+
+
+	/** Constructs object with "null values" (address of "0:0:0:0:0:0").
+	 */
+	public MACNumber() {
+		this.bytes = new byte[6];
+	}
+
+	/** Build a MACNumber from a set of bytes.
+	 * The byte array must contains 6 elements.
+	 * 
+	 * @param bytes is the list of bytes from which the address must be built.
+	 * @throws IllegalArgumentException if the byte array does not corresponds to a valid MAC Number.
+	 */
+	public MACNumber(byte[] bytes) {
+		if (bytes == null || bytes.length != 6) {
+			throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+		}
+		this.bytes = new byte[6];
+		System.arraycopy(bytes, 0, this.bytes, 0, 6);
+	}
+
+	/** Build a MACNumber from a string representation.
+	 * 
+	 * @param address is the string representation of a MAC address
+	 * @throws IllegalArgumentException if the byte array does not corresponds to a valid MAC Number.
+	 * @see #toString()
+	 */
+	public MACNumber(String address) {
+		if (address==null)
+			throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+		String[] parts = address.split(Pattern.quote(":")); //$NON-NLS-1$
+		if (parts.length!=6)
+			throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+		this.bytes = new byte[6];
+		try {
+			int val;
+			for(int i=0; i<6; i++) {
+				val = Integer.parseInt(parts[i],16);
+				this.bytes[i] = (byte)val;
+			}
+		}
+		catch(Exception _) {
+			throw new IllegalArgumentException("mac address not 6 bytes long"); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @param o {@inheritDoc}
+	 * @return {@inheritDoc}
+	 */
+	@Override
+	public boolean equals(Object o) {
+		if (!(o instanceof MACNumber)) return false;
+
+		byte[] bao = ((MACNumber) o).bytes;
+		if (bao.length != this.bytes.length) return false;
+
+		for (int i = 0; i < bao.length; i++) if (bao[i] != this.bytes[i]) return false;
+		return true;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @return {@inheritDoc}
+	 */
+	@Override
+	public int hashCode() {
+		int blen = this.bytes.length;
+		if (blen == 0) return 0;
+
+		int hc = this.bytes[0];
+		for (int i = 1; i < blen; i++) {
+			hc *= 37;
+			hc += this.bytes[i];
+		}
+		return hc;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @return {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		int blen = this.bytes.length;
+		StringBuilder sb = new StringBuilder(blen*3);
+		for (int i = 0; i < blen; i++) {
+			int lo = this.bytes[i];
+			int hi = ((lo >> 4) & 0xF);
+			lo &= 0xF;
+			if (i != 0) sb.append(':');
+			sb.append(Character.forDigit(hi,16));
+			sb.append(Character.forDigit(lo,16));
+		}
+		return sb.toString();
+	}
+
+	/** Replies if all the MAC address number are equal to zero.
+	 * 
+	 * @return <code>true</code> if all the bytes are zero.
+	 * @see #NULL
+	 */
+	public boolean isNull() {
+		for (int i = 0; i < this.bytes.length; i++) {
+			if (this.bytes[i]!=0) return false;
+		}
+		return true;
+	}
+
+	/** Replies the bytes that compose this MAC Address.
+	 * 
+	 * @return a copy of the current bytes.
+	 */
+	public byte[] getBytes() {
+		return this.bytes.clone();
+	}
+	
+}
+


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/MACNumber.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystem.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystem.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystem.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,373 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import org.arakhne.vmutil.locale.Locale;
+
+/**
+ * This is a list of supported operating system.  
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public enum OperatingSystem {
+
+	/**
+	 * Windows&reg;.
+	 */
+	WIN,
+
+	/**
+	 * Linux distribution.
+	 */
+	LINUX,
+
+	/**
+	 * Android Linux distribution.
+	 * 
+	 * @since 7.0
+	 */
+	ANDROID,
+
+	/**
+	 * Solaris&reg;.
+	 */
+	SOLARIS,
+
+	/**
+	 * Mac OS X&reg;.
+	 */
+	MACOSX,
+
+	/**
+	 * Free BSD.
+	 */
+	FREEBSD,
+
+	/**
+	 * Net BSD.
+	 */
+	NETBSD,
+
+	/**
+	 * Standard BSD.
+	 */
+	BSD,
+
+	/**
+	 * Open BSD.
+	 */
+	OPENBSD,
+
+	/**
+	 * AIX&reg;.
+	 */
+	AIX,
+
+	/**
+	 * HPUX&reg;.
+	 */
+	HPUX,
+
+	/**
+	 * Unknown operating systems.
+	 */
+	OTHER;
+
+	private static final String NULL = new String();
+	private static String osSerialNumber = null;
+	private static String osUUID = null;
+	private static OperatingSystem currentOSInstance = null;
+
+	/** Replies the type of identification found on this operating system.
+	 * 
+	 * @return the type of identification found on this operating system.
+	 */
+	public static OperatingSystemIdentificationType getIdentificationType() {
+		if (nativeWrapper==null)
+			return OperatingSystemIdentificationType.BIOS;
+		return nativeWrapper.getIdentificationType();
+	}
+
+	/** Replies if the current OperatingSystem constant is corresponding
+	 * to the current operating system.
+	 * 
+	 * @return <code>true</code> if the current operating system corresponds to this constant,
+	 * otherwise <code>false</code>
+	 */
+	public boolean isCurrentOS() {
+		return getCurrentOS()==this;
+	}
+
+	/** Replies of this OS is Unix compliant.
+	 * 
+	 * @return <code>true</code> if this constant corresponds to a Unix-like operating system,
+	 * otherwise <code>false</code>
+	 */
+	public boolean isUnixCompliant() {
+		switch(this) {
+		case AIX:
+		case BSD:
+		case FREEBSD:
+		case HPUX:
+		case LINUX:
+		case ANDROID:
+		case MACOSX:
+		case NETBSD:
+		case OPENBSD:
+		case SOLARIS:
+			return true;
+		case WIN:
+		case OTHER:
+			return false;
+		default:
+		}
+		return false;
+	}
+
+
+	/** Replies the name of the current OS.
+	 * 
+	 * @return the name of the current operating system.
+	 * @see System#getProperty(java.lang.String)
+	 */
+	public static String getCurrentOSName() {
+		return System.getProperty("os.name"); //$NON-NLS-1$
+	}
+
+	/** Replies the version of the current OS.
+	 * 
+	 * @return the version of the current operating system.
+	 * @see System#getProperty(java.lang.String)
+	 */
+	public static String getCurrentOSVersion() {
+		return System.getProperty("os.version"); //$NON-NLS-1$
+	}
+
+	/** Replies the current operating system.
+	 * 
+	 * @return the current operating system constant.
+	 */
+	public static OperatingSystem getCurrentOS() {
+		if (currentOSInstance!=null) return currentOSInstance;
+
+		String os = System.getProperty("os.name").trim().toLowerCase(); //$NON-NLS-1$
+
+		/* Let's try to figure canonical OS name, just in case some
+		 * JVMs use funny values (unlikely)
+		 */
+		if (os.indexOf("windows") >= 0) { //$NON-NLS-1$
+			return currentOSInstance=WIN;
+		}
+		else if (os.indexOf("linux") >= 0) { //$NON-NLS-1$
+			String vmName = System.getProperty("java.vm.name").trim().toLowerCase(); //$NON-NLS-1$
+			if (vmName.indexOf("dalvik") >= 0) { //$NON-NLS-1$
+				return currentOSInstance=ANDROID;
+			}
+			String runtimeName = System.getProperty("java.runtime.name").trim().toLowerCase(); //$NON-NLS-1$
+			if (runtimeName.indexOf("android") >= 0) { //$NON-NLS-1$
+				return currentOSInstance=ANDROID;
+			}
+			return currentOSInstance=LINUX;
+		}
+		else if ((os.indexOf("solaris") >= 0)|| //$NON-NLS-1$
+				(os.indexOf("sunos") >= 0)) { //$NON-NLS-1$
+			return currentOSInstance=SOLARIS;
+		}
+		else if ((os.indexOf("mac os x") >= 0)|| //$NON-NLS-1$
+				(os.indexOf("macosx") >= 0)) { //$NON-NLS-1$
+			return currentOSInstance=MACOSX;
+		}
+		else if (os.indexOf("bsd") >= 0) { //$NON-NLS-1$
+			if (os.indexOf("freebsd") >= 0) { //$NON-NLS-1$
+				return currentOSInstance=FREEBSD;
+			}
+			else if (os.indexOf("netbsd") >= 0) { //$NON-NLS-1$
+				return currentOSInstance=NETBSD;
+			}
+			else if (os.indexOf("openbsd") >= 0) { //$NON-NLS-1$
+				return currentOSInstance=OPENBSD;
+			}
+			else { // default
+				return currentOSInstance=BSD;
+			}
+		}
+		else if (os.indexOf("aix") >= 0) { //$NON-NLS-1$
+			return currentOSInstance=AIX;
+		}
+		else if (os.indexOf("hp ux") >= 0) { //$NON-NLS-1$
+			return currentOSInstance=HPUX;
+		}
+		else {
+			return currentOSInstance=OTHER;
+		}
+	}
+
+	/** Replies the data model of the current operating system: 32 or 64 bits.
+	 * 
+	 * @return the integer which is corresponding to the data model, or <code>0</code> if
+	 * it could not be determined.
+	 */
+	public static int getOperatingSystemArchitectureDataModel() {
+		return LibraryLoader.getOperatingSystemArchitectureDataModel();
+	}
+
+	/** Replies if the current operating system is 64bit.
+	 * 
+	 * @return <code>true</code> if the operating system is 64bits, othewise
+	 * <code>false</code>
+	 */
+	public static boolean is64BitOperatingSystem() {
+		return getOperatingSystemArchitectureDataModel()==64;
+	}
+
+	/** Replies if the current operating system is 32bit.
+	 * 
+	 * @return <code>true</code> if the operating system is 32bits, othewise
+	 * <code>false</code>
+	 */
+	public static boolean is32BitOperatingSystem() {
+		int dataModel = getOperatingSystemArchitectureDataModel();
+		return dataModel==32 || dataModel==0;
+	}
+
+	/** Get the OS serial number.
+	 * <p>
+	 * This function does not allow to run any system command with
+	 * the super-user rights, and it disable any additional GUI.
+	 * 
+	 * @return the serial number associated to the current operating system.
+	 */
+	public static String getOSSerialNumber() {
+		return getOSSerialNumber(false, false);
+	}
+
+	/** Get the OS serial number.
+	 * 
+	 * @param enableSuperUser indicates if the super-user commands are enabled or not.
+	 * @param enableGUI indicates if any additional GUI could be opened, or not.
+	 * @return the serial number associated to the current operating system.
+	 * @sine 6.1
+	 */
+	public static String getOSSerialNumber(boolean enableSuperUser, boolean enableGUI) {
+		if (osSerialNumber==null) {
+			if (nativeWrapper!=null)
+				osSerialNumber = nativeWrapper.getOSSerialNumber(enableSuperUser, enableGUI);
+			if (osSerialNumber==null)
+				osSerialNumber = NULL;
+		}
+		return osSerialNumber==NULL ? null : osSerialNumber;
+	}
+
+	/** Get the OS UUID.
+	 * <p>
+	 * This function does not allow to run any system command with
+	 * the super-user rights, and it disable any additional GUI.
+	 * 
+	 * @return an unique identifier for the current operating system.
+	 */
+	public static String getOSUUID() {
+		return getOSUUID(false, false);
+	}
+
+	/** Get the OS UUID.
+	 * 
+	 * @param enableSuperUser indicates if the super-user commands are enabled or not.
+	 * @param enableGUI indicates if any additional GUI could be opened, or not.
+	 * @return an unique identifier for the current operating system.
+	 * @since 6.1
+	 */
+	public static String getOSUUID(boolean enableSuperUser, boolean enableGUI) {
+		if (osUUID==null) {
+			if (nativeWrapper!=null)
+				osUUID = nativeWrapper.getOSUUID(enableSuperUser, enableGUI);
+			if (osUUID==null)
+				osUUID = NULL;
+		}
+		return osUUID==NULL ? null : osUUID;
+	}
+
+	private static OperatingSystemWrapper nativeWrapper; 
+
+	static {
+		OperatingSystemIdentificationType type = OperatingSystemIdentificationType.BIOS;
+		nativeWrapper = null;
+
+		switch(getCurrentOS()) {
+		case BSD:
+		case FREEBSD:
+		case NETBSD:
+		case OPENBSD:
+		case MACOSX:
+			nativeWrapper = new OperatingSystemDiskUtilWrapper();
+			break;
+		case LINUX:
+			nativeWrapper = new OperatingSystemUDevWrapper();
+			break;
+		case ANDROID:
+			nativeWrapper = new OperatingSystemAndroidWrapper();
+			break;
+		case WIN:
+			type = OperatingSystemIdentificationType.OPERATING_SYSTEM;
+			break;
+		case AIX:
+		case HPUX:
+		case SOLARIS:
+		case OTHER:
+		default:
+		}
+
+		Throwable error = null;
+		if (nativeWrapper==null) {
+			try {
+				LibraryLoader.loadPlatformDependentLibrary(
+						"josuuid", //$NON-NLS-1$
+						System.getProperty("os.name").trim().toLowerCase(), //$NON-NLS-1$
+						"org/arakhne/vmutil"); //$NON-NLS-1$
+			}
+			catch (Throwable e) {
+				error = e;
+			}
+			if (error==null) {
+				nativeWrapper = new OperatingSystemNativeWrapper(type);
+			}
+		}
+
+		if (nativeWrapper==null) {
+			try {
+				String errorMsg = Locale.getString("NATIVE_NOT_SUPPORTED"); //$NON-NLS-1$
+				if (errorMsg!=null && !"".equals(errorMsg)) { //$NON-NLS-1$
+					System.err.println(errorMsg);
+				}
+				else {
+					if (error!=null) error.printStackTrace();
+				}
+			}
+			catch(Throwable e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystem.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemAndroidWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemAndroidWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemAndroidWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,98 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Wrapper to the Android functions.
+ * This class was introduced to avoid to kill the current
+ * JVM even if the native functions are unloadable.
+ * In this way, on operating system without the support
+ * for the native libs is still able to be run. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 7.0
+ */
+class OperatingSystemAndroidWrapper extends AbstractOperatingSystemWrapper {
+
+	/**
+	 */
+	public OperatingSystemAndroidWrapper() {
+		//
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getOSSerialNumber(boolean enableSuperUser, boolean enableGUI) {
+		String serial;
+		try {
+			Class<?> secureClass = Android.getSystemSettingsClass();
+
+			Method getStringMethod = secureClass.getMethod("getString", Android.getContextResolverClass(), String.class); //$NON-NLS-1$
+
+			Field androidIdField = secureClass.getField("ANDROID_ID"); //$NON-NLS-1$
+			Object androidId = androidIdField.get(null);
+
+			serial = (String)getStringMethod.invoke(null, Android.getContextResolver(), androidId);
+		}
+		catch (Throwable _) {
+			serial = null;
+		}
+		return serial;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getOSUUID(boolean enableSuperUser, boolean enableGUI) {
+		String serial;
+		try {
+			Class<?> secureClass = Android.getSecureSettingsClass();
+
+			Method getStringMethod = secureClass.getMethod("getString", Android.getContextResolverClass(), String.class); //$NON-NLS-1$
+
+			Field androidIdField = secureClass.getField("ANDROID_ID"); //$NON-NLS-1$
+			Object androidId = androidIdField.get(null);
+
+			serial = (String)getStringMethod.invoke(null, Android.getContextResolver(), androidId);
+		}
+		catch (Throwable _) {
+			serial = null;
+		}
+		return serial;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public OperatingSystemIdentificationType getIdentificationType() {
+		return OperatingSystemIdentificationType.OPERATING_SYSTEM;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemAndroidWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemDiskUtilWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemDiskUtilWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemDiskUtilWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,87 @@
+/* 
+  * $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+
+/**
+ * Wrapper to the MacOS functions.
+ * This class was introduced to avoid to kill the current
+ * JVM even if the native functions are unloadable.
+ * In this way, on operating system without the support
+ * for the native libs is still able to be run. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.3
+ */
+class OperatingSystemDiskUtilWrapper extends AbstractOperatingSystemWrapper {
+
+	/**
+	 */
+	public OperatingSystemDiskUtilWrapper() {
+		//
+	}
+
+	private static String runDiskUtil(File f, String key) {
+		String r = runCommand(
+				"diskutil", //$NON-NLS-1$
+				"info", //$NON-NLS-1$
+				f.toString());
+		return cut(":", 1, grep(key+":", r));  //$NON-NLS-1$//$NON-NLS-2$
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getOSSerialNumber(boolean enableSuperUser, boolean enableGUI) {
+		File f;
+		f = new File("/dev/disk0s1"); //$NON-NLS-1$
+		if (f.exists()) {
+			return runDiskUtil(f, "Volume UUID"); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getOSUUID(boolean enableSuperUser, boolean enableGUI) {
+		File f;
+		f = new File("/dev/disk0s1"); //$NON-NLS-1$
+		if (f.exists()) {
+			return runDiskUtil(f, "Volume UUID"); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public OperatingSystemIdentificationType getIdentificationType() {
+		return OperatingSystemIdentificationType.HARD_DISK;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemDiskUtilWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemIdentificationType.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemIdentificationType.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemIdentificationType.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,60 @@
+/* 
+  * $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+/**
+ * Types of identification of the operating system.  
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.3
+ */
+public enum OperatingSystemIdentificationType {
+
+	/**
+	 * Identification comes from the BIOS.
+	 */
+	BIOS,
+	
+	/**
+	 * Identification comes from the Operating System itself.
+	 */
+	OPERATING_SYSTEM,
+	
+	/**
+	 * Identification comes from the hard disk.
+	 */
+	HARD_DISK,
+
+	/**
+	 * Identification comes from the network card.
+	 */
+	NETWORK_CARD,
+
+	/**
+	 * Identification comes from a dongle.
+	 */
+	DONGLE;
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemIdentificationType.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,98 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2009, 2011 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.FileNotFoundException;
+
+
+/**
+ * This class print on the standard output several informations
+ * about your operating system.
+ * These informations are extracted by the Java or the native
+ * libraries from <code>arakhneVmutils</code>.  
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class OperatingSystemInfo {
+
+	private static void showTitle(String title) {
+		System.out.print("#######################################\n# "); //$NON-NLS-1$
+		System.out.println(title);
+		System.out.println("#######################################"); //$NON-NLS-1$
+	}
+	
+	private static void showPropertyValue(String name) {
+		showValue(name, System.getProperty(name));
+	}
+	
+	private static void showValue(String name, Object value) {
+		System.out.print(name);
+		System.out.print(" = "); //$NON-NLS-1$
+		System.out.println((value==null) ? null : value.toString());
+	}
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		
+		showTitle("JRE Properties"); //$NON-NLS-1$
+		
+		showPropertyValue("java.class.path"); //$NON-NLS-1$
+		showPropertyValue("java.library.path"); //$NON-NLS-1$
+		showPropertyValue("java.home"); //$NON-NLS-1$
+		showPropertyValue("os.name"); //$NON-NLS-1$
+		showPropertyValue("os.version"); //$NON-NLS-1$
+		showPropertyValue("file.separator"); //$NON-NLS-1$
+		showPropertyValue("path.separator"); //$NON-NLS-1$
+		showPropertyValue("sun.arch.data.model"); //$NON-NLS-1$
+		showPropertyValue("user.dir"); //$NON-NLS-1$
+		showPropertyValue("user.name"); //$NON-NLS-1$
+		showPropertyValue("user.home"); //$NON-NLS-1$
+		
+		showTitle("FileSystem"); //$NON-NLS-1$
+
+		showValue("getUserHomeDirectoryName()", FileSystem.getUserHomeDirectoryName()); //$NON-NLS-1$
+		try {
+			showValue("getUserHomeDirectory()", FileSystem.getUserHomeDirectory()); //$NON-NLS-1$
+		}
+		catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
+
+		showTitle("OperatingSystem"); //$NON-NLS-1$
+		
+		showValue("getCurrentOSName()", OperatingSystem.getCurrentOSName()); //$NON-NLS-1$
+		showValue("getCurrentOSVersion()", OperatingSystem.getCurrentOSVersion()); //$NON-NLS-1$
+		showValue("getOSSerialNumber()", OperatingSystem.getOSSerialNumber()); //$NON-NLS-1$
+		showValue("getOSUUID()", OperatingSystem.getOSUUID()); //$NON-NLS-1$
+		showValue("getIdentificationType()", OperatingSystem.getIdentificationType().name()); //$NON-NLS-1$
+		showValue("getOperatingSystemArchitectureDataModel()", Integer.toString(OperatingSystem.getOperatingSystemArchitectureDataModel())); //$NON-NLS-1$
+		showValue("getCurrentOS()", OperatingSystem.getCurrentOS().name()); //$NON-NLS-1$
+		showValue("is32BitOperatingSystem()", Boolean.toString(OperatingSystem.is32BitOperatingSystem())); //$NON-NLS-1$
+		showValue("is64BitOperatingSystem()", Boolean.toString(OperatingSystem.is64BitOperatingSystem())); //$NON-NLS-1$
+	}
+	
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemInfo.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemNativeWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemNativeWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemNativeWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,66 @@
+/* 
+  * $Id$
+ * 
+ * Copyright (C) 2011-12 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+/**
+ * Wrapper to the native functions.
+ * This class was introduced to avoid to kill the current
+ * JVM even if the native functions are unloadable.
+ * In this way, on operating system without the support
+ * for the native libs is still able to be run. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.0
+ */
+class OperatingSystemNativeWrapper implements OperatingSystemWrapper {
+
+	private final OperatingSystemIdentificationType type;
+	
+	/**
+	 * @param type is the type of identification supported by the wrapper.
+	 */
+	public OperatingSystemNativeWrapper(OperatingSystemIdentificationType type) {
+		this.type = type;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public native String getOSSerialNumber(boolean enableSuperUser, boolean enableGUI);
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public native String getOSUUID(boolean enableSuperUser, boolean enableGUI);
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public OperatingSystemIdentificationType getIdentificationType() {
+		return this.type;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemNativeWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemUDevWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemUDevWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemUDevWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,98 @@
+/* 
+  * $Id$
+ * 
+ * Copyright (C) 2011-12 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+
+/**
+ * Wrapper to the MacOS functions.
+ * This class was introduced to avoid to kill the current
+ * JVM even if the native functions are unloadable.
+ * In this way, on operating system without the support
+ * for the native libs is still able to be run. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.3
+ */
+class OperatingSystemUDevWrapper extends AbstractOperatingSystemWrapper {
+
+	/**
+	 */
+	public OperatingSystemUDevWrapper() {
+		//
+	}
+
+	private static String runUdev(File f, String key) {
+		String r = runCommand(
+				"udevadm", //$NON-NLS-1$
+				"info", //$NON-NLS-1$
+				"-q", //$NON-NLS-1$
+				"property", //$NON-NLS-1$
+				"-n", //$NON-NLS-1$
+				f.toString());
+		return cut("=", 1, grep(key+"=", r));  //$NON-NLS-1$//$NON-NLS-2$
+	}
+	
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getOSSerialNumber(boolean enableSuperUser, boolean enableGUI) {
+		File f;
+		f = new File("/dev/sda"); //$NON-NLS-1$
+		if (f.exists()) {
+			return runUdev(f, "ID_SERIAL"); //$NON-NLS-1$
+		}
+		f = new File("/dev/hda"); //$NON-NLS-1$
+		if (f.exists()) {
+			return runUdev(f, "ID_SERIAL"); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getOSUUID(boolean enableSuperUser, boolean enableGUI) {
+		File f;
+		f = new File("/dev/sda"); //$NON-NLS-1$
+		if (f.exists()) {
+			return runUdev(f, "ID_SERIAL_SHORT"); //$NON-NLS-1$
+		}
+		f = new File("/dev/hda"); //$NON-NLS-1$
+		if (f.exists()) {
+			return runUdev(f, "ID_SERIAL_SHORT"); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public OperatingSystemIdentificationType getIdentificationType() {
+		return OperatingSystemIdentificationType.HARD_DISK;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemUDevWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,61 @@
+/* 
+  * $Id$
+ * 
+ * Copyright (C) 2011-12 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+/**
+ * Wrapper to the OS dependent functions.
+ * This class was introduced to avoid to kill the current
+ * JVM even if the native functions are unloadable.
+ * In this way, on operating system without the support
+ * for the native libs is still able to be run. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.3
+ */
+interface OperatingSystemWrapper {
+
+	/** Replies the type of identification provided by this wrapper.
+	 * 
+	 * @return the type of identification provided by this wrapper.
+	 */
+	public OperatingSystemIdentificationType getIdentificationType();
+	
+	/** Get the OS serial number.
+	 * 
+	 * @param enableSuperUser indicates if the super-user commands are enabled or not.
+	 * @param enableGUI indicates if any additional GUI could be opened, or not.
+	 * @return the serial number associated to the current operating system.
+	 */
+	public String getOSSerialNumber(boolean enableSuperUser, boolean enableGUI);
+
+	/** Get the OS UUID.
+	 * 
+	 * @param enableSuperUser indicates if the super-user commands are enabled or not.
+	 * @param enableGUI indicates if any additional GUI could be opened, or not.
+	 * @return an unique identifier for the current operating system.
+	 */
+	public String getOSUUID(boolean enableSuperUser, boolean enableGUI);
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/OperatingSystemWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,650 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2009 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Pattern;
+
+/**
+ * This utility class provides a way to extend the reflection API and
+ * the Class class with autoboxing-compliant functions.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since since JDK 1.5
+ */
+public class ReflectionUtil {
+
+    /**
+     * Determines if the specified <code>Object</code> is assignment-compatible
+     * with the object represented by the <code>Class</code>.  This method extends
+     * {@link Class#isInstance(Object)} with autoboxing support.
+     *
+     * @param type is the class against which the object must be test
+     * @param obj is the object to check
+     * @return <code>true</code> if <code>obj</code> is an instance of the type
+     * @see Class#isInstance(Object)
+     */
+    public static boolean isInstance(Class<?> type, Object obj) {
+    	assert(type!=null);
+    	if (obj==null) return false;
+
+    	// Test according to the Class's behaviour
+    	if (type.isInstance(obj)) return true;
+    	
+    	// Test according to autoboxing
+    	if (type.isPrimitive()
+    			&&
+    			type!=Void.class && type!=void.class) {
+    		
+    		if (type==Boolean.class) return boolean.class.isInstance(obj);
+    		if (type==boolean.class) return Boolean.class.isInstance(obj);
+    		
+    		if (type==Character.class) return char.class.isInstance(obj);
+    		if (type==char.class) return Character.class.isInstance(obj);
+
+    		if (type==Byte.class) return byte.class.isInstance(obj);
+    		if (type==byte.class) return Byte.class.isInstance(obj);
+
+    		if (type==Short.class) return short.class.isInstance(obj);
+    		if (type==short.class) return Short.class.isInstance(obj);
+
+    		if (type==Integer.class) return int.class.isInstance(obj);
+    		if (type==int.class) return Integer.class.isInstance(obj);
+
+    		if (type==Long.class) return long.class.isInstance(obj);
+    		if (type==long.class) return Long.class.isInstance(obj);
+
+    		if (type==Float.class) return float.class.isInstance(obj);
+    		if (type==float.class) return Float.class.isInstance(obj);
+    		
+    		if (type==Double.class) return double.class.isInstance(obj);
+    		if (type==double.class) return Double.class.isInstance(obj);
+
+    		if (type==Void.class) return void.class.isInstance(obj);
+    		if (type==void.class) return Void.class.isInstance(obj);
+    		
+    		assert false: "Unsupported primitive type"; //$NON-NLS-1$
+    	}
+    	
+    	return false;
+    }
+
+
+    /**
+     * Determines if the <code>assignmentTarget</code> object is either the same as,
+     * or is a superclass or superinterface of, the class or interface 
+     * represented by the specified
+     * <code>assignementSource</code> parameter. This method extends
+     * {@link Class#isAssignableFrom(Class)} with autoboxing support.
+     * 
+     * @param assignementTarget is the class that is tested to be a super class.
+     * @param assignementSource is the class that is tested to be a sub class.
+     * @return <code>true</code> if an object of the <var>assignementSource</var> type
+     * could be assigned to a variable of <var>assignementTarget</var> type,
+     * otherwise <code>false</code>.
+     */
+    public static boolean isAssignableFrom(Class<?> assignementTarget, Class<?> assignementSource) {
+    	assert(assignementSource!=null);
+    	assert(assignementTarget!=null);
+    	
+    	// Test according to the Class's behaviour
+    	if (assignementTarget.isAssignableFrom(assignementSource)) return true;
+    	
+    	// Test according to autoboxing
+    	if (assignementTarget.isPrimitive() && assignementSource.isPrimitive()
+    			&&
+    			assignementTarget!=Void.class && assignementTarget!=void.class
+    			&&
+    			assignementSource!=Void.class && assignementSource!=void.class) {
+    		return true;
+    	}
+    	
+    	return false;
+    }
+
+	/** Replies the type that corresponds to the specified class.
+	 * If the name corresponds to a primitive type, the low-level type
+	 * will be replied.
+	 * This method extends
+     * {@link Class#forName(String)} with autoboxing support.
+	 * 
+	 * @param name is the name of the class to load.
+	 * @return the loaded class
+	 * @throws ClassNotFoundException  if name names an
+	 * unknown class or primitive
+	 */
+	public static Class<?> forName(String name) throws ClassNotFoundException {
+		if (name == null || "".equals(name) || "null".equals(name) || "void".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			return void.class;
+		}
+		if ("boolean".equals(name)) { //$NON-NLS-1$
+			return boolean.class;
+		}
+		if ("byte".equals(name)) { //$NON-NLS-1$
+			return byte.class;
+		}
+		if ("char".equals(name)) { //$NON-NLS-1$
+			return char.class;
+		}
+		if ("double".equals(name)) { //$NON-NLS-1$
+			return double.class;
+		}
+		if ("float".equals(name)) { //$NON-NLS-1$
+			return float.class;
+		}
+		if ("int".equals(name)) { //$NON-NLS-1$
+			return int.class;
+		}
+		if ("long".equals(name)) { //$NON-NLS-1$
+			return long.class;
+		}
+		if ("short".equals(name)) { //$NON-NLS-1$
+			return short.class;
+		}
+		return Class.forName(name);
+	}
+
+	/** Replies the type that corresponds to the specified class.
+	 * If the name corresponds to a primitive type, the low-level type
+	 * will be replied.
+	 * This method extends
+     * {@link Class#forName(String)} with autoboxing support.
+	 * 
+	 * @param name is the name of the class to load.
+	 * @param loader is the class loader to use.
+	 * @return the loaded class
+	 * @throws ClassNotFoundException  if name names an
+	 * unknown class or primitive
+	 */
+	public static Class<?> forName(String name, ClassLoader loader) throws ClassNotFoundException {
+		return forName(name, true, loader);
+	}
+
+	/** Replies the type that corresponds to the specified class.
+	 * If the name corresponds to a primitive type, the low-level type
+	 * will be replied.
+	 * This method extends
+     * {@link Class#forName(String)} with autoboxing support.
+	 * 
+	 * @param name is the name of the class to load.
+	 * @param typeInitialization must be <code>true</code> to initialize the type, <code>false</code> otherwise.
+	 * @param loader is the class loader to use.
+	 * @return the loaded class
+	 * @throws ClassNotFoundException  if name names an
+	 * unknown class or primitive
+	 */
+	public static Class<?> forName(String name, boolean typeInitialization, ClassLoader loader) throws ClassNotFoundException {
+		if (name == null || "".equals(name) || "null".equals(name) || "void".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			return void.class;
+		}
+		if ("boolean".equals(name)) { //$NON-NLS-1$
+			return boolean.class;
+		}
+		if ("byte".equals(name)) { //$NON-NLS-1$
+			return byte.class;
+		}
+		if ("char".equals(name)) { //$NON-NLS-1$
+			return char.class;
+		}
+		if ("double".equals(name)) { //$NON-NLS-1$
+			return double.class;
+		}
+		if ("float".equals(name)) { //$NON-NLS-1$
+			return float.class;
+		}
+		if ("int".equals(name)) { //$NON-NLS-1$
+			return int.class;
+		}
+		if ("long".equals(name)) { //$NON-NLS-1$
+			return long.class;
+		}
+		if ("short".equals(name)) { //$NON-NLS-1$
+			return short.class;
+		}
+		return Class.forName(name, typeInitialization, loader);
+	}
+
+	/**
+	 * Replies the list of the classes in the given package.
+	 * @param pkg is the package to explore.
+	 * @return the list of classes in the package.
+	 */
+	public static Collection<Class<?>> getPackageClasses(Package pkg) {
+		return getPackageClasses(pkg.getName());
+	}
+
+	/**
+	 * Replies the list of the classes in the given package.
+	 * @param packageName is the name of the package to explore.
+	 * @return the list of classes in the package.
+	 */
+	public static Collection<Class<?>> getPackageClasses(String packageName) {
+		Collection<Class<?>> classes = new ArrayList<>();
+	 
+		String[] entries = System.getProperty("java.class.path").split( //$NON-NLS-1$
+				Pattern.quote(System.getProperty("path.separator"))); //$NON-NLS-1$
+		String lentry;			
+		
+		for(String path : entries) {
+			lentry = path.toLowerCase();
+			if(lentry.endsWith(".jar") || lentry.endsWith(".war")) { //$NON-NLS-1$//$NON-NLS-2$
+				getPackageClassesFromJar(classes, path, packageName);
+			}else{
+				getPackageClassesFromFileSystem(classes, path, packageName);
+			}
+	 
+		}
+	 
+		return classes;
+	}
+	
+	private static String basename(String name) {
+		int idx = name.lastIndexOf('/');
+		if (idx>=0 && idx<name.length()) {
+			return name.substring(idx+1);
+		}
+		return name;
+	}
+
+	private static String filename(String name) {
+		String basename = basename(name);
+		int idx = basename.indexOf('.');
+		if (idx>=0 && idx<basename.length()) {
+			return basename.substring(0,idx);
+		}
+		return name;
+	}
+
+	private static void getPackageClassesFromJar(Collection<Class<?>> classes, String jarFilename, String packageName) {
+		try {
+			try (JarFile jarFile = new JarFile(jarFilename)) {
+				String packagePath = packageName.replace(".", "/"); //$NON-NLS-1$//$NON-NLS-2$
+		
+				Enumeration<JarEntry> entries = jarFile.entries();
+				JarEntry entry;
+				String entryPath, entryClassname;
+				
+				while (entries.hasMoreElements()) {
+					entry = entries.nextElement();
+					entryPath = entry.getName();
+		
+					// In package and not inner class
+					if (entryPath.startsWith(packagePath)
+						&& !entryPath.endsWith("/") //$NON-NLS-1$
+						&& !entryPath.contains("$")) { //$NON-NLS-1$
+						entryClassname = packageName + "." + filename(entryPath); //$NON-NLS-1$
+						try {
+							classes.add(Class.forName(entryClassname));
+						}
+						catch(ClassNotFoundException _) {
+							//
+						}
+					}	
+				}
+			}
+		}
+		catch(IOException _) {
+			//
+		}
+	}
+
+	private static void getPackageClassesFromFileSystem(Collection<Class<?>> classes, String directory, String packageName) {
+		String packagePath = packageName.replace(".", File.separator); //$NON-NLS-1$
+		File packageDirectory = new File(directory, packagePath);
+		String entryClassname;
+		
+		if (packageDirectory.isDirectory()) {
+			for(String entryPath : packageDirectory.list()) {
+	
+				// In package and not inner class
+				if (!entryPath.contains("$")) { //$NON-NLS-1$
+					entryClassname = packageName + "." + FileSystem.shortBasename(entryPath); //$NON-NLS-1$
+					try {
+						classes.add(Class.forName(entryClassname));
+					}
+					catch(AssertionError e) {
+						throw e;
+					}
+					catch(Throwable _) {
+						//
+					}
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Replies the list of all the subclasses of the given class
+	 * in the current classpath.
+	 * 
+	 * @param <T> is the type of the superclass.
+	 * @param className is the name of the class to explore.
+	 * @return the list of subclasses.
+	 */
+	public static <T> Collection<Class<? extends T>> getSubClasses(Class<T> className) {
+		Collection<Class<? extends T>> list = new ArrayList<>();
+		getSubClasses(className, true, true, true, list);
+		return list;
+	}
+
+	/**
+	 * Replies the list of all the subclasses of the given class
+	 * in the current classpath.
+	 * 
+	 * @param <T> is the type of the superclass.
+	 * @param className is the name of the class to explore.
+	 * @param allowAbstract is <code>true</code> to allow abstract classes to be put in the replied list
+	 * @param allowInterface is <code>true</code> to allow interfaces to be put in the replied list.
+	 * @param allowEnum is <code>true</code> to allow enumeration to be put in the replied list.
+	 * @param result is the list of subclasses which will be filled by this function.
+	 */
+	public static <T> void getSubClasses(Class<T> className, boolean allowAbstract, boolean allowInterface, boolean allowEnum, Collection<Class<? extends T>> result) {
+		String[] entries = System.getProperty("java.class.path").split( //$NON-NLS-1$
+				Pattern.quote(System.getProperty("path.separator"))); //$NON-NLS-1$
+		String lentry;			
+		
+		for(String path : entries) {
+			lentry = path.toLowerCase();
+			if(lentry.endsWith(".jar") || lentry.endsWith(".war")) { //$NON-NLS-1$//$NON-NLS-2$
+				getSubClassesFromJar(result, path, className, allowAbstract, allowInterface, allowEnum);
+			}else{
+				getSubClassesFromFileSystem(result, path, className, allowAbstract, allowInterface, allowEnum);
+			}
+	 
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private static <T> void getSubClassesFromJar(Collection<Class<? extends T>> classes, String jarFilename, Class<T> className, boolean allowAbstract, boolean allowInterface, boolean allowEnum) {
+		try {
+			try (JarFile jarFile = new JarFile(jarFilename)) {
+				String classN = className.getCanonicalName();
+				if (classN!=null) {
+					Enumeration<JarEntry> entries = jarFile.entries();
+					JarEntry entry;
+					String entryPath, entryClassname;
+					
+					while (entries.hasMoreElements()) {
+						entry = entries.nextElement();
+						entryPath = entry.getName();
+			
+						// In package and not inner class
+						if (entryPath.endsWith(".class") //$NON-NLS-1$
+							&& !entryPath.contains("$")) { //$NON-NLS-1$
+							entryClassname = entryPath.substring(0, entryPath.length()-6).replaceAll(
+									Pattern.quote(File.separator), "."); //$NON-NLS-1$
+							try {
+								Class<?> clazz = Class.forName(entryClassname);
+								if ((className.isAssignableFrom(clazz))
+									&&(allowAbstract || !Modifier.isAbstract(clazz.getModifiers()))
+									&&(allowInterface || !clazz.isInterface())
+									&&(allowEnum || !clazz.isEnum()))
+									classes.add((Class<? extends T>)clazz);
+							}
+							catch(AssertionError e) {
+								throw e;
+							}
+							catch(Throwable _) {
+								//
+							}
+						}	
+					}
+				}
+			}
+		}
+		catch(IOException _) {
+			//
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private static <T> void getSubClassesFromFileSystem(Collection<Class<? extends T>> classes, String directory, Class<T> className, boolean allowAbstract, boolean allowInterface, boolean allowEnum) {
+		String classN = className.getCanonicalName();
+		if (classN!=null) {
+			List<String> directories = new ArrayList<>();
+			directories.add(""); //$NON-NLS-1$
+			
+			String ldir, entryClassname;
+			File dir, fullFile;
+			
+			while (!directories.isEmpty()) {
+				ldir = directories.remove(0);
+				dir = new File(directory, ldir);
+				if (dir.isDirectory()) {
+					for(String entryPath : dir.list()) {
+			
+						fullFile = new File(dir,entryPath);
+						
+						if (fullFile.isDirectory()) {
+							if (ldir==null || "".equals(ldir)) { //$NON-NLS-1$
+								directories.add(entryPath);
+							}
+							else {
+								directories.add(new File(ldir,entryPath).toString());
+							}
+						}
+						// In package and not inner class
+						else if (entryPath.endsWith(".class") //$NON-NLS-1$
+							&& !entryPath.contains("$")) { //$NON-NLS-1$
+							assert(ldir!=null);
+							entryClassname = ldir.replaceAll(
+									Pattern.quote(File.separator), ".") //$NON-NLS-1$
+									+ "." + FileSystem.shortBasename(entryPath); //$NON-NLS-1$
+							try {
+								Class<?> clazz = Class.forName(entryClassname);
+								if ((className.isAssignableFrom(clazz))
+									&&(allowAbstract || !Modifier.isAbstract(clazz.getModifiers()))
+									&&(allowInterface || !clazz.isInterface())
+									&&(allowEnum || !clazz.isEnum()))
+									classes.add((Class<? extends T>)clazz);
+							}
+							catch(AssertionError e) {
+								throw e;
+							}
+							catch(Throwable _) {
+								//
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	/**
+     * Determines the interfaces implemented by the classes from the lowest type
+     * to the highestType which are extended the given interfaceType.
+     * <p>
+     * Insteed of {@link Class#getInterfaces()}, this function is exploring
+     * the super classes. This function does not explore super-interfaces
+     * of implemented interfaces.
+     * <p>
+     * <pre><code>
+     * interface IA {}
+     * interface IB extends IA {}
+     * interface IC {}
+     * interface ID extends IB, IC {}
+     * class CA implements IC {}
+     * class CB extends CA {}
+     * class CC extends CB implements IB {}
+     * </code></pre>
+     * This function replies for:
+     * <ul>
+     * <li><code>getAllDirectInterfaces(IA,null,null)</code>=<code>{}</code></li>
+     * <li><code>getAllDirectInterfaces(IB,null,null)</code>=<code>{IA}</code></li>
+     * <li><code>getAllDirectInterfaces(IC,null,null)</code>=<code>{}</code></li>
+     * <li><code>getAllDirectInterfaces(ID,null,null)</code>=<code>{IB,IC}</code></li>
+     * <li><code>getAllDirectInterfaces(CA,null,null)</code>=<code>{IC}</code></li>
+     * <li><code>getAllDirectInterfaces(CB,null,null)</code>=<code>{IC}</code></li>
+     * <li><code>getAllDirectInterfaces(CC,null,null)</code>=<code>{IB,IC}</code></li>
+     * </ul>
+	 * 
+	 * @param <T> is the highest type to explore in type hierarchy.
+	 * @param <I> indicates the type of the replied interfaces.
+	 * @param lowestType is the lowest type to explore in type hierarchy.
+	 * @param highestType is the highest type to explore in type hierarchy.
+	 * @param interfaceType indicates the type of the replied interfaces.
+	 * @return the implemented interfaces.
+	 * @since 5.0
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T,I> Set<Class<? extends I>> getAllDirectInterfaces(Class<? extends T> lowestType, Class<T> highestType, Class<I> interfaceType) {
+		assert(lowestType!=null);
+		Set<Class<? extends I>> collection = new TreeSet<>(ClassComparator.SINGLETON);
+		Class<?> type = lowestType;
+		boolean cont;
+		do {
+			for(Class<?> directInterface : type.getInterfaces()) {
+				if (interfaceType==null || interfaceType.isAssignableFrom(directInterface))
+						collection.add((Class<? extends I>)directInterface);
+			}
+			cont = (highestType==null || !type.equals(highestType));
+			type = type.getSuperclass();
+		}
+		while (type!=null && cont);
+		return collection;
+	}
+	
+	/**
+     * Determines the interfaces implemented by the classes from the lowest type
+     * to the highestType which are extended the given interfaceType.
+     * <p>
+     * Insteed of {@link Class#getInterfaces()}, this function is exploring
+     * the super classes. This function does not explore super-interfaces
+     * of implemented interfaces.
+     * <p>
+     * <pre><code>
+     * interface IA {}
+     * interface IB extends IA {}
+     * interface IC {}
+     * interface ID extends IB, IC {}
+     * class CA implements IC {}
+     * class CB extends CA {}
+     * class CC extends CB implements IB {}
+     * </code></pre>
+     * This function replies for:
+     * <ul>
+     * <li><code>getAllDirectInterfaces(IA,null,null)</code>=<code>{}</code></li>
+     * <li><code>getAllDirectInterfaces(IB,null,null)</code>=<code>{IA}</code></li>
+     * <li><code>getAllDirectInterfaces(IC,null,null)</code>=<code>{}</code></li>
+     * <li><code>getAllDirectInterfaces(ID,null,null)</code>=<code>{IB,IC}</code></li>
+     * <li><code>getAllDirectInterfaces(CA,null,null)</code>=<code>{IC}</code></li>
+     * <li><code>getAllDirectInterfaces(CB,null,null)</code>=<code>{IC}</code></li>
+     * <li><code>getAllDirectInterfaces(CC,null,null)</code>=<code>{IB,IC}</code></li>
+     * </ul>
+	 * 
+	 * @param <T> is the highest type to explore in type hierarchy.
+	 * @param lowestType is the lowest type to explore in type hierarchy.
+	 * @param highestType is the highest type to explore in type hierarchy.
+	 * @return the implemented interfaces.
+	 * @since 5.0
+	 */
+	public static <T> Set<Class<?>> getAllDirectInterfaces(Class<? extends T> lowestType, Class<T> highestType) {
+		assert(lowestType!=null);
+		Set<Class<?>> collection = new TreeSet<>(ClassComparator.SINGLETON);
+		Class<?> type = lowestType;
+		boolean cont;
+		do {
+			for(Class<?> directInterface : type.getInterfaces()) {
+				collection.add(directInterface);
+			}
+			cont = (highestType==null || !type.equals(highestType));
+			type = type.getSuperclass();
+		}
+		while (type!=null && cont);
+		return collection;
+	}
+
+	/**
+	 * Replies the list of all the superclasses of the given class.
+	 * <p>
+	 * This function does not replies <code>Object.class</code>.
+	 * 
+	 * @param <T> is the type of the lowest class.
+	 * @param className is the type of the lowest class.
+	 * @return the list of superclasses.
+	 * @since 5.0
+	 */
+	public static <T> Collection<Class<? super T>> getSuperClasses(Class<T> className) {
+		assert(className!=null);
+		Collection<Class<? super T>> list = new ArrayList<>();
+		Class<? super T> type = className.getSuperclass();
+		while (type!=null && !Object.class.equals(type)) {
+			list.add(type);
+			type = type.getSuperclass();
+		}
+		return list;
+	}
+	
+	/** Replies the top-most type which is common to both given types.
+	 * 
+	 * @param type1
+	 * @param type2
+	 * @return the top-most type which is common to both given types.
+	 * @since 6.0
+	 */
+	public static Class<?> getCommonType(Class<?> type1, Class<?> type2) {
+		if (type1==null) return type2;
+		if (type2==null) return type1;
+		Class<?> top = type1;
+		while (!top.isAssignableFrom(type2)) {
+			top = top.getSuperclass();
+			assert(top!=null);
+		}
+		return top;
+	}
+
+	/** Replies the top-most type which is common to both given objects.
+	 * 
+	 * @param instance1
+	 * @param instance2
+	 * @return the top-most type which is common to both given objects.
+	 * @since 6.0
+	 */
+	public static Class<?> getCommonType(Object instance1, Object instance2) {
+		if (instance1==null ) {
+			return instance2==null ? null : instance2.getClass();
+		}
+		if (instance2==null) return instance1.getClass();
+		Class<?> top = instance1.getClass();
+		while (!top.isInstance(instance2)) {
+			top = top.getSuperclass();
+			assert(top!=null);
+		}
+		return top;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ReflectionUtil.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,67 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.IOException;
+
+/**
+ * The exception <code>ResourceNotFoundException</code> is 
+ * thrown when a required Java resource was not found.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 4.2
+ */
+public class ResourceNotFoundException extends IOException {
+
+	private static final long serialVersionUID = 4951959393164477007L;
+
+	/**
+	 */
+	public ResourceNotFoundException() {
+		super();
+	}
+		
+	/**
+	 * @param message
+	 */
+	public ResourceNotFoundException(String message) {
+		super(message);
+	}
+
+	/**
+	 * @param cause
+	 */
+	public ResourceNotFoundException(Throwable cause) {
+		super(cause);
+	}
+
+	/**
+	 * @param message
+	 * @param cause
+	 */
+	public ResourceNotFoundException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceNotFoundException.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,97 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * This interface provides implementations to load resources according to
+ * several heuristics:<ul>
+ * <li>search the resource in class paths;</li>
+ * <li>search the resource in ./resources subdirectory in class paths.</li>
+ * </ul>
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 7.0
+ */
+public interface ResourceWrapper {
+
+    /**
+     * Replies the URL of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames.
+     * <p>
+     * If the <var>classLoader</var> parameter is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If this last is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param classLoader is the research scope. If <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public URL getResource(ClassLoader classLoader, String path);
+    
+    /**
+     * Replies the input stream of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames, and may not start the
+     * path with a slash.
+     * <p>
+     * If the <var>classLoader</var> parameter is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If this last is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param classLoader is the research scope. If <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public InputStream getResourceAsStream(ClassLoader classLoader, String path);
+    
+    /** Translate the given resource name according to the current JVM standard.
+     * <p>
+     * The <code>resourceName</code> argument should be a fully 
+     * qualified class name. However, for compatibility with earlier 
+     * versions, Sun's Java SE Runtime Environments do not verify this,
+     * and so it is possible to access <code>PropertyResourceBundle</code>s
+     * by specifying a path name (using "/") instead of a fully 
+     * qualified class name (using ".").
+     * In several VM, such as Dalvik, the translation from "." to "/" is not
+     * automatically done by the VM to retreive the file.
+     * 
+     * @param resourceName
+     * @return the translated resource name.
+     */
+    public String translateResourceName(String resourceName);
+    
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ResourceWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Resources.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Resources.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Resources.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,372 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2008-2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This utility class provides to load resources according to
+ * several heuristics:<ul>
+ * <li>search the resource in class paths;</li>
+ * <li>search the resource in ./resources subdirectory in class paths.</li>
+ * </ul>
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 4.2
+ */
+public class Resources {
+
+	private static ResourceWrapper currentResourceInstance = null;
+
+	static {
+		URLHandlerUtil.installArakhneHandlers();
+		
+		ResourceWrapper wrapper = null;
+		
+		switch(OperatingSystem.getCurrentOS()) {
+		case ANDROID:
+			wrapper = new AndroidResourceWrapper();
+			break;
+		case AIX:
+		case BSD:
+		case FREEBSD:
+		case HPUX:
+		case LINUX:
+		case MACOSX:
+		case NETBSD:
+		case OPENBSD:
+		case OTHER:
+		case SOLARIS:
+		case WIN:
+		default:
+		}
+		
+		if (wrapper==null) {
+			currentResourceInstance = new StandardJREResourceWrapper();
+		}
+		else {
+			currentResourceInstance = wrapper;
+		}
+	}
+
+	/** Character used to separate paths on an resource name.
+	 */
+	public static final String NAME_SEPARATOR = "/"; //$NON-NLS-1$
+
+	/**
+     * Replies the URL of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames.
+     * <p>
+     * The class loader replied by {@link ClassLoaderFinder} is used.
+     * If it is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public static URL getResource(String path) {
+    	return getResource((ClassLoader)null, path);
+    }
+
+   	/**
+     * Replies the URL of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames.
+     * <p>
+     * The name of <var>packagename</var> is translated into a resource
+     * path (by replacing the dots by slashes) and the given path
+     * is append to. For example, the two following codes are equivalent:<pre><code>
+     * Resources.getResources(Package.getPackage("org.arakhne.afc"), "/a/b/c/d.png");
+     * Resources.getResources("org/arakhne/afc/a/b/c/d.png");
+     * </code></pre>
+     * <p>
+     * If the <var>classLoader</var> parameter is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If this last is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param classLoader is the research scope. If <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * @param packagename is the package in which the resource should be located.
+     * @param path is the relative path of the resource in the package. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     * @since 6.2
+     */
+    public static URL getResource(ClassLoader classLoader, Package packagename, String path) {
+    	if (packagename==null || path==null) return null;
+    	StringBuilder b = new StringBuilder();
+    	b.append(packagename.getName().replaceAll(
+    			Pattern.quote("."), //$NON-NLS-1$
+    			Matcher.quoteReplacement(NAME_SEPARATOR)));
+    	if (!path.startsWith(NAME_SEPARATOR)) {
+    		b.append(NAME_SEPARATOR);
+    	}
+    	b.append(path);
+    	return getResource(packagename.getClass().getClassLoader(), b.toString());
+    }
+
+   	/**
+     * Replies the URL of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames.
+     * <p>
+     * The name of <var>classname</var> is translated into a resource
+     * path (by remove the name of the class and replacing the dots by slashes) and the given path
+     * is append to. For example, the two following codes are equivalent:<pre><code>
+     * Resources.getResources(Resources.class, "/a/b/c/d.png");
+     * Resources.getResources("org/arakhne/vmutil/a/b/c/d.png");
+     * </code></pre>
+     * <p>
+     * The class loader of the given class is used. If it is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If it is also <code>null</code>, the class loader of this Resources
+     * class is used.
+     *
+     * @param classname is located in the package in which the resource should be also located.
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public static URL getResource(Class<?> classname, String path) {
+    	if (classname==null) return null;
+    	URL u = getResource(classname.getClassLoader(), classname.getPackage(), path);
+    	if (u==null)
+    		u = getResource(classname.getClassLoader(), path);
+    	return u;
+    }
+
+    /**
+     * Replies the URL of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames.
+     * <p>
+     * If the <var>classLoader</var> parameter is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If this last is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param classLoader is the research scope. If <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public static URL getResource(ClassLoader classLoader, String path) {
+    	return currentResourceInstance.getResource(classLoader, path);
+    }
+    
+    /**
+     * Replies the input stream of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames, and may not start the
+     * path with a slash.
+     * <p>
+     * The class loader replied by {@link ClassLoaderFinder} is used.
+     * If it is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public static InputStream getResourceAsStream(String path) {
+    	return getResourceAsStream((ClassLoader)null, path);
+    }
+    
+   	/**
+     * Replies the input stream of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames.
+     * <p>
+     * The name of <var>packagename</var> is translated into a resource
+     * path (by replacing the dots by slashes) and the given path
+     * is append to. For example, the two following codes are equivalent:<pre><code>
+     * Resources.getResources(Package.getPackage("org.arakhne.afc"), "/a/b/c/d.png");
+     * Resources.getResources("org/arakhne/afc/a/b/c/d.png");
+     * </code></pre>
+     * <p>
+     * If the <var>classLoader</var> parameter is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If this last is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param classLoader is the research scope. If <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * @param packagename is the package in which the resource should be located.
+     * @param path is the relative path of the resource in the package. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     * @since 6.2
+     */
+    public static InputStream getResourceAsStream(ClassLoader classLoader, Package packagename, String path) {
+    	if (packagename==null || path==null) return null;
+    	StringBuilder b = new StringBuilder();
+    	b.append(packagename.getName().replaceAll(
+    			Pattern.quote("."), //$NON-NLS-1$
+    			Matcher.quoteReplacement(NAME_SEPARATOR)));
+    	if (!path.startsWith(NAME_SEPARATOR)) {
+    		b.append(NAME_SEPARATOR);
+    	}
+    	b.append(path);
+    	return getResourceAsStream(classLoader, b.toString());
+    }
+
+   	/**
+     * Replies the input stream of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames.
+     * <p>
+     * The name of <var>classname</var> is translated into a resource
+     * path (by remove the name of the class and replacing the dots by slashes) and the given path
+     * is append to. For example, the two following codes are equivalent:<pre><code>
+     * Resources.getResources(Resources.class, "/a/b/c/d.png");
+     * Resources.getResources("org/arakhne/vmutil/a/b/c/d.png");
+     * </code></pre>
+     * <p>
+     * The class loader of the given class is used. If it is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If it is also <code>null</code>, the class loader of this Resources
+     * class is used.
+     *
+     * @param classname is located in the package in which the resource should be also located.
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    @SuppressWarnings("resource")
+	public static InputStream getResourceAsStream(Class<?> classname, String path) {
+    	if (classname==null) return null;
+    	InputStream is = getResourceAsStream(classname.getClassLoader(), classname.getPackage(), path);
+    	if (is==null)
+    		is = getResourceAsStream(classname.getClassLoader(), path);
+    	return is;
+    }
+
+    /**
+     * Replies the input stream of a resource.
+     * <p>
+     * You may use Unix-like syntax to write the resource path, ie.
+     * you may use slashes to separate filenames, and may not start the
+     * path with a slash.
+     * <p>
+     * If the <var>classLoader</var> parameter is <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * If this last is <code>null</code>, the class loader of
+     * the Resources class is used.
+     *
+     * @param classLoader is the research scope. If <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * @param path is the absolute path of the resource. 
+     * @return the url of the resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public static InputStream getResourceAsStream(ClassLoader classLoader, String path) {
+    	return currentResourceInstance.getResourceAsStream(classLoader, path);
+    }
+
+   	/**
+     * Replies the URL of a property resource that is associated to the given class.
+     *
+     * @param classname is the class for which the property resource should be replied.
+     * @param locale is the expected localization of the resource file; or <code>null</code>
+     * for the default. 
+     * @return the url of the property resource or <code>null</code> if the resource was
+     * not found in class paths.
+     * @since 7.0
+     */
+    public static URL getPropertyFile(Class<?> classname, Locale locale) {
+    	return getPropertyFile(classname.getClassLoader(), classname, locale);
+    }
+
+   	/**
+     * Replies the URL of a property resource that is associated to the given class.
+     *
+     * @param classLoader is the research scope. If <code>null</code>,
+     * the class loader replied by {@link ClassLoaderFinder} is used.
+     * @param classname is the class for which the property resource should be replied.
+     * @param locale is the expected localization of the resource file; or <code>null</code>
+     * for the default. 
+     * @return the url of the property resource or <code>null</code> if the resource was
+     * not found in class paths.
+     */
+    public static URL getPropertyFile(ClassLoader classLoader, Class<?> classname, Locale locale) {
+    	StringBuilder name = new StringBuilder();
+    	
+    	// Localized file
+    	if (locale!=null) {
+    		String country = locale.getCountry();
+    		if (country!=null && !country.isEmpty()) {
+    	    	name.append(classname.getSimpleName());
+    	    	name.append("_"); //$NON-NLS-1$
+    	    	name.append(country);
+    	    	name.append(".properties"); //$NON-NLS-1$
+    	    	URL url = getResource(classLoader, classname.getPackage(), name.toString());
+    	    	if (url!=null) {
+    	    		return url;
+    	    	}
+    		}
+    	}
+    	
+    	// Default property file
+    	name.setLength(0);
+    	name.append(classname.getSimpleName());
+    	name.append(".properties"); //$NON-NLS-1$
+    	return getResource(classLoader, classname.getPackage(), name.toString());
+    }
+
+    /** Translate the given resource name according to the current JVM standard.
+     * <p>
+     * The <code>resourceName</code> argument should be a fully 
+     * qualified class name. However, for compatibility with earlier 
+     * versions, Sun's Java SE Runtime Environments do not verify this,
+     * and so it is possible to access <code>PropertyResourceBundle</code>s
+     * by specifying a path name (using "/") instead of a fully 
+     * qualified class name (using ".").
+     * In several VM, such as Dalvik, the translation from "." to "/" is not
+     * automatically done by the VM to retreive the file.
+     * 
+     * @param resourceName
+     * @return the translated resource name.
+     * @since 7.0
+     */
+    public static String translateResourceName(String resourceName) {
+    	return currentResourceInstance.translateResourceName(resourceName);
+    }
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/Resources.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/StandardJREResourceWrapper.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/StandardJREResourceWrapper.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/StandardJREResourceWrapper.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,113 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2008-2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * This interface provides the standard JRE implementation to load resources according to
+ * several heuristics:<ul>
+ * <li>search the resource in class paths;</li>
+ * <li>search the resource in ./resources subdirectory in class paths.</li>
+ * </ul>
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 7.0
+ */
+class StandardJREResourceWrapper implements ResourceWrapper {
+
+	/** Prefix (or directory name) where resources may be located.
+	 */
+	public static final String RESOURCE_PREFIX = "resources/"; //$NON-NLS-1$
+
+	/**
+	 */
+	public StandardJREResourceWrapper() {
+		//
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public URL getResource(ClassLoader classLoader, String path) {
+    	if (path==null) return null;
+    	String resourcePath = path;
+    	if (path.startsWith("/")) { //$NON-NLS-1$
+    		resourcePath = path.substring(1);
+    	}
+    	
+    	ClassLoader loader = (classLoader==null)
+    			? ClassLoaderFinder.findClassLoader() //Resources.class.getClassLoader()
+    			: classLoader;
+    	assert(loader!=null);
+    			
+    	URL url = loader.getResource(resourcePath);
+    	
+    	if (url==null) {
+    		// Try to find in ./resources sub directory
+    		url = loader.getResource(RESOURCE_PREFIX+resourcePath);
+    	}
+    	return url;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+	@SuppressWarnings("resource")
+	@Override
+    public InputStream getResourceAsStream(ClassLoader classLoader, String path) {
+    	if (path==null) return null;
+    	String resourcePath = path;
+    	if (path.startsWith("/")) { //$NON-NLS-1$
+    		resourcePath = path.substring(1);
+    	}
+    	ClassLoader loader = classLoader;
+    	if (loader==null) {
+    		loader = ClassLoaderFinder.findClassLoader();
+    	}
+    	if (loader==null) {
+    		loader = Resources.class.getClassLoader();
+    	}
+    	
+    	assert(loader!=null);
+    	InputStream is = loader.getResourceAsStream(resourcePath);
+    	if (is==null) {
+    		// Try to find in ./resources sub directory
+    		is = loader.getResourceAsStream(RESOURCE_PREFIX+resourcePath);
+    	}
+    	return is;
+    }
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+    public String translateResourceName(String resourceName) {
+		return resourceName;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/StandardJREResourceWrapper.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,124 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2010 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.util.EmptyStackException;
+import java.util.Stack;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * This class permits to centralize the identify of the thread service providers. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class ThreadServiceFinder {
+
+	private static final Stack<ThreadServiceProvider> services = new Stack<>();
+	
+	static {
+		// Add the default provider
+		services.push(new DefaultProvider());
+	}
+	
+    /**
+     * Replies the current service provider.
+	 * 
+     * @return the thread service provider or <code>null</code>
+     */
+    public static ThreadServiceProvider getProvider() {
+    	try {
+    		return services.peek();
+    	}
+    	catch(EmptyStackException _) {
+    		return null;
+    	}
+    }
+
+    /**
+     * Add a preferred provider.
+	 * 
+     * @param provider is the preferred thread service provider
+     */
+    public static void addPreferredProvider(ThreadServiceProvider provider) {
+    	services.push(provider);
+    }
+
+    /**
+     * Remove a provider.
+	 * 
+     * @param provider is the preferred thread service provider
+     */
+    public static void removeProvider(ThreadServiceProvider provider) {
+    	services.remove(provider);
+    }
+
+    /**
+     * Remove a provider.
+     */
+    public static void removeProvider() {
+    	services.pop();
+    }
+
+    /**
+     * @author $Author: galland$
+     * @version $FullVersion$
+     * @mavengroupid $GroupId$
+     * @mavenartifactid $ArtifactId$
+     */
+    static class DefaultProvider implements ThreadServiceProvider {
+
+    	private ExecutorService executorService = null;
+    	
+    	private ScheduledExecutorService scheduledExecutorService = null;
+    	
+		/** {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public ExecutorService getExecutorService() {
+			if (this.executorService==null) {
+				this.executorService = Executors.newCachedThreadPool();
+			}
+			return this.executorService;
+		}
+
+		/** {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public ScheduledExecutorService getScheduledExecutorService() {
+			if (this.scheduledExecutorService==null) {
+				this.scheduledExecutorService = Executors.newScheduledThreadPool(3);
+			}
+			return this.scheduledExecutorService;
+		}
+
+    }
+    
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceFinder.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,48 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2010 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * This interface describes a provider of thread's service.. 
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public interface ThreadServiceProvider {
+
+	/** Replies the thread executor for this provider.
+	 * 
+	 * @return the default executor service.
+	 */
+	public ExecutorService getExecutorService();
+	
+	/** Replies the scheduled thread executor for this provider.
+	 * 
+	 * @return the default scheduled executor service.
+	 */
+	public ScheduledExecutorService getScheduledExecutorService();
+	
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/ThreadServiceProvider.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URISchemeType.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URISchemeType.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URISchemeType.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,481 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2009 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.net.URI;
+import java.net.URL;
+
+/** Commonly supported types of schemes for URL.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.0
+ */
+public enum URISchemeType {
+
+	/**
+	 * One of the most widely used URL scheme is the http scheme. 
+	 * The http URL scheme is used to locate documents that
+	 * reside on Web servers.
+	 * <p>
+	 * A Web server is more accurately called an HTTP server.
+	 * HTTP stands for Hypertext Transfer Protocol, and is a 
+	 * protocol designed to transfer hypertext documents over 
+	 * the Internet. It is used to transfer almost all of 
+	 * the documents you download using your Web browser. 
+	 */
+	HTTP {
+		@Override
+		public boolean isFileBasedScheme() {
+			return true;
+		}
+	},
+	
+	/**
+	 * One of the most widely used URL scheme is the https scheme. 
+	 * The https URL scheme is used to locate documents that
+	 * reside on Securized Web servers.
+	 * <p>
+	 * https stands for Hypertext Transfer Protocol Secure. It 
+	 * is a combination of the Hypertext Transfer Protocol (http) with the
+	 * <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security";>SSL/TLS</a>
+	 * protocol to provide encryption and secure identification 
+	 * of the server. HTTPS connections are often used for 
+	 * payment transactions on the World Wide Web and for 
+	 * sensitive transactions in corporate information systems. 
+	 * HTTPS should not be confused with Secure HTTP (S-HTTP)
+	 * specified in
+	 * <a href="http://tools.ietf.org/html/rfc2660";>RFC 2660</a>.
+	 */
+	HTTPS {
+		@Override
+		public boolean isFileBasedScheme() {
+			return true;
+		}
+	},
+	
+	/**
+	 * The ftp scheme is very similar to the http scheme, and is 
+	 * used to locate files available via FTP 
+	 * (File Transfer Protocol). The syntax is very similar to http syntax:
+	 * <pre><code>
+	 * ftp://sunsite.unc.edu/pub/Linux/ls-lR.gz
+	 * </code></pre>
+	 * <p>
+	 * The above URL points to the FTP server on sunsite.unc.edu, 
+	 * to the file ls-lR.gz in the /pub/Linux directory. It is 
+	 * also possible to specify a username and optionally, a 
+	 * password for the connection. The syntax is like this:
+	 * <pre><code>
+	 * ftp://user@host/path/file
+	 * ftp://user:password@host/path/file
+	 * </code></pre>
+	 * <p>
+	 * Note that supplying a password like this is sometimes a 
+	 * bad idea. Some people might tell you this is a huge 
+	 * security risk, but this is not really true: a URL like 
+	 * the one above is typed into your browser will only be a 
+	 * risk if someone peeps over your shoulder and sees the 
+	 * password. The password itself is transmitted unencrypted 
+	 * anyway, and can be intercepted in transit. Before you 
+	 * go paranoid about this, remember that if your read 
+	 * your mail through POP (Post Office Protocol), like 
+	 * most people do, then your mail password is also 
+	 * transmitted in the clear. The lesson in this is that 
+	 * if you're going to be paranoid, at least do it for 
+	 * the right reasons. 
+	 */
+	FTP {
+		@Override
+		public boolean isFileBasedScheme() {
+			return true;
+		}
+	},
+	
+	/**
+	 * The file scheme is used to point to files on your computer. 
+	 * It is slightly tricky, because (most) absolute file URLs 
+	 * aren't really absolute; they're always relative to your 
+	 * computer. However, you can specify the hostname in a file 
+	 * URL. Remember that a URL just tells you where a resource 
+	 * is located, not how to locate it. So this does make sense. 
+	 * If the hostname is omitted, the current host is assumed. 
+	 * If a URL is encountered by a program with a hostname 
+	 * that's different than the one it's working on, it will 
+	 * most likely decide that it cannot access the file, but 
+	 * this has nothing to do with the URL itself. The syntax 
+	 * is again much like the http syntax, only omitting the 
+	 * port numbers, like this:
+	 * <pre><code>
+	 * file:///home/stephanos/public_html/myface.jpg
+	 * file://localhost/temp/install_log.txt
+	 * </code></pre>
+	 * <p>
+	 * Note that the pathname here represents a path name in the 
+	 * local filesystem, so the slashes are usually replaced by 
+	 * a more appropriate character before the file is accessed. 
+	 * Unix uses slashes, Windows uses backslashes, Macintosh and 
+	 * other operating systems use other conventions. 
+	 */
+	FILE {
+		@Override
+		public boolean isFileBasedScheme() {
+			return true;
+		}
+	},
+	
+	/**
+	 * The mailto scheme is an example of an opaque URI 
+	 * scheme. mailto URLs identify someone's 
+	 * e-mail address. Their syntax is simple. 
+	 * You have the scheme name, the colon, and then 
+	 * the e-mail address. If you're someone who has a 
+	 * thing for collecting e-mail addresses, you 
+	 * might refer to yourself in the following ways:
+	 * <pre><code>
+	 * mailto:someone@xxxxxxxxxxx
+	 * mailto:someone@xxxxxxxxxxx?subject=Feedback
+	 * </code></pre>
+	 */
+	MAILTO {
+		@Override
+		public boolean isFileBasedScheme() {
+			return false;
+		}
+	},
+	
+	/**
+	 * The news scheme is another opaque URL scheme. 
+	 * It is used to refer to Usenet newsgroups or 
+	 * specific messages within these newsgroups. 
+	 * It has two possible syntaxes. One is the name 
+	 * of a Usenet newsgroup, and the other is the 
+	 * message id of a Usenet post. Note that the 
+	 * message id must be entered without the usual 
+	 * angle brackets (&lt; and &gt;).
+	 * <pre><code>
+	 * news:comp.infosystems.www.authoring.html
+	 * news:ba-ciwah-1998Jun4-013702@xxxxxxxxxxxx
+	 * news:*
+	 * </code></pre>
+	 * <p>
+	 * The third example points to all available 
+	 * newsgroups and can be used to refer to Usenet 
+	 * in general. 
+	 */
+	NEWS {
+		@Override
+		public boolean isFileBasedScheme() {
+			return false;
+		}
+	},
+	
+	/**
+	 * The telnet scheme has identical syntax to the ftp scheme, 
+	 * with the exception that there is no pathame. Only a 
+	 * hostname, and optionally a port, username and password 
+	 * may be supplied.
+	 * <pre><code>
+	 * telnet://user:password@xxxxxxxxxxxxxxxxxxxxx:35/
+	 * </code></pre>
+	 * <p>
+	 * The above indicates a telnet session for user "user" 
+	 * with password "password" on port 35 of 
+	 * somehost.internet.com.
+	 */
+	TELNET {
+		@Override
+		public boolean isFileBasedScheme() {
+			return false;
+		}
+	},
+	
+	/**
+	 * The ssh scheme (also known as sftp - for Secure FTP) 
+	 * is very similar to the ftp scheme, and is 
+	 * used to locate files available via SSH (Secure SHell). 
+	 * The syntax is very similar to ftp syntax:
+	 * <pre><code>
+	 * ssh://sunsite.unc.edu/pub/Linux/ls-lR.gz
+	 * </code></pre>
+	 * <p>
+	 * The above URL points to the SSH server on sunsite.unc.edu, 
+	 * to the file ls-lR.gz in the /pub/Linux directory. It is 
+	 * also possible to specify a username and optionally, a 
+	 * password for the connection. The syntax is like this:
+	 * <pre><code>
+	 * ssh://user@host/path/file
+	 * ssh://user:password@host/path/file
+	 * </code></pre>
+	 * <p>
+	 * Secure Shell is a network protocol that allows data to 
+	 * be exchanged using a secure channel between two 
+	 * networked devices. Used primarily on GNU/Linux and 
+	 * Unix based systems to access shell accounts, SSH was 
+	 * designed as a replacement for Telnet and other insecure 
+	 * remote shells, which send information, notably passwords, 
+	 * in plaintext, rendering them susceptible to packet 
+	 * analyzation. The encryption used by SSH provides 
+	 * confidentiality and integrity of data over an insecure 
+	 * network, such as the Internet.
+	 */
+	SSH {
+		@Override
+		public boolean isFileBasedScheme() {
+			return true;
+		}
+	},
+	
+	/**
+	 * The jar scheme describes a Java ARchive (JAR) file or 
+	 * an entry in a JAR file. The syntax of a JAR URL is:
+	 * <pre><code>
+	 * jar:&lt;url&gt;!/{entry}
+	 * </code></pre>
+	 * where <code>&lt;url&gt;</code> is an URL of the JAR file,
+	 * and <code>{entry}</code> is the absolute path of a file
+	 * inside the JAR file; for example:
+	 * <pre><code>
+	 * jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class
+	 * </code></pre>
+	 * <p>
+	 * Jar URLs should be used to refer to a JAR file or 
+	 * entries in a JAR file. The example above is a JAR URL 
+	 * which refers to a JAR entry. If the entry name is 
+	 * omitted, the URL refers to the whole JAR file: 
+	 * <pre><code>
+	 * jar:http://www.foo.com/bar/baz.jar!/
+	 * </code></pre>
+	 * <p>
+	 * When constructing a JAR url via new URL(context, spec), 
+	 * the following rules apply:
+	 * <ul>
+	 * <li>if there is no context URL and the specification passed 
+	 * to the URL constructor doesn't contain a separator, the 
+	 * URL is considered to refer to a JarFile.</li>
+	 * <li>if there is a context URL, the context URL is assumed 
+	 * to refer to a JAR file or a Jar directory.</li>
+	 * <li>if the specification begins with a '/', the Jar directory 
+	 * is ignored, and the spec is considered to be at the root
+	 * of the Jar file.</li>
+	 * </ul>
+	 */
+	JAR {
+		@Override
+		public boolean isFileBasedScheme() {
+			return true;
+		}
+	},
+
+	/**
+	 * In the Java programming language a resource is a piece of data 
+	 * that can be accessed by the code of an application. An 
+	 * application can access its resources through Uniform Resource 
+	 * Locators (URL), like web resources, but the resources are 
+	 * usually contained within the JAR file(s) of the application, or
+	 * inside one directory of the JVM class paths.
+	 * <p>
+	 * The resource scheme is simulator to the file scheme.
+	 * It is used to point to files somewhere in the class paths. 
+	 * It is always absolute filename from one of the roots given
+	 * in class paths.
+	 * The syntax is again much like the http syntax, only omitting
+	 * the port numbers, like this:
+	 * <pre><code>
+	 * resource:/org/arakhne/vmutil/resource.txt
+	 * resource:/org/arakhne/vmutil/resource.jpg
+	 * </code></pre>
+	 * <p>
+	 * Because the pathname here represents a path name in the 
+	 * class paths, the slashes are mandatory. 
+	 */
+	RESOURCE {
+		@Override
+		public boolean isFileBasedScheme() {
+			return true;
+		}
+	},
+
+	/**
+	 * This value indicates that the scheme is not recognized. 
+	 */
+	UNSUPPORTED {
+		@Override
+		public boolean isFileBasedScheme() {
+			return false;
+		}
+	};
+	
+	/** Replies the scheme string ended with a column character.
+	 * 
+	 * @return the scheme string with a column.
+	 */
+	@Override
+	public String toString() {
+		return name().toLowerCase()+":"; //$NON-NLS-1$
+	}
+	
+	/** Replies if the given URL uses this scheme.
+	 * 
+	 * @param url
+	 * @return <code>true</code> if the url uses this scheme,
+	 * otherwise <code>false</code>
+	 */
+	public boolean isURL(URL url) {
+		return getSchemeType(url)==this;
+	}
+
+	/** Replies if the given URI uses this scheme.
+	 * 
+	 * @param uri
+	 * @return <code>true</code> if the uri uses this scheme,
+	 * otherwise <code>false</code>
+	 */
+	public boolean isURI(URI uri) {
+		return getSchemeType(uri)==this;
+	}
+
+	/** Replies if the given string corresponds to this scheme.
+	 * 
+	 * @param string
+	 * @return <code>true</code> if the string corresponds to this scheme,
+	 * otherwise <code>false</code>
+	 */
+	public boolean isScheme(String string) {
+		return getSchemeType(string)==this;
+	}
+	
+	/** Remove this URI scheme from the given string.
+	 * 
+	 * @param string
+	 * @return the <var>string</var> without the URI scheme.
+	 */
+	public String removeScheme(String string) {
+		if (string!=null) {
+			int idx = string.indexOf(':');
+			if (idx>=0) {
+				String p = string.substring(0, idx+1);
+				if (toString().equalsIgnoreCase(p)) {
+					p = string.substring(idx+1);
+					if (p.startsWith("//")) { //$NON-NLS-1$
+						return p.substring(2);
+					}
+					return p;
+				}
+			}
+		}
+		return string;		
+	}
+
+	/** Remove any supported URI scheme from the given string.
+	 * 
+	 * @param string
+	 * @return the <var>string</var> without the URI scheme.
+	 */
+	public static String removeAnyScheme(String string) {
+		if (string!=null) {
+			int idx = string.indexOf(':');
+			if (idx>=0) {
+				String p = string.substring(0, idx+1);
+				for(URISchemeType type : values()) {
+					if (type.toString().equalsIgnoreCase(p)) {
+						p = string.substring(idx+1);
+						if (p.startsWith("//")) { //$NON-NLS-1$
+							return p.substring(2);
+						}
+						return p;
+					}
+				}
+			}
+		}
+		return string;		
+	}
+
+	private static URISchemeType getSchemeType(String protocol) {
+		String p = protocol;
+		int idx = protocol.indexOf(':');
+		if (idx>=0) {
+			p = protocol.substring(0, idx);
+		}
+		if (p==null
+				|| "".equals(protocol) //$NON-NLS-1$
+				|| "file".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return FILE;
+		if ("http".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return HTTP;
+		if ("https".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return HTTPS;
+		if ("ftp".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return FTP;
+		if ("mailto".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return MAILTO;
+		if ("news".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return NEWS;
+		if ("ssh".equalsIgnoreCase(p) //$NON-NLS-1$
+			|| "sftp".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return SSH;
+		if ("telnet".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return TELNET;
+		if ("jar".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return JAR;
+		if ("resource".equalsIgnoreCase(p)) //$NON-NLS-1$
+			return RESOURCE;
+		return URISchemeType.UNSUPPORTED;		
+	}
+
+	/** Replies the type of scheme for the given URL.
+	 * 
+	 * @param url
+	 * @return the type of scheme for the given URL.
+	 */
+	public static URISchemeType getSchemeType(URL url) {
+		if (url!=null)
+			return getSchemeType(url.getProtocol());
+		return URISchemeType.UNSUPPORTED;		
+	}
+	
+	/** Replies the type of scheme for the given URI.
+	 * 
+	 * @param uri
+	 * @return the type of scheme for the given URI.
+	 */
+	public static URISchemeType getSchemeType(URI uri) {
+		if (uri!=null)
+			return getSchemeType(uri.getScheme());
+		return URISchemeType.UNSUPPORTED;		
+	}
+	
+	/** Replies if this URI scheme represents a local or remote file.
+	 * 
+	 * @return <code>true</code> if this scheme is file-based,
+	 * otherwise <code>false</code>
+	 */
+	public abstract boolean isFileBasedScheme();
+
+	static {
+		URLHandlerUtil.installArakhneHandlers();
+	}
+
+}
+


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URISchemeType.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URLHandlerUtil.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URLHandlerUtil.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URLHandlerUtil.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,120 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2009 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/** Utilities around URLHandler.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.0
+ */
+public class URLHandlerUtil {
+
+	private static final String HANDLER_PACKAGES = "java.protocol.handler.pkgs"; //$NON-NLS-1$
+	
+	private static void install(String... packageNames) {
+		List<String> array = new LinkedList<>();
+
+		String str = System.getProperty(HANDLER_PACKAGES);
+		if (str!=null && !"".equals(str)) { //$NON-NLS-1$
+			array.addAll(Arrays.asList(str.split("\\|"))); //$NON-NLS-1$
+		}
+		
+		for(String packageName : packageNames) {
+			if (!array.contains(packageName)) {
+				array.add(0, packageName);
+			}
+		}
+
+		StringBuilder buffer = new StringBuilder();
+		for(String s : array) {
+			if (buffer.length()>0)
+				buffer.append('|');
+			buffer.append(s);
+		}
+
+		String nstr = buffer.toString();
+		if (!nstr.equals(str)) {
+			System.setProperty(HANDLER_PACKAGES, nstr);
+		}
+	}
+
+	private static void uninstall(String... packageNames) {
+		List<String> array = new LinkedList<>();
+
+		String str = System.getProperty(HANDLER_PACKAGES);
+		if (str!=null && !"".equals(str)) { //$NON-NLS-1$
+			array.addAll(Arrays.asList(str.split("\\|"))); //$NON-NLS-1$
+		}
+			
+		array.removeAll(Arrays.asList(packageNames));
+
+		StringBuilder buffer = new StringBuilder();
+		for(String s : array) {
+			if (buffer.length()>0)
+				buffer.append('|');
+			buffer.append(s);
+		}
+
+		String nstr = buffer.toString();
+		if (!nstr.equals(str)) {
+			System.setProperty(HANDLER_PACKAGES, nstr);
+		}
+	}
+
+	/** Install the URL handlers provided by Arakhn&ecirc;
+	 * libraries.
+	 * <p>
+	 * Handlers are provided for:<ul>
+	 * <li><code>file</code>: handler for files which is supported input and output.</li>
+	 * <li><code>resource</code>: handler for resource URL.</li>
+	 * </ul>
+	 * 
+	 * @see #uninstallArakhneHandlers()
+	 */
+	public static void installArakhneHandlers() {
+		install(URLHandlerUtil.class.getPackage().getName());
+	}
+
+	/** Uninstall the URL handlers provided by Arakhn&ecirc;
+	 * libraries.
+	 * <p>
+	 * Handlers are provided for:<ul>
+	 * <li><code>file</code>: handler for files which is supported input and output.</li>
+	 * <li><code>resource</code>: handler for resource URL.</li>
+	 * </ul>
+	 * 
+	 * @see #installArakhneHandlers()
+	 */
+	public static void uninstallArakhneHandlers() {
+		uninstall(URLHandlerUtil.class.getPackage().getName());
+	}
+
+}
+


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/URLHandlerUtil.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/VMCommandLine.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/VMCommandLine.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/VMCommandLine.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,923 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2009 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+/**
+ * This utility class permits to get the java command line for the current VM.  
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class VMCommandLine {
+
+	private static String classnameToLaunch = null;
+	private static boolean analyzed = false;
+	private static SortedMap<String,List<Object>> commandLineOptions = null;
+	private static String[] commandLineParameters = null;
+	
+	/** Replies a binary executable filename depending of the current platform.
+	 * 
+	 * @param name is the name which must be converted into a binary executable filename.
+	 * @return the binary executable filename.
+	 */
+	public static String getExecutableFilename(String name) {
+		if (OperatingSystem.WIN.isCurrentOS()) return name+".exe"; //$NON-NLS-1$
+		return name;
+	}
+	
+	/** Replies the current java VM binary.
+	 * 
+	 * @return the binary executable filename that was used to launch the virtual machine.
+	 */
+	public static String getVMBinary() {
+		String java_home = System.getProperty("java.home"); //$NON-NLS-1$
+		File bin_dir = new File(new File(java_home),"bin"); //$NON-NLS-1$
+		if (bin_dir.isDirectory()) {
+			File exec = new File(bin_dir,getExecutableFilename("javaw")); //$NON-NLS-1$
+			if (exec.isFile()) {
+				return exec.getAbsolutePath();
+			}
+			exec = new File(bin_dir,getExecutableFilename("java")); //$NON-NLS-1$
+			if (exec.isFile()) {
+				return exec.getAbsolutePath();
+			}			
+		}
+		return null;
+	}
+	
+	/** Run a new VM with the given class path.
+	 * 
+	 * @param classToLaunch is the class to launch.
+	 * @param classpath is the class path to use.
+	 * @param additionalParams is the list of additional parameters
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException
+	 * @since 6.2 
+	 */
+	public static Process launchVMWithClassPath(Class<?> classToLaunch, String classpath, String... additionalParams) throws IOException {
+		return launchVMWithClassPath(classToLaunch.getCanonicalName(), classpath, additionalParams);
+	}
+
+	/** Run a new VM with the given class path.
+	 * 
+	 * @param classToLaunch is the class to launch.
+	 * @param classpath is the class path to use.
+	 * @param additionalParams is the list of additional parameters
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException 
+	 * @since 6.2
+	 */
+	public static Process launchVMWithClassPath(String classToLaunch, String classpath, String... additionalParams) throws IOException {
+		String java_bin = getVMBinary();
+		if (java_bin==null) throw new FileNotFoundException("java"); //$NON-NLS-1$
+		long totalMemory = Runtime.getRuntime().maxMemory() / 1024;
+		String user_dir = FileSystem.getUserHomeDirectoryName();
+		String[] params;
+		int nParams;
+		if (classpath!=null && !"".equals(classpath)) { //$NON-NLS-1$
+			nParams = 5;
+			params = new String[additionalParams.length+nParams];
+			params[0] = java_bin;
+			params[1] = "-Xmx"+totalMemory+"k"; //$NON-NLS-1$ //$NON-NLS-2$
+			params[2] = "-classpath"; //$NON-NLS-1$
+			params[3] = classpath;
+			params[4] = classToLaunch;
+		}
+		else {
+			nParams = 3;
+			params = new String[additionalParams.length+nParams];
+			params[0] = java_bin;
+			params[1] = "-Xmx"+totalMemory+"k"; //$NON-NLS-1$ //$NON-NLS-2$
+			params[2] = classToLaunch;
+		}
+		System.arraycopy(additionalParams,0,params,nParams,additionalParams.length);
+		return Runtime.getRuntime().exec(params,null,new File(user_dir));
+	}
+
+	/** Run a new VM with the given class path.
+	 * 
+	 * @param classToLaunch is the class to launch.
+	 * @param classpath is the class path to use.
+	 * @param additionalParams is the list of additional parameters
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException
+	 * @since 6.2 
+	 */
+	public static Process launchVMWithClassPath(Class<?> classToLaunch, File[] classpath, String... additionalParams) throws IOException {
+		return launchVMWithClassPath(classToLaunch.getCanonicalName(), classpath, additionalParams);
+	}
+
+	/** Run a new VM with the given class path.
+	 * 
+	 * @param classToLaunch is the class to launch.
+	 * @param classpath is the class path to use.
+	 * @param additionalParams is the list of additional parameters
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException 
+	 * @since 6.2
+	 */
+	public static Process launchVMWithClassPath(String classToLaunch, File[] classpath, String... additionalParams) throws IOException {
+		StringBuilder b = new StringBuilder();
+		for(File f : classpath) {
+			if (b.length()>0) {
+				b.append(File.pathSeparator);
+			}
+			b.append(f.getAbsolutePath());
+		}
+		return launchVMWithClassPath(classToLaunch, b.toString(), additionalParams);
+	}
+
+	/** Run a jar file inside a new VM.
+	 * 
+	 * @param jarFile is the jar file to launch.
+	 * @param additionalParams is the list of additional parameters
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException
+	 * @since 6.2 
+	 */
+	public static Process launchVMWithJar(File jarFile, String... additionalParams) throws IOException {
+		String java_bin = getVMBinary();
+		if (java_bin==null) throw new FileNotFoundException("java"); //$NON-NLS-1$
+		long totalMemory = Runtime.getRuntime().maxMemory() / 1024;
+		String user_dir = FileSystem.getUserHomeDirectoryName();
+		int nParams = 4;
+		String[] params = new String[additionalParams.length+nParams];
+			params[0] = java_bin;
+			params[1] = "-Xmx"+totalMemory+"k"; //$NON-NLS-1$ //$NON-NLS-2$
+			params[2] = "-jar"; //$NON-NLS-1$
+			params[3] = jarFile.getAbsolutePath();
+		System.arraycopy(additionalParams,0,params,nParams,additionalParams.length);
+		return Runtime.getRuntime().exec(params,null,new File(user_dir));
+	}
+
+	/** Run a new VM with the class path of the current VM.
+	 * 
+	 * @param classToLaunch is the class to launch.
+	 * @param additionalParams is the list of additional parameters
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException 
+	 */
+	public static Process launchVM(Class<?> classToLaunch, String... additionalParams) throws IOException {
+		return launchVM(classToLaunch.getCanonicalName(), additionalParams);
+	}
+
+	/** Run a new VM with the class path of the current VM.
+	 * 
+	 * @param classToLaunch is the class to launch.
+	 * @param additionalParams is the list of additional parameters
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException 
+	 * @since 6.2
+	 */
+	public static Process launchVM(String classToLaunch, String... additionalParams) throws IOException {
+		return launchVMWithClassPath(
+				classToLaunch,
+				System.getProperty("java.class.path"), //$NON-NLS-1$
+				additionalParams);
+	}
+
+	/** Save parameters that permit to relaunch a VM with
+	 * {@link #relaunchVM()}.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 */
+	public static void saveVMParameters(Class<?> classToLaunch, String... parameters) {
+ 		saveVMParameters(
+ 				(classToLaunch!=null)
+ 				? classToLaunch.getCanonicalName()
+ 				: null, parameters);
+	}
+
+	/** Save parameters that permit to relaunch a VM with
+	 * {@link #relaunchVM()}.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 * @since 6.2
+	 */
+	public static void saveVMParameters(String classToLaunch, String... parameters) {
+		classnameToLaunch = classToLaunch;
+		commandLineParameters = parameters;
+		if (commandLineOptions!=null) commandLineOptions.clear();
+		commandLineOptions = null;
+		analyzed = false;
+	}
+
+	/** Save parameters that permit to relaunch a VM with
+	 * {@link #relaunchVM()}.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 */
+	public static void saveVMParametersIfNotSet(Class<?> classToLaunch, String... parameters) {
+		saveVMParametersIfNotSet(classToLaunch.getCanonicalName(), parameters);
+	}
+
+	/** Save parameters that permit to relaunch a VM with
+	 * {@link #relaunchVM()}.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 * @since 6.2
+	 */
+	public static void saveVMParametersIfNotSet(String classToLaunch, String... parameters) {
+		if (classnameToLaunch==null || "".equals(classnameToLaunch)) { //$NON-NLS-1$
+			saveVMParameters(classToLaunch, parameters);
+		}
+	}
+
+	/** Launch a VM with the same parameters as ones saved by
+	 * {@link #saveVMParameters(Class, String[])}.
+	 * 
+	 * @return the process that is running the new virtual machine, neither <code>null</code>
+	 * @throws IOException 
+	 */
+	public static Process relaunchVM() throws IOException {
+		if (classnameToLaunch==null) return null;		
+		return launchVM(classnameToLaunch, getAllCommandLineParameters());
+	}
+
+	/** Replies the command line including the options and the standard parameters.
+	 * 
+	 * @return  the command line.
+	 */
+	public static String[] getAllCommandLineParameters() {
+		int osize = commandLineOptions==null ? 0 : commandLineOptions.size();
+		int psize = commandLineParameters==null ? 0 : commandLineParameters.length;
+		int tsize = (osize>0 && psize>0) ? 1 : 0;
+		List<String> params = new ArrayList<>(osize+tsize);
+		if (osize>0) {
+			List<Object> values;
+			String name, prefix, v;
+			for(Entry<String,List<Object>> entry : commandLineOptions.entrySet()) {
+				name = entry.getKey();
+				prefix = (name.length()>1) ? "--" : "-"; //$NON-NLS-1$ //$NON-NLS-2$
+				values = entry.getValue();
+				if (values==null || values.isEmpty()) {
+					params.add(prefix+name);
+				}
+				else {
+					for(Object value : values) {
+						if (value!=null) {
+							v = value.toString();
+							if (v!=null && v.length()>0) {
+								params.add(prefix+name+"="+v); //$NON-NLS-1$
+							}
+							else {
+								params.add(prefix+name);
+							}
+						}
+					}
+				}
+			}
+		}
+		if (tsize>0) params.add("--"); //$NON-NLS-1$
+		
+		String[] tab = new String[params.size()+psize];
+		params.toArray(tab);
+		params.clear();
+		
+		if (psize>0)
+			System.arraycopy(commandLineParameters, 0, tab, osize+tsize, psize);
+		
+		return tab;
+	}
+
+	/** Replies the command line parameters.
+	 * 
+	 * @return the list of the parameters on the command line
+	 */
+	public static String[] getCommandLineParameters() {
+		return commandLineParameters==null ? new String[0] : commandLineParameters;
+	}
+	
+	/** Shift the command line parameters by one on the left.
+	 * The first parameter is removed from the list.
+	 * 
+	 * @return the removed element or <code>null</code>
+	 */
+	public static String shiftCommandLineParameters() {
+		String removed = null;
+		if (commandLineParameters!=null) {
+			if (commandLineParameters.length==0) {
+				commandLineParameters = null;
+			}
+			else if (commandLineParameters.length==1) {
+				removed = commandLineParameters[0];
+				commandLineParameters = null;
+			}
+			else {
+				removed = commandLineParameters[0];
+				String[] newTab = new String[commandLineParameters.length-1];
+				System.arraycopy(commandLineParameters,1,newTab,0,commandLineParameters.length-1);
+				commandLineParameters = newTab;
+			}
+		}
+		return removed;
+	}
+
+	/** Replies the command line options.
+	 * 
+	 * @return the list of options passed on the command line
+	 */
+	public static Map<String,List<Object>> getCommandLineOptions() {
+		if (commandLineOptions!=null)
+			return Collections.unmodifiableSortedMap(commandLineOptions);
+		return Collections.emptyMap();
+	}
+	
+	/** Replies one command option.
+	 *
+	 * @param name is the name of the option
+	 * @return the option value or <code>null</code> if the option is not on the command line.
+	 */
+	public static List<Object> getCommandLineOption(String name) {
+		if (commandLineOptions!=null) {
+			if (commandLineOptions.containsKey(name)) {
+				List<Object> value = commandLineOptions.get(name);
+				return value==null ? Collections.emptyList() : value;
+			}
+		}
+		return null;
+	}
+
+	/** Replies if an option was specified on the command line.
+	 *
+	 * @param name is the name of the option
+	 * @return <code>true</code> if the option was found on the command line, otherwise <code>false</code>.
+	 */
+	public static boolean hasCommandLineOption(String name) {
+		return (commandLineOptions!=null && commandLineOptions.containsKey(name));
+	}
+
+	private static boolean registerOptionValue(SortedMap<String,List<Object>> options, String name, Object value, OptionType type) {
+		boolean success = true;
+		
+		Object optValue = value;
+		
+		List<Object> values = options.get(name);
+		if (values==null) {
+			values = new ArrayList<>();
+			options.put(name, values);
+		}
+		switch(type) {
+		case AUTO_INCREMENTED:
+			{
+				long v;
+				if (values.isEmpty()) v = -1;
+				else {
+					optValue = values.get(0);
+					if (optValue==null) v = 0;
+					else if (!(optValue instanceof Number)) {
+						v = Long.parseLong(optValue.toString());
+					}
+					else {
+						v = ((Number)optValue).longValue();
+					}
+				}
+				if (values.isEmpty()) values.add(Long.valueOf(v+1));
+				else values.set(0, Long.valueOf(v+1));
+			}
+			break;
+		case FLAG:
+			if (optValue==null) {
+				if (values.isEmpty())
+					optValue = Boolean.TRUE;
+				else
+					optValue = values.get(0);
+			}
+			else if (!(optValue instanceof Boolean)) {
+				optValue = Boolean.parseBoolean(optValue.toString());
+			}
+			if (values.isEmpty()) values.add(optValue);
+			else values.set(0, optValue);
+			break;
+		case MANDATORY_BOOLEAN:
+		case OPTIONAL_BOOLEAN:
+			if (optValue==null) {
+				optValue = Boolean.TRUE;
+			}
+			else if (!(optValue instanceof Boolean)) {
+				optValue = Boolean.parseBoolean(optValue.toString());
+			}
+			values.add(optValue);
+			break;
+		case MANDATORY_FLOAT:
+		case OPTIONAL_FLOAT:
+			try {
+				if (optValue==null) {
+					optValue = Double.valueOf(0.);
+				}
+				else if (!(optValue instanceof Number)) {
+					optValue = Double.parseDouble(optValue.toString());
+				}
+				else {
+					optValue = Double.valueOf(((Number)optValue).doubleValue());
+				}
+			}
+			catch(NumberFormatException e) {
+				if (type.isOptional()) {
+					success = false;
+					optValue = Double.valueOf(0.);
+				}
+				else throw e;
+			}
+			values.add(optValue);
+			break;
+		case MANDATORY_INTEGER:
+		case OPTIONAL_INTEGER:
+			try {
+				if (optValue==null) {
+					optValue = Long.valueOf(0);
+				}
+				else if (!(optValue instanceof Number)) {
+					optValue = Long.parseLong(optValue.toString());
+				}
+				else {
+					optValue = Long.valueOf(((Number)optValue).longValue());
+				}
+			}
+			catch(NumberFormatException e) {
+				if (type.isOptional()) {
+					success = false;
+					optValue = Long.valueOf(0);
+				}
+				else throw e;
+			}
+			values.add(optValue);
+			break;
+		case MANDATORY_STRING:
+		case OPTIONAL_STRING:
+			values.add(optValue==null ? "" : optValue.toString()); //$NON-NLS-1$
+			break;
+		case SIMPLE:
+			values.add(optValue);
+			break;
+		default:
+		}
+		
+		return success;
+	}
+	
+	/** Analyse the command line to extract the options.
+	 * <p>
+	 * The options will be recognized thanks to the <var>optionDefinitions</var>.
+	 * Each entry of <var>optionDefinitions</var> describes an option. They must
+	 * have one of the following formats:
+	 * <ul>
+	 * <li>{@code name}: a simple option without value or flag,</li>
+	 * <li>{@code name=s}: an option with a mandatory string value,</li>
+	 * <li>{@code name:s}: an option with an optional string value,</li>
+	 * <li>{@code name=i}: an option with a mandatory integer value,</li>
+	 * <li>{@code name:i}: an option with an optional integer value,</li>
+	 * <li>{@code name=f}: an option with a mandatory floating-point value,</li>
+	 * <li>{@code name:f}: an option with an optional floating-point value,</li>
+	 * <li>{@code name=b}: an option with a mandatory boolean value,</li>
+	 * <li>{@code name:b}: an option with an optional boolean value,</li>
+	 * <li>{@code name+}: an option with an autoincremented integer value,</li>
+	 * <li>{@code name!}: an option which could be flaged or not: {@code --name} or {@code --noname}.</li>
+	 * </ul>
+	 * 
+	 * @param optionDefinitions is the list of definitions of the available command line options.
+	 */
+	public static void splitOptionsAndParameters(String... optionDefinitions) {
+		if (analyzed) return;
+		
+		List<String> params = new ArrayList<>();
+		SortedMap<String,List<Object>> options = new TreeMap<>();
+		String opt;
+
+		// Analyze definitions
+		Map<String,OptionType> defs = new TreeMap<>();
+		for (String def : optionDefinitions) {
+			if (def.endsWith("!")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-1);
+				defs.put(opt, OptionType.FLAG);
+				registerOptionValue(options, opt, Boolean.FALSE, OptionType.FLAG);
+			}
+			else if (def.endsWith("+")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-1);
+				defs.put(opt, OptionType.AUTO_INCREMENTED);
+				registerOptionValue(options, opt, Long.valueOf(0), OptionType.AUTO_INCREMENTED);
+			}
+			else if (def.endsWith("=b")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.MANDATORY_BOOLEAN);
+			}
+			else if (def.endsWith(":b")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.OPTIONAL_BOOLEAN);
+			}
+			else if (def.endsWith("=f")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.MANDATORY_FLOAT);
+			}
+			else if (def.endsWith(":f")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.OPTIONAL_FLOAT);
+			}
+			else if (def.endsWith("=i")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.MANDATORY_INTEGER);
+			}
+			else if (def.endsWith(":i")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.OPTIONAL_INTEGER);
+			}
+			else if (def.endsWith("=s")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.MANDATORY_STRING);
+			}
+			else if (def.endsWith(":s")) { //$NON-NLS-1$
+				opt = def.substring(0, def.length()-2);
+				defs.put(opt, OptionType.OPTIONAL_STRING);
+			}
+			else {
+				defs.put(def, OptionType.SIMPLE);
+			}
+		}
+		
+		int idx;
+		String base, nbase, val;
+		OptionType type;
+		OptionType waitingValue = null;
+		String valueOptionName = null;
+		boolean allParameters = false;
+		boolean success;
+		
+		for(String param : commandLineParameters) {
+			if (allParameters) {
+				params.add(param);
+				continue;
+			}
+			
+			if (waitingValue!=null && waitingValue.isMandatory()) {
+				// Expect a value as the next parameter
+				success = registerOptionValue(options, valueOptionName, param, waitingValue);
+				waitingValue = null;
+				valueOptionName = null;
+				if (success) continue;
+			}
+			
+			if ("--".equals(param)) { //$NON-NLS-1$
+				if (waitingValue!=null) {
+					registerOptionValue(options, valueOptionName, null, waitingValue);
+					waitingValue = null;
+					valueOptionName = null;
+				}
+				allParameters = true;
+				continue;
+			}
+			else if ((File.separatorChar!='/')&&(param.startsWith("/"))) { //$NON-NLS-1$
+				opt = param.substring(1);
+			}
+			else if (param.startsWith("--")) { //$NON-NLS-1$
+				opt = param.substring(2);
+			}
+			else if (param.startsWith("-")) { //$NON-NLS-1$
+				opt = param.substring(1);
+			}
+			else if (waitingValue!=null) {
+				success = registerOptionValue(options, valueOptionName, param, waitingValue);
+				waitingValue = null;
+				valueOptionName = null;
+				if (!success) params.add(param);
+				continue;
+			}
+			else {
+				params.add(param);
+				continue;
+			}
+			
+			if (waitingValue!=null) {
+				success = registerOptionValue(options, valueOptionName, param, waitingValue);
+				waitingValue = null;
+				valueOptionName = null;
+				if (success) continue;
+			}
+
+			idx = opt.indexOf('=');
+			if (idx>0) {
+				base = opt.substring(0,idx);
+				val = opt.substring(idx+1);
+			}
+			else {
+				base = opt;
+				val = null;
+			}
+
+			nbase = null;
+			type = defs.get(base);
+			if (type==null && base.toLowerCase().startsWith("no")) { //$NON-NLS-1$
+				nbase = base.substring(2);
+				type = defs.get(nbase);
+			}
+			if (type!=null) {
+				switch(type) {
+				case FLAG:
+					if (nbase==null)
+						registerOptionValue(options, base, Boolean.TRUE, type);
+					else
+						registerOptionValue(options, nbase, Boolean.FALSE, type);
+					break;
+				case MANDATORY_FLOAT:
+				case MANDATORY_BOOLEAN:
+				case MANDATORY_INTEGER:
+				case MANDATORY_STRING:
+				case OPTIONAL_FLOAT:
+				case OPTIONAL_BOOLEAN:
+				case OPTIONAL_INTEGER:
+				case OPTIONAL_STRING:
+					if (val!=null) {
+						registerOptionValue(options, base, val, type);
+					}
+					else {
+						waitingValue = type;
+						valueOptionName = base;
+					}
+					break;
+				default:
+					registerOptionValue(options, base, val, type);
+				}
+			}
+			else {
+				// Not a recognized option, assuming simple
+				registerOptionValue(options, base, val, OptionType.SIMPLE);
+			}
+		}
+		
+		if (waitingValue!=null && waitingValue.isMandatory()) {
+			throw new IllegalStateException("expected a value for command line option "+valueOptionName); //$NON-NLS-1$
+		}
+		
+		commandLineParameters = new String[params.size()];
+		params.toArray(commandLineParameters);
+		params.clear();
+
+		commandLineOptions = options;
+		
+		analyzed = true;
+	}
+	
+	/**
+	 * Create a interface to the command line options.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 * @see #saveVMParametersIfNotSet(Class, String[])
+	 */
+	public VMCommandLine(Class<?> classToLaunch, String... parameters) {
+		saveVMParametersIfNotSet(classToLaunch, parameters);
+	}
+	
+	/**
+	 * Create a interface to the command line options.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 * @see #saveVMParametersIfNotSet(String, String[])
+	 * @since 6.2
+	 */
+	public VMCommandLine(String classToLaunch, String... parameters) {
+		saveVMParametersIfNotSet(classToLaunch, parameters);
+	}
+
+	/**
+	 * Create a interface to the command line options.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param optionDefinitions is the list of definitions of the available command line options.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 * @see #saveVMParametersIfNotSet(Class, String[])
+	 * @see #splitOptionsAndParameters(String[])
+	 */
+	public VMCommandLine(Class<?> classToLaunch, String[] optionDefinitions, String... parameters) {
+		saveVMParametersIfNotSet(classToLaunch, parameters);
+		splitOptionsAndParameters(optionDefinitions);
+	}
+
+	/**
+	 * Create a interface to the command line options.
+	 * 
+	 * @param classToLaunch is the class which contains a <code>main</code>.
+	 * @param optionDefinitions is the list of definitions of the available command line options.
+	 * @param parameters is the parameters to pass to the <code>main</code>.
+	 * @see #saveVMParametersIfNotSet(String, String[])
+	 * @see #splitOptionsAndParameters(String[])
+	 * @since 6.2
+	 */
+	public VMCommandLine(String classToLaunch, String[] optionDefinitions, String... parameters) {
+		saveVMParametersIfNotSet(classToLaunch, parameters);
+		splitOptionsAndParameters(optionDefinitions);
+	}
+
+	/**
+	 * Create a interface to the command line options.
+	 * 
+	 * @see #VMCommandLine(Class, String[], String[])
+	 * @see #VMCommandLine(Class, String[])
+	 */
+	public VMCommandLine() {
+		if (classnameToLaunch==null) {
+			throw new IllegalArgumentException("you must call the other constructor previously"); //$NON-NLS-1$
+		}
+	}
+	
+	/** Replies if the given option is present on the command line.
+	 * 
+	 * @param optionLabel is the name of the option
+	 * @return <code>true</code> if the option is present, otherwise <code>false</code>
+	 */
+	@SuppressWarnings("static-method")
+	public boolean hasOption(String optionLabel) {
+		return hasCommandLineOption(optionLabel);
+	}
+
+	/** Replies the first value of the option.
+	 * 
+	 * @param optionLabel is the name of the option
+	 * @return the option value or <code>null</code> if the option is not present or has no value.
+	 */
+	@SuppressWarnings("static-method")
+	public Object getFirstOptionValue(String optionLabel) {
+		List<Object> options = getCommandLineOption(optionLabel);
+		if (options==null || options.isEmpty()) return null;
+		return options.get(0);
+	}
+
+	/** Replies the values of the option.
+	 * 
+	 * @param optionLabel is the name of the option
+	 * @return the option values or <code>null</code> if the option is not present.
+	 */
+	@SuppressWarnings("static-method")
+	public List<Object> getOptionValues(String optionLabel) {
+		List<Object> options = getCommandLineOption(optionLabel);
+		if (options==null) return null;
+		return Collections.unmodifiableList(options);
+	}
+
+	/** Replies the parameters on the command line that are not options.
+	 * 
+	 * @return the parameters.
+	 */
+	@SuppressWarnings("static-method")
+	public String[] getParameters() {
+		return getCommandLineParameters();
+	}
+
+	/** Shift the command line parameters by one on the left.
+	 * The first parameter is removed from the list.
+	 * 
+	 * @return the removed element or <code>null</code>
+	 */
+	@SuppressWarnings("static-method")
+	public String shiftParameters() {
+		return shiftCommandLineParameters();
+	}
+
+	/** Replies the count of parameters on the command line that are not options.
+	 * 
+	 * @return the count of parameters
+	 */
+	@SuppressWarnings("static-method")
+	public int getParameterCount() {
+		return getCommandLineParameters().length;
+	}
+
+	/** Replies the parameter at the specified index.
+	 * 
+	 * @param index
+	 * @return the value of the parameter.
+	 * @throws IndexOutOfBoundsException
+	 */
+	@SuppressWarnings("static-method")
+	public String getParameterAt(int index) {
+		return getCommandLineParameters()[index];
+	}
+
+	/** Replies if the given index corresponds to a command line parameter.
+	 * 
+	 * @param index
+	 * @return <code>true</code> if the given index corresponds to a parameter,
+	 * otherwise <code>false</code>
+	 * @throws IndexOutOfBoundsException
+	 */
+	@SuppressWarnings("static-method")
+	public boolean isParameterExists(int index) {
+		String[] params = getCommandLineParameters();
+		return index>=0 && index<params.length && params[index]!=null;
+	}
+
+	/**
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	private static enum OptionType {
+
+		/**
+		 * a simple option without value or flag.
+		 */
+		SIMPLE,
+		
+		/** an option with a mandatory string value.
+		 */
+		MANDATORY_STRING,
+
+		/** an option with an optional string value.
+		 */
+		OPTIONAL_STRING,
+
+		/** an option with a mandatory integer value.
+		 */
+		MANDATORY_INTEGER,
+
+		/** an option with an optional integer value.
+		 */
+		OPTIONAL_INTEGER,
+
+		/** an option with a mandatory floating-point value.
+		 */
+		MANDATORY_FLOAT,
+
+		/** an option with an optional floating-point value.
+		 */
+		OPTIONAL_FLOAT,
+
+		/** an option with a mandatory boolean value.
+		 */
+		MANDATORY_BOOLEAN,
+
+		/** an option with an optional boolean value.
+		 */
+		OPTIONAL_BOOLEAN,
+
+		/** an option with an auto-incremented integer value.
+		 */
+		AUTO_INCREMENTED,
+
+		/** an option which could be flaged or not: {@code --name} or {@code --noname}.
+		 */
+		FLAG;
+		
+		/** Replies if the value is mandatory.
+		 * 
+		 * @return <code>true</code> if the value is mandatory, otherwise <code>false</code>
+		 */
+		public boolean isMandatory() {
+			return this==MANDATORY_BOOLEAN
+			|| this==MANDATORY_FLOAT
+			|| this==MANDATORY_STRING
+			|| this==MANDATORY_INTEGER;
+		}
+		
+		/** Replies if the value is optional.
+		 * 
+		 * @return <code>true</code> if the value is not mandatory, otherwise <code>false</code>
+		 */
+		public boolean isOptional() {
+			return this==OPTIONAL_BOOLEAN
+			|| this==OPTIONAL_FLOAT
+			|| this==OPTIONAL_STRING
+			|| this==OPTIONAL_INTEGER;
+		}
+
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/VMCommandLine.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/Caller.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/Caller.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/Caller.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,142 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil.caller;
+
+/**
+ * This utility class provides a way to determine which class
+ * call a function.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public interface Caller {
+	
+	/** Replies the class from the stack according to its level.
+	 * <p>
+	 * The given <var>level</var> permits to specify which class to reply:
+	 * <ul>
+	 * <li><code>0</code>: the class where is defined the function (<code>f<sub>0</sub></code>) 
+	 * that has called <code>getCallerClass()</code></li>
+	 * <li><code>1</code>: the class where is defined the function (<code>f<sub>1</sub></code>) 
+	 * that has called <code>f<sub>0</sub></code></li>
+	 * <li><code>2</code>: the class where is defined the function (<code>f<sub>2</sub></code>) 
+	 * that has called <code>f<sub>1</sub></code></li>
+	 * <li>etc.</li>
+	 * </ul>
+	 * 
+	 * @param level is the desired level of the class
+	 * @return the class from the call stack according to the given level.
+	 */
+	public Class<?> getCallerClass(int level);
+
+	/** Replies the method from the stack according to its level.
+	 * <p>
+	 * The given <var>level</var> permits to specify which method to reply:
+	 * <ul>
+	 * <li><code>0</code>: the method where is defined the function (<code>f<sub>0</sub></code>) 
+	 * that has called <code>getCallerClass()</code></li>
+	 * <li><code>1</code>: the method where is defined the function (<code>f<sub>1</sub></code>) 
+	 * that has called <code>f<sub>0</sub></code></li>
+	 * <li><code>2</code>: the method where is defined the function (<code>f<sub>2</sub></code>) 
+	 * that has called <code>f<sub>1</sub></code></li>
+	 * <li>etc.</li>
+	 * </ul>
+	 * <p>
+	 * The returned value is the name of the method instead of a
+	 * <code>Method</code> instance. It is due to JRE that does not
+	 * store in the stack trace the complete prototype of the
+	 * methods. So the following code failed: the stack contains
+	 * the method name "test2", but no function has the prototype
+	 * {@code void test2()}.
+	 * <pre>
+	 * class Test {
+	 *     public void test1(int a) {
+	 *         test2();
+	 *     }
+	 *     public void test2(int a) {
+	 *     	   getCallerMethod(); // IllegalArgumentException because test1() not defined.
+	 *     }
+	 * }
+	 * </pre>
+	 * Another failure example: 
+	 * <pre>
+	 * class Test2 {
+	 *     public void test1(int a) {
+	 *         test2();
+	 *     }
+	 *     public void test1() {
+	 *     }
+	 *     public void test2(int a) {
+	 *     	   getCallerMethod(); // test1() is replied !!! not test1(int)
+	 *     }
+	 * }
+	 * </pre>
+	 * 
+	 * @param level is the desired level of the class
+	 * @return the method from the call stack according to the given level.
+	 */
+	public String getCallerMethod(int level);
+
+	/** Replies the line number of the caller from the stack according to its level.
+	 * <p>
+	 * The given <var>level</var> permits to specify which method to reply:
+	 * <ul>
+	 * <li><code>0</code>: the method where is defined the function (<code>f<sub>0</sub></code>) 
+	 * that has called <code>getCallerClass()</code></li>
+	 * <li><code>1</code>: the method where is defined the function (<code>f<sub>1</sub></code>) 
+	 * that has called <code>f<sub>0</sub></code></li>
+	 * <li><code>2</code>: the method where is defined the function (<code>f<sub>2</sub></code>) 
+	 * that has called <code>f<sub>1</sub></code></li>
+	 * <li>etc.</li>
+	 * </ul>
+	 * <p>
+	 * The returned value is the line number of the calling method.
+	 * 
+	 * @param level is the desired level of the class
+	 * @return the line number of method from the call stack
+	 * according to the given level.
+	 */
+	public long getCallerLine(int level);
+
+	/** Replies the filename of the method of the caller from the stack according to its level.
+	 * <p>
+	 * The given <var>level</var> permits to specify which method to reply:
+	 * <ul>
+	 * <li><code>0</code>: the method where is defined the function (<code>f<sub>0</sub></code>) 
+	 * that has called <code>getCallerClass()</code></li>
+	 * <li><code>1</code>: the method where is defined the function (<code>f<sub>1</sub></code>) 
+	 * that has called <code>f<sub>0</sub></code></li>
+	 * <li><code>2</code>: the method where is defined the function (<code>f<sub>2</sub></code>) 
+	 * that has called <code>f<sub>1</sub></code></li>
+	 * <li>etc.</li>
+	 * </ul>
+	 * <p>
+	 * 
+	 * @param level is the desired level of the class
+	 * @return the filename of the method from the call
+	 * stack according to the given level.
+	 */
+	public String getCallerFilename(int level);
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/Caller.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/StackTraceCaller.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/StackTraceCaller.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/StackTraceCaller.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,150 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil.caller;
+
+import org.arakhne.vmutil.ClassLoaderFinder;
+
+/**
+ * This utility class provides a way to determine which class
+ * call a function.
+ * <p>
+ * It inspirated from the Andriod API.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class StackTraceCaller implements Caller {
+
+	/**
+	 */
+	public StackTraceCaller() {
+		//
+	}
+	
+	/** Load a class but avoid any exception.
+	 * 
+	 * @param name the class name.
+	 * @return the class or <code>null</code>.
+	 */
+	public static Class<?> loadClass(String name) {
+		try {
+			return ClassLoaderFinder.findClassLoader().loadClass(name);
+		}
+		catch(AssertionError e) {
+			throw e;
+		}
+		catch(Throwable e) {
+			return null;
+		}
+	}
+
+	/** Replies the stack trace element for the given level.
+	 * <p>
+	 * The given <var>level</var> permits to specify which class to reply:
+	 * <ul>
+	 * <li><code>0</code>: the class where is defined the function (<code>f<sub>0</sub></code>) 
+	 * that has called one function of <code>Caller</code></li>
+	 * <li><code>1</code>: the class where is defined the function (<code>f<sub>1</sub></code>) 
+	 * that has called <code>f<sub>0</sub></code></li>
+	 * <li><code>2</code>: the class where is defined the function (<code>f<sub>2</sub></code>) 
+	 * that has called <code>f<sub>1</sub></code></li>
+	 * <li>etc.</li>
+	 * </ul>
+	 * 
+	 * @param level is the desired level.
+	 * @return the stack trace element; or <code>null</code>.
+	 */
+	protected static StackTraceElement getTraceElementAt(int level) {
+		if (level<0) return null;
+		try {
+			StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+			int j = -1;
+			boolean found = false;
+			Class<?> type;
+			for(int i=0; i<stackTrace.length; ++i) {
+				if (found) {
+					if (i-j==level) return stackTrace[i];
+				}
+				else {
+					type = loadClass(stackTrace[i].getClassName());
+					if (type!=null && Caller.class.isAssignableFrom(type)) {
+						j = i+1;
+					}
+					else if (j>=0) {
+						// First ocurrence of a class in the stack, after the
+						// inner invocation of StackTraceCaller
+						found = true;
+						if (i-j==level) return stackTrace[i];
+					}
+				}
+			}
+		}
+		catch(AssertionError e) {
+			throw e;
+		}
+		catch(Throwable _) {
+			//
+		}
+		return null;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public Class<?> getCallerClass(int level) {
+		StackTraceElement element = getTraceElementAt(level);
+		if (element==null) throw new IllegalArgumentException();
+		Class<?> type = loadClass(element.getClassName());
+		if (type==null) throw new IllegalArgumentException();
+		return type;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getCallerMethod(int level) {
+		StackTraceElement element = getTraceElementAt(level);
+		if (element==null) throw new IllegalArgumentException();
+		return element.getMethodName();
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public long getCallerLine(int level) {
+		StackTraceElement element = getTraceElementAt(level);
+		if (element==null) throw new IllegalArgumentException();
+		return element.getLineNumber();
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public String getCallerFilename(int level) {
+		StackTraceElement element = getTraceElementAt(level);
+		if (element==null) throw new IllegalArgumentException();
+		return element.getFileName();
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/StackTraceCaller.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/SunCaller.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/SunCaller.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/SunCaller.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,60 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil.caller;
+
+import sun.reflect.Reflection;
+
+/**
+ * This utility class provides a way to determine which class
+ * call a function.
+ * <p>
+ * It inspirated from the Sun's <code>sun.reflect.Reflection</code> class
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+@SuppressWarnings("restriction")
+public class SunCaller extends StackTraceCaller {
+	
+	/**
+	 */
+	public SunCaller() {
+		//
+	}
+	
+	/** {@inheritDoc}
+	 */
+	@Override
+	public Class<?> getCallerClass(int level) {
+    	// Parameter value of Reflection.getClassClass:
+		//
+    	// 0: Reflection.class | Reflection.getCallerClass()
+    	// 1: Caller.class     | this 
+		// 2: ???              | Caller of this function - not interesting because known
+		// 3: ???              | Caller of the caller of this function - START INTEREST HERE
+		if (level<0) throw new IllegalArgumentException();
+		return Reflection.getCallerClass(level+2);
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/caller/SunCaller.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/Handler.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/Handler.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/Handler.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,65 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.file;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLStreamHandler;
+
+import org.arakhne.vmutil.URISchemeType;
+
+/**
+ * The class <code>Handler</code> is supporting file protocol
+ * for URL streams. This stream protocol
+ * handler knows how to make a connection for "file" protocol.
+ * <p>
+ * In most cases, an instance of a <code>URLStreamHandler</code>
+ * subclass is not created directly by an application. Rather, the
+ * first time a protocol name is encountered when constructing a
+ * <code>URL</code>, the appropriate stream protocol handler is
+ * automatically loaded.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new FileURLStreamHandlerFactory());</code>.
+ * 
+ * @author $Author: galland$
+ * @author $Author: willaume$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @see URLStreamHandler
+ * @see HandlerFactory
+ * @since 6.0
+ */
+public class Handler extends URLStreamHandler {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected URLConnection openConnection(URL url) throws IOException {
+		if (URISchemeType.FILE.isURL(url)) {
+			return new URLConnection(url);
+		}
+		throw new UnsupportedOperationException("Unsupported protocol: "+url); //$NON-NLS-1$
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/Handler.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/HandlerFactory.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/HandlerFactory.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/HandlerFactory.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,61 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.file;
+
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+import org.arakhne.vmutil.URISchemeType;
+
+/**
+ * This class defines a factory for <code>URL</code> stream
+ * "resource" and "file" protocol handlers.
+ * <p>
+ * It is used by the <code>URL</code> class to create a
+ * <code>URLStreamHandler</code> for a "resource" protocol.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new FileResourceURLStreamHandlerFactory());</code>.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @see URLStreamHandlerFactory
+ * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+ * @since 6.0
+ */
+public class HandlerFactory
+implements URLStreamHandlerFactory {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public URLStreamHandler createURLStreamHandler(String protocol) {
+		if (URISchemeType.FILE.isScheme(protocol))
+            return new Handler();
+		// Force the default factory to retreive stream handler.
+		return null;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/HandlerFactory.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/URLConnection.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/URLConnection.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/URLConnection.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,210 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.file;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.UnknownServiceException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.MimetypesFileTypeMap;
+
+import org.arakhne.vmutil.FileSystem;
+
+/**
+ * The class <code>URLConnection</code> is implementing
+ * connection between an URL and a local file.
+ * Instances of this class can be used both to
+ * read from and to write to the resource referenced by the file URL.
+ * <p>
+ * Supported header fields are:
+ * <ul>
+ * <li><code>content-type</code></li>
+ * <li><code>content-length</code></li>
+ * <li><code>last-modified</code></li>
+ * </ul>
+ * 
+ * @author $Author: galland$
+ * @author $Author: willaume$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @see java.net.URLConnection
+ * @since 6.0
+ */
+class URLConnection extends java.net.URLConnection {
+
+	private File file = null;
+	
+	private String contentType = null;
+	
+	/**
+	 * @param url is the "file"-protocol url to use.
+	 */
+	protected URLConnection(URL url) {
+		super(url);
+	}
+	
+	/**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderField(int n) {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	switch(n) {
+    	case 0: // content-type
+    		return this.contentType;
+    	case 1: // content-length
+    		return Long.toString(this.file.length());
+    	case 2: // last-modified
+    		return Long.toString(this.file.lastModified());
+    	default:
+    	}
+    	return null;
+    }
+	
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderField(String name) {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	if ("content-type".equals(name)) { //$NON-NLS-1$
+    		return this.contentType;
+    	}
+    	if ("content-length".equals(name)) { //$NON-NLS-1$
+    		return Long.toString(this.file.length());
+    	}
+    	if ("last-modified".equals(name)) { //$NON-NLS-1$
+    		return Long.toString(this.file.lastModified());
+    	}
+    	return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderFieldKey(int n) {
+    	switch(n) {
+    	case 0:
+    		return "content-type"; //$NON-NLS-1$
+    	case 1:
+    		return "content-length"; //$NON-NLS-1$
+    	case 2:
+    		return "last-modified"; //$NON-NLS-1$
+    	default:
+    	}
+    	return null;
+    }
+		
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public Map<String,List<String>> getHeaderFields() {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+		Map<String, List<String>> flds = new HashMap<>();
+    	flds.put("content-type", singletonList(this.contentType)); //$NON-NLS-1$
+    	flds.put("content-length", singletonList(Long.toString(this.file.length()))); //$NON-NLS-1$
+    	flds.put("last-modified", singletonList(Long.toString(this.file.lastModified()))); //$NON-NLS-1$
+        return flds;
+    }
+	
+	private static List<String> singletonList(String value) {
+		if (value==null) return null;
+		return Collections.singletonList(value);
+	}
+
+    /**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void connect() throws IOException {
+		if (!this.connected) {
+			this.file = FileSystem.convertURLToFile(this.url);
+			if (this.file==null)
+				throw new FileNotFoundException(this.url.toExternalForm());
+			this.contentType = new MimetypesFileTypeMap().getContentType(this.file);
+			this.connected = true;
+		}
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public OutputStream getOutputStream() throws IOException {
+        connect();
+		if (getDoOutput()) {
+			OutputStream os = new FileOutputStream(this.file);
+			if (getUseCaches()) {
+				os = new BufferedOutputStream(os);
+			}
+			return os;
+		}
+		throw new UnknownServiceException("URL connection cannot do output"); //$NON-NLS-1$
+    }
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public InputStream getInputStream() throws IOException {
+        connect();
+		if (getDoInput()) {
+			InputStream is = new FileInputStream(this.file);
+			if (getUseCaches()) {
+				is = new BufferedInputStream(is);
+			}
+			return is;
+		}
+		throw new UnknownServiceException("URL connection cannot do input"); //$NON-NLS-1$
+    }
+	
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/file/URLConnection.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/Locale.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/Locale.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/Locale.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,585 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (c) 2008-10, Multiagent Team,
+ * Laboratoire Systemes et Transports,
+ * Universite de Technologie de Belfort-Montbeliard.
+ * All rights reserved.
+ *
+ * Copyright (C) 2012 Stephane GALLAND, Olivier LAMOTTE.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil.locale;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Map.Entry;
+
+import org.arakhne.vmutil.Caller;
+import org.arakhne.vmutil.ClassLoaderFinder;
+
+/**
+ * This utility class permits a easier use of localized strings.
+ * <code>Locale</code> provides a means to retreive
+ * messages in the default language. Use this to construct messages
+ * displayed for end users.
+ * <p>
+ * <code>Locale</code> takes a string from a properties resource, 
+ * then inserts the parameter strings into the extracted strings
+ * at the appropriate places.
+ * The pattern matching is proceeded with {@link LocaleMessageFormat}
+ * formatter. Note that <code>''</code> may represent a single quote
+ * in strings (see {@link LocaleMessageFormat} for details).
+ * 
+ * FIXME: Does java.text.Normalizer may replace decodeString functions?
+ *
+ * @author $Author: galland$
+ * @author $Author: lamotte$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.4
+ */
+public class Locale {
+	
+	private static Class<?> detectResourceClass(Class<?> resource) {
+    	if (resource==null) {
+        	// Parameter value:
+        	// 0: is always Locale.class (ie. this PRIVATE function)
+        	// 1: is always Locale.class (ie. the caller of this PRIVATE function)
+        	// 2: is the third top of the trace stack ie, the first caller outside Locale.class
+    		return Caller.getCallerClass(2);
+    	}
+    	return resource;
+	}
+    
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * <p>
+     * The <code>resourcePath</code> argument should be a fully 
+     * qualified class name. However, for compatibility with earlier 
+     * versions, Sun's Java SE Runtime Environments do not verify this,
+     * and so it is possible to access <code>PropertyResourceBundle</code>s
+     * by specifying a path name (using "/") instead of a fully 
+     * qualified class name (using ".").
+     * 
+     * @param resourcePath is the name (path) of the resource file, a fully qualified class name
+     * @param key is the name of the resource into the specified file
+     * @param defaultValue is the default value to replies if the resource does not contain the specified key. 
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringWithDefaultFrom(String resourcePath, String key, String defaultValue, Object... params) {
+        // This method try to use the plugin manager class loader
+        // if it exists, otherwhise, it use the default class loader        
+    	return getStringWithDefaultFrom(
+    			ClassLoaderFinder.findClassLoader(),
+    			resourcePath, key, defaultValue, params);
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * <p>
+     * The <code>resourcePath</code> argument should be a fully 
+     * qualified class name. However, for compatibility with earlier 
+     * versions, Sun's Java SE Runtime Environments do not verify this,
+     * and so it is possible to access <code>PropertyResourceBundle</code>s
+     * by specifying a path name (using "/") instead of a fully 
+     * qualified class name (using ".").
+     * 
+     * @param classLoader is the class loader to use, a fully qualified class name
+     * @param resourcePath is the name (path) of the resource file
+     * @param key is the name of the resource into the specified file
+     * @param defaultValue is the default value to replies if the resource does not contain the specified key. 
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringWithDefaultFrom(ClassLoader classLoader, String resourcePath, String key, String defaultValue, Object... params) {
+
+        if (resourcePath == null) return defaultValue;
+        
+        // Get the resource file
+        ResourceBundle resource = null;
+        try {
+        	resource = ResourceBundle.getBundle(resourcePath,
+            		java.util.Locale.getDefault(),
+            		classLoader);
+        }
+        catch (MissingResourceException exep) {
+            return defaultValue;
+        }
+        
+        // get the resource string
+        String result;
+        
+        try {
+            result = resource.getString(key);
+        }
+        catch (Exception e) {
+            return defaultValue;
+        }
+
+        // replace the \n and \r by a real new line character
+        result = result.replaceAll("[\\n\\r]","\n"); //$NON-NLS-1$ //$NON-NLS-2$
+        result = result.replaceAll("\\t","\t"); //$NON-NLS-1$ //$NON-NLS-2$
+        
+        // replace the parameter values
+        assert(params!=null);
+ 		return LocaleMessageFormat.format(result, params);
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * <p>
+     * The <code>resourcePath</code> argument should be a fully 
+     * qualified class name. However, for compatibility with earlier 
+     * versions, Sun's Java SE Runtime Environments do not verify this,
+     * and so it is possible to access <code>PropertyResourceBundle</code>s
+     * by specifying a path name (using "/") instead of a fully 
+     * qualified class name (using ".").
+     * 
+     * @param resourcePath is the name (path) of the resource file, a fully qualified class name
+     * @param key is the name of the resource into the specified file
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringFrom(String resourcePath, String key, Object... params) {
+    	return getStringWithDefaultFrom(resourcePath, key, key, params);
+    }
+    
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * <p>
+     * The <code>resourcePath</code> argument should be a fully 
+     * qualified class name. However, for compatibility with earlier 
+     * versions, Sun's Java SE Runtime Environments do not verify this,
+     * and so it is possible to access <code>PropertyResourceBundle</code>s
+     * by specifying a path name (using "/") instead of a fully 
+     * qualified class name (using ".").
+     *  
+     * @param classLoader is the classLoader to use.
+     * @param resourcePath is the name (path) of the resource file, a fully qualified class name
+     * @param key is the name of the resource into the specified file
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringFrom(ClassLoader classLoader, String resourcePath, String key, Object... params) {
+    	return getStringWithDefaultFrom(classLoader,resourcePath, key, key, params);
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * 
+     * @param resource is the name of the resource file
+     * @param key is the name of the resource into the specified file
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getString(Class<?> resource, String key, Object... params) {
+    	Class<?> res = detectResourceClass(resource);
+    	return getString(ClassLoaderFinder.findClassLoader(),res,key,params);
+    }
+    
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * 
+     * @param classLoader is the class loader to use.
+     * @param resource is the name of the resource file
+     * @param key is the name of the resource into the specified file
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getString(ClassLoader classLoader, Class<?> resource, String key, Object... params) {
+    	Class<?> res = detectResourceClass(resource);
+    	if (res==null) return key;
+    	String val = getStringWithDefaultFrom(classLoader,res.getCanonicalName(),key,null,params);
+    	if (val==null && classLoader!=resource.getClassLoader()) {
+    		val = getStringWithDefaultFrom(classLoader,res.getCanonicalName(),key,null,params);
+    	}
+    	while ((res!=null)&&(val==null)) {
+    		res = res.getSuperclass();
+    		if (res!=null) {
+    			val = getStringWithDefaultFrom(classLoader,res.getCanonicalName(),key,null,params);
+    		}
+    	}    	
+    	if (val==null) return key;
+    	return val;
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * 
+     * @param resource is the name of the resource file
+     * @param key is the name of the resource into the specified file
+     * @param defaultValue is the default value to replies if the resource does not contain the specified key. 
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringWithDefault(Class<?> resource, String key, String defaultValue, Object... params) {
+    	Class<? >res = detectResourceClass(resource);
+    	return getStringWithDefault(ClassLoaderFinder.findClassLoader(),res,key,defaultValue,params);
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * 
+     * @param classLoader is the class loader to use.
+     * @param resource is the name of the resource file
+     * @param key is the name of the resource into the specified file
+     * @param defaultValue is the default value to replies if the resource does not contain the specified key. 
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringWithDefault(ClassLoader classLoader, Class<?> resource, String key, String defaultValue, Object... params) {
+    	Class<?> res = detectResourceClass(resource);
+    	if (res==null) return defaultValue;
+    	String val = getStringWithDefaultFrom(classLoader,res.getCanonicalName(),key,null,params);
+    	if (val==null && classLoader!=resource.getClassLoader()) {
+    		val = getStringWithDefaultFrom(classLoader,res.getCanonicalName(),key,null,params);
+    	}
+    	while ((res!=null)&&(val==null)) {
+    		res = res.getSuperclass();
+    		if (res!=null) {
+    			val = getStringWithDefaultFrom(classLoader,res.getCanonicalName(),key,null,params);
+    		}
+    	}    	
+    	if (val==null) return defaultValue;
+    	return val;
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * <p>
+     * This function assumes the classname of the caller as the
+     * resource provider. 
+     * 
+     * @param key is the name of the resource into the specified file
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getString(String key, Object... params) {
+    	Class<?> resource = detectResourceClass(null);
+    	return getString(ClassLoaderFinder.findClassLoader(),resource,key,params);
+    }
+    
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * <p>
+     * This function assumes the classname of the caller as the
+     * resource provider. 
+     * 
+     * @param classLoader is the classLoader to use.
+     * @param key is the name of the resource into the specified file
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getString(ClassLoader classLoader, String key, Object... params) {
+    	Class<?> resource = detectResourceClass(null);
+    	return getString(classLoader,resource,key,params);
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * 
+     * @param key is the name of the resource into the specified file
+     * @param defaultValue is the default value to replies if the resource does not contain the specified key. 
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringWithDefault(String key, String defaultValue, Object... params) {
+    	Class<?> resource = detectResourceClass(null);
+    	return getStringWithDefault(ClassLoaderFinder.findClassLoader(),resource,key,defaultValue,params);
+    }
+
+    /**
+     * Replies the text that corresponds to the specified resource.
+     * 
+     * @param classLoader is the class loader to use.
+     * @param key is the name of the resource into the specified file
+     * @param defaultValue is the default value to replies if the resource does not contain the specified key. 
+     * @param params is the the list of parameters which will
+     * replaces the <code>#1</code>, <code>#2</code>... into the string.
+     * @return the text that corresponds to the specified resource
+     */
+    public static String getStringWithDefault(ClassLoader classLoader, String key, String defaultValue, Object... params) {
+    	Class<?> resource = detectResourceClass(null);
+    	return getStringWithDefault(classLoader,resource,key,defaultValue,params);
+    }
+
+    /** Decode the specified array of bytes according to
+     * a charset selection. This function tries
+     * to decode a string from the given byte array
+     * with the following charsets (in preferred order):
+     * <ul>
+     * <li>the current charset returned by {@link Charset#defaultCharset()},</li>
+     * <li>OEM United States: IBM437,</li>
+     * <li>West European: ISO-8859-1,</li>
+     * <li>one of the charst returned by {@link Charset#availableCharsets()}.</li>
+     * </ul>
+     * <p>
+     * The IBM437 charset was added to support several specific files (Dbase files)
+     * generated from a GIS.
+     * 
+     * @param bytes is the array of bytes to decode.
+     * @return the decoded string with the appropriate charset set.
+     */
+    public static String decodeString(byte[] bytes) {
+    	Charset default_charset = Charset.defaultCharset();
+    	Charset west_european = Charset.forName("ISO-8859-1"); //$NON-NLS-1$
+    	Charset utf = Charset.forName("UTF-8"); //$NON-NLS-1$
+    	
+    	String refBuffer = new String(bytes);
+    	
+		CharBuffer buffer = decodeString(bytes,default_charset,refBuffer.length());
+
+		if ((buffer==null)&&(!default_charset.equals(west_european))) {
+			buffer = decodeString(bytes,west_european,refBuffer.length());
+		}
+    	
+		if ((buffer==null)&&(!default_charset.equals(utf))) {
+			buffer = decodeString(bytes,utf,refBuffer.length());
+		}
+
+		if (buffer==null) {
+    		// Decode until one of the available charset replied a value
+	    	for (Charset charset : Charset.availableCharsets().values()) {
+				buffer = decodeString(bytes,charset,refBuffer.length());
+				if (buffer!=null) break;
+	    	}
+    	}
+    	// Use the default encoding
+    	if (buffer==null) return refBuffer;
+    	return buffer.toString();
+    }
+   
+    /** Decode the specified array of bytes with the specified charset.
+     * 
+     * @param bytes is the array of bytes to decode.
+     * @param charset is the charset to use for decoding
+     * @param referenceLength is the length of the attempted result. If negative, this parameter is ignored.
+     * @return the decoded string with the appropriate charset set,
+     * or <code>null</code> if the specified charset cannot be
+     * used to decode all the characters inside the byte array.
+     */
+    private static CharBuffer decodeString(byte[] bytes, Charset charset, int referenceLength) {
+    	try {
+    		Charset autodetected_charset = charset;
+        	CharsetDecoder decoder = charset.newDecoder();
+			CharBuffer buffer = decoder.decode(ByteBuffer.wrap(bytes));
+			if ((decoder.isAutoDetecting())&&
+				(decoder.isCharsetDetected())) {
+				autodetected_charset = decoder.detectedCharset();
+				if (charset.contains(autodetected_charset)) {
+					buffer.position(0);
+					if ((referenceLength>=0)&&(buffer.remaining()==referenceLength))
+						return buffer;
+					return null;
+				}
+			}
+			// Apply a proprietaty detection
+			buffer.position(0);
+			char c;
+			int type;
+			while (buffer.hasRemaining()) {
+				c = buffer.get();
+				type = Character.getType(c);
+	        	switch(type) {
+	        	case Character.UNASSIGNED:
+	        	case Character.CONTROL:
+	        	case Character.FORMAT:
+	        	case Character.PRIVATE_USE:
+	        	case Character.SURROGATE:
+		        	// Character not supported?
+	        		return null;
+	        	default:
+	        	}
+			}
+			buffer.position(0);
+			if ((referenceLength>=0)&&(buffer.remaining()==referenceLength))
+				return buffer;
+		}
+    	catch (CharacterCodingException e) {
+			//
+		}
+    	return null;
+    }
+    
+    /** Decode the bytes from the specified input stream
+     * according to a charset selection. This function tries
+     * to decode a string from the given byte array
+     * with the following charsets (in preferred order):
+     * <ul>
+     * <li>the current charset returned by {@link Charset#defaultCharset()},</li>
+     * <li>OEM United States: IBM437,</li>
+     * <li>West European: ISO-8859-1,</li>
+     * <li>one of the charst returned by {@link Charset#availableCharsets()}.</li>
+     * </ul>
+     * <p>
+     * The IBM437 charset was added to support several specific files (Dbase files)
+     * generated from a GIS.
+     * 
+     * @param stream is the stream to decode.
+     * @return the decoded string with the appropriate charset set.
+     * @throws IOException 
+     */
+    public static String decodeString(InputStream stream) throws IOException {
+    	byte[] complete_buffer = new byte[0];
+    	byte[] buffer = new byte[2048];
+    	int red;
+    	
+    	while ((red=stream.read(buffer))>0) {
+    		byte[] tmp = new byte[complete_buffer.length+red];
+    		System.arraycopy(complete_buffer,0,tmp,0,complete_buffer.length);
+    		System.arraycopy(buffer,0,tmp,complete_buffer.length,red);
+    		complete_buffer = tmp;
+    		tmp = null;
+    	}
+    	
+    	String s = decodeString(complete_buffer);
+    	complete_buffer = null;
+    	buffer = null;
+    	return s;
+    }
+
+    /** Decode the bytes from the specified input stream
+     * according to a charset selection. This function tries
+     * to decode a string from the given byte array
+     * with the following charsets (in preferred order):
+     * <ul>
+     * <li>the current charset returned by {@link Charset#defaultCharset()},</li>
+     * <li>OEM United States: IBM437,</li>
+     * <li>West European: ISO-8859-1,</li>
+     * <li>one of the charst returned by {@link Charset#availableCharsets()}.</li>
+     * </ul>
+     * <p>
+     * The IBM437 charset was added to support several specific files (Dbase files)
+     * generated from a GIS.
+     * <p>
+     * This function read the input stream line by line.
+     * 
+     * @param stream is the stream to decode.
+     * @param lineArray is the array of lines to fill
+     * @return <code>true</code> is the decoding was successful,
+     * otherwhise <code>false</code>
+     * @throws IOException 
+     */
+    public static boolean decodeString(InputStream stream, List<String> lineArray) throws IOException {
+    	// Read the complete file
+    	byte[] complete_buffer = new byte[0];
+    	byte[] buffer = new byte[2048];
+    	int red;
+    	
+    	while ((red=stream.read(buffer))>0) {
+    		byte[] tmp = new byte[complete_buffer.length+red];
+    		System.arraycopy(complete_buffer,0,tmp,0,complete_buffer.length);
+    		System.arraycopy(buffer,0,tmp,complete_buffer.length,red);
+    		complete_buffer = tmp;
+    		tmp = null;
+    	}
+
+    	buffer = null;
+    	
+    	// Get the two default charsets
+    	//Charset oem_us = Charset.forName("IBM437"); //$NON-NLS-1$
+    	Charset west_european = Charset.forName("ISO-8859-1"); //$NON-NLS-1$
+    	Charset default_charset = Charset.defaultCharset();
+    	
+    	// Decode with the current charset
+    	boolean ok = decodeString(new ByteArrayInputStream(complete_buffer),lineArray,default_charset);
+    	
+    	// Decode with the default oem US charset
+    	/*if ((!ok)&&(!default_charset.equals(oem_us))) {
+    		ok = decodeString(new ByteArrayInputStream(complete_buffer),lineArray,oem_us); 
+    	}*/
+
+    	// Decode with the default west european charset
+    	if ((!ok)&&(!default_charset.equals(west_european))) {
+    		ok = decodeString(new ByteArrayInputStream(complete_buffer),lineArray,west_european); 
+    	}
+    	
+		// Decode until one of the available charset replied a value
+    	if (!ok) {
+	    	for (Entry<String,Charset> charset : Charset.availableCharsets().entrySet()) {
+				if (decodeString(new ByteArrayInputStream(complete_buffer),lineArray,charset.getValue())) {
+					complete_buffer = null;
+					return true;
+				}
+			}
+    	}
+
+		complete_buffer = null;
+    	return ok;
+    }
+
+    /** Decode the bytes from the specified input stream
+     * according to a charset selection. This function tries
+     * to decode a string from the given byte array
+     * with the following charsets (in preferred order):
+     * <p>
+     * This function read the input stream line by line.
+     * 
+     * @param stream is the stream to decode.
+     * @param lineArray is the array of lines to fill.
+     * @param charset is the charset to use.
+     * @return <code>true</code> is the decoding was successful,
+     * otherwhise <code>false</code>
+     * @throws IOException 
+     */
+    private static boolean decodeString(InputStream stream, List<String> lineArray, Charset charset) throws IOException {
+    	try {
+    		BufferedReader breader = new BufferedReader(
+    				new InputStreamReader(stream,charset.newDecoder()));
+    		
+    		lineArray.clear();
+    		
+    		String line;
+    		while ((line=breader.readLine())!=null) {
+    			lineArray.add(line);
+    		}
+    		
+    		return true;
+    	}
+    	catch(CharacterCodingException _) {
+    		//
+    	}
+    	return false;
+    }
+    
+}
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/Locale.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/LocaleMessageFormat.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/LocaleMessageFormat.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/LocaleMessageFormat.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,326 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (c) 2011, Multiagent Team,
+ * Laboratoire Systemes et Transports,
+ * Universite de Technologie de Belfort-Montbeliard.
+ * All rights reserved.
+ *
+ * Copyright (C) 2012 Stephane GALLAND, Olivier LAMOTTE.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil.locale;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * <code>LocaleMessageFormat</code> provides a means to produce concatenated
+ * messages in a language-neutral way in the {@link Locale}
+ * utility class.
+ * <p>
+ * <code>LocaleMessageFormat</code> takes a set of objects, formats them, then
+ * inserts the formatted strings into the pattern at the appropriate places.
+ * <p>
+ * In addition to the standard JDK {@link MessageFormat}, <code>LocaleMessageFormat</code>
+ * provides the <code>FormatStyle</code> named "raw". This new style does not try
+ * to format the given data according to the locale. It simply put the 
+ * not-formatted data in the result.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 6.4
+ */
+public class LocaleMessageFormat extends MessageFormat {
+
+	private static final long serialVersionUID = 6637824487735941754L;
+	
+	/** String that corresponds to the raw format style.
+	 */
+	public static final String RAW_FORMAT_STYLE = "raw"; //$NON-NLS-1$
+
+	/**
+	 * Creates a LocaleMessageFormat with the given pattern and uses it
+	 * to format the given arguments. This is equivalent to
+	 * <blockquote>
+	 *     <code>(new {@link #LocaleMessageFormat(String) MessageFormat}(pattern)).{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code>
+	 * </blockquote>
+	 *
+	 * @exception IllegalArgumentException if the pattern is invalid,
+	 *            or if an argument in the <code>arguments</code> array
+	 *            is not of the type expected by the format element(s)
+	 *            that use it.
+	 */
+	public static String format(String pattern, Object ... arguments) {
+		LocaleMessageFormat temp = new LocaleMessageFormat(pattern);
+		return temp.format(arguments);
+	}
+
+	/**
+	 * @param pattern the pattern for this message format
+	 * @exception IllegalArgumentException if the pattern is invalid
+	 */
+	public LocaleMessageFormat(String pattern) {
+		super(pattern);
+	}
+
+	/**
+	 * @param pattern the pattern for this message format
+	 * @param locale the locale for this message format
+	 * @exception IllegalArgumentException if the pattern is invalid
+	 */
+	public LocaleMessageFormat(String pattern, Locale locale) {
+		super(pattern, locale);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void applyPattern(String pattern) {
+		super.applyPattern(pattern);
+		Format[] formats = getFormats();
+		boolean changed = false;
+		for(int i=0; i<formats.length; ++i) {
+			if (formats[i] instanceof DecimalFormat) {
+				DecimalFormat df = (DecimalFormat)formats[i];
+				if (RAW_FORMAT_STYLE.equalsIgnoreCase(df.getPositivePrefix())) {
+					formats[i] = new RawNumberFormat(
+							pattern,
+							df.getGroupingSize(),
+							df.getMinimumIntegerDigits(),
+							df.getMaximumIntegerDigits(),
+							df.getMinimumFractionDigits(),
+							df.getMaximumFractionDigits(),
+							df.getRoundingMode());
+					changed = true;
+				}
+			}
+		}
+		if (changed) {
+			setFormats(formats);
+		}
+	}
+
+	/**
+	 * @author $Author: sgalland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	private static class RawNumberFormat extends NumberFormat {
+
+		private static final long serialVersionUID = 7091190928835741939L;
+
+		private static final char RAW_NEGATIVE_SIGN = '-';
+		private static final char RAW_DECIMAL_SEPARATOR = '.';
+		private static final char RAW_ZERO_DIGIT = '0';
+		
+		private final boolean isUnformatted;
+		private final RoundingMode roundingMode;
+		
+		/**
+		 * @param pattern
+		 * @param groupSize
+		 * @param minInt
+		 * @param maxInt
+		 * @param minFrac
+		 * @param maxFrac
+		 * @param roundingMode
+		 */
+		public RawNumberFormat(String pattern, int groupSize, int minInt, int maxInt, int minFrac, int maxFrac, RoundingMode roundingMode) {
+			super();
+			this.roundingMode = roundingMode;
+			this.isUnformatted = (groupSize==0) && (minInt==0) && (maxInt==Integer.MAX_VALUE) && (minFrac==0) && (maxFrac==0);
+			setMinimumIntegerDigits(minInt);
+			setMaximumIntegerDigits(maxInt);
+			setMinimumFractionDigits(minFrac);
+			setMaximumFractionDigits(maxFrac);
+		}
+		
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) {
+			if (number instanceof BigInteger) {
+				return format((BigInteger)number, toAppendTo, pos);
+			}
+			if (number instanceof BigDecimal) {
+				return format((BigDecimal)number, toAppendTo, pos);
+			}
+			return super.format(number, toAppendTo, pos);
+		}
+		
+		private void formatInteger(boolean negative, String number, StringBuffer toAppendTo) {
+			assert(!this.isUnformatted);
+			
+			if (negative) toAppendTo.append(RAW_NEGATIVE_SIGN);
+			
+			for(int c=getMinimumIntegerDigits()-number.length(); c>0; --c) {
+				toAppendTo.append(RAW_ZERO_DIGIT);
+			}
+			
+			toAppendTo.append(number);
+
+			int n = getMinimumFractionDigits();
+			if (n>0) {
+				toAppendTo.append(RAW_DECIMAL_SEPARATOR);
+				for(int c=0; c<n; ++c) {
+					toAppendTo.append(RAW_ZERO_DIGIT);
+				}
+			}
+		}
+	    
+		private void formatDecimal(BigDecimal number, StringBuffer toAppendTo) {
+			assert(!this.isUnformatted);
+			
+			boolean negative = (number.compareTo(BigDecimal.ZERO)<0);
+			int minInt = getMinimumIntegerDigits();
+			int minFrac = getMinimumFractionDigits();
+			int maxFrac = getMaximumFractionDigits();
+			
+			BigDecimal n = number.setScale(maxFrac, this.roundingMode);
+			
+			String rawString = n.abs().toPlainString();
+			int decimalPos = rawString.indexOf(RAW_DECIMAL_SEPARATOR);
+			String integer, decimal;
+			if (decimalPos<0) {
+				integer = rawString;
+				decimal = ""; //$NON-NLS-1$
+			}
+			else {
+				integer = rawString.substring(0, decimalPos);
+				decimal = rawString.substring(decimalPos+1);
+			}
+			
+			if (negative) toAppendTo.append(RAW_NEGATIVE_SIGN);
+			
+			int c = minInt - integer.length();
+			while (c>0) {
+				toAppendTo.append(RAW_ZERO_DIGIT);
+				--c;
+			}
+			
+			toAppendTo.append(integer);
+			
+			if (minFrac>0 || (maxFrac>0 && decimal.length()>0)) {
+				toAppendTo.append(RAW_DECIMAL_SEPARATOR);
+				toAppendTo.append(decimal);
+				
+				c = minFrac - decimal.length();
+				while (c>0) {
+					toAppendTo.append(RAW_ZERO_DIGIT);
+					--c;
+				}
+			}
+		}
+		
+		/**
+		 * Specialization of format.
+		 * 
+		 * @param number is the number to format.
+		 * @param toAppendTo is the string buffer into which the formatting result may be appended.
+		 * @param pos is on input: an alignment field, if desired. On output: the offsets of 
+		 * 	the alignment field.
+		 * @return the value passed in as <code>toAppendTo</code>
+		 * @throws ArithmeticException if rounding is needed with rounding
+		 *                   mode being set to RoundingMode.UNNECESSARY
+		 * @see java.text.Format#format
+		 */
+		public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {
+			if (this.isUnformatted) {
+				toAppendTo.append(number.toString());
+			}
+			else {
+				formatInteger(number.signum()<0, number.abs().toString(), toAppendTo);
+			}
+			return toAppendTo;
+		}
+
+		/**
+		 * Specialization of format.
+		 * 
+		 * @param number is the number to format.
+		 * @param toAppendTo is the string buffer into which the formatting result may be appended.
+		 * @param pos is on input: an alignment field, if desired. On output: the offsets of 
+		 * 	the alignment field.
+		 * @return the value passed in as <code>toAppendTo</code>
+		 * @throws ArithmeticException if rounding is needed with rounding
+		 *                   mode being set to RoundingMode.UNNECESSARY
+		 * @see java.text.Format#format
+		 */
+		public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
+			if (this.isUnformatted) {
+				toAppendTo.append(number.toPlainString());
+			}
+			else {
+				formatDecimal(number, toAppendTo);
+			}
+			return toAppendTo;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
+			if (this.isUnformatted) {
+				toAppendTo.append(Double.toString(number));
+			}
+			else {
+				formatDecimal(new BigDecimal(number), toAppendTo);
+			}
+			return toAppendTo;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
+			if (this.isUnformatted) {
+				toAppendTo.append(Long.toString(number));
+			}
+			else {
+				formatInteger(number<0, Long.toString(Math.abs(number)), toAppendTo);
+			}
+			return toAppendTo;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public Number parse(String source, ParsePosition parsePosition) {
+			throw new UnsupportedOperationException();
+		}
+
+	} // class RawNumberFormat
+
+}
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/locale/LocaleMessageFormat.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/Handler.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/Handler.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/Handler.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,64 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.resource;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLStreamHandler;
+
+import org.arakhne.vmutil.URISchemeType;
+
+/**
+ * The class <code>Handler</code> is supporting resource protocol
+ * for URL streams. This stream protocol
+ * handler knows how to make a connection for "resource" protocol.
+ * <p>
+ * In most cases, an instance of a <code>URLStreamHandler</code>
+ * subclass is not created directly by an application. Rather, the
+ * first time a protocol name is encountered when constructing a
+ * <code>URL</code>, the appropriate stream protocol handler is
+ * automatically loaded.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new ResourceURLStreamHandlerFactory());</code>.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @see URLStreamHandler
+ * @see HandlerFactory
+ * @since 6.0
+ */
+public class Handler extends URLStreamHandler {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected URLConnection openConnection(URL url) throws IOException {
+		if (URISchemeType.RESOURCE.isURL(url)) {
+			return new URLConnection(url);
+		}
+		throw new UnsupportedOperationException("Unsupported protocol: "+url); //$NON-NLS-1$
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/Handler.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/HandlerFactory.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/HandlerFactory.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/HandlerFactory.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,61 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.resource;
+
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+import org.arakhne.vmutil.URISchemeType;
+
+/**
+ * This class defines a factory for <code>URL</code> stream
+ * "resource" protocol handlers.
+ * <p>
+ * It is used by the <code>URL</code> class to create a
+ * <code>URLStreamHandler</code> for a "resource" protocol.
+ * <p>
+ * To use this factory, invoke the following code only ONCE time:
+ * <code>URL.setURLStreamHandlerFactory(new ResourceURLStreamHandlerFactory());</code>.
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @see URLStreamHandlerFactory
+ * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+ * @since 6.0
+ */
+public class HandlerFactory
+implements URLStreamHandlerFactory {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public URLStreamHandler createURLStreamHandler(String protocol) {
+		if (URISchemeType.RESOURCE.isScheme(protocol))
+            return new Handler();
+		// Force the default factory to retreive stream handler.
+		return null;
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/HandlerFactory.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/URLConnection.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/URLConnection.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/URLConnection.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,159 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Alexandre WILLAUME, Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+import org.arakhne.vmutil.ResourceNotFoundException;
+import org.arakhne.vmutil.Resources;
+
+/**
+ * The class <code>URLConnection</code> is implementing
+ * connection between an URL and a Java resource.
+ * Instances of this class can be used to
+ * read from the resource referenced by the resource URL. Write
+ * is allowed depending on where resource is located.
+ * <p>
+ * Supported header fields are the same as the real resource URL
+ * (basicaly, file or jar protocols).
+ * 
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @see URLConnection
+ * @since 6.0
+ */
+class URLConnection extends java.net.URLConnection {
+
+	private URL location = null;
+	private java.net.URLConnection connection = null;
+	
+	/**
+	 * @param url is the "file"-protocol url to use.
+	 */
+	protected URLConnection(URL url) {
+		super(url);
+	}
+	
+	/**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderField(int n) {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	return this.connection.getHeaderField(n);
+    }
+	
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderField(String name) {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	return this.connection.getHeaderField(name);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public String getHeaderFieldKey(int n) {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	return this.connection.getHeaderFieldKey(n);
+    }
+		
+    /**
+     * {@inheritDoc}
+     */
+	@Override
+    public Map<String,List<String>> getHeaderFields() {
+		try {
+			connect();
+		}
+		catch(IOException e) {
+			throw new IllegalStateException(e);
+		}
+    	return this.connection.getHeaderFields();
+    }
+	
+    /**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void connect() throws IOException {
+		if (!this.connected) {
+			this.location = Resources.getResource(this.url.getFile());
+			if (this.location==null)
+				throw new ResourceNotFoundException(this.url.toExternalForm());
+			this.connection = this.location.openConnection();
+			if (this.connection==null)
+				throw new ResourceNotFoundException(this.url.toExternalForm());
+			this.connection.setDoInput(getDoInput());
+			this.connection.setDoOutput(getDoOutput());
+			this.connection.setAllowUserInteraction(getAllowUserInteraction());
+			this.connection.setConnectTimeout(getConnectTimeout());
+			this.connection.setDefaultUseCaches(getDefaultUseCaches());
+			this.connection.setReadTimeout(getReadTimeout());
+			this.connection.setIfModifiedSince(getIfModifiedSince());
+			this.connected = true;
+		}
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public OutputStream getOutputStream() throws IOException {
+        connect();
+        return this.connection.getOutputStream();
+    }
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public InputStream getInputStream() throws IOException {
+        connect();
+        return this.connection.getInputStream();
+    }
+	
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/java/org/arakhne/vmutil/resource/URLConnection.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem.properties
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem.properties	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem.properties	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,20 @@
+# $Id$
+# 
+# Copyright (C) 2011 Stephane GALLAND.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# This program is free software; you can redistribute it and/or modify
+
+NATIVE_NOT_SUPPORTED = Your operating system is not supporting the native methods defined in OperatingSystem. They may replies null value. 


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem_fr.properties
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem_fr.properties	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem_fr.properties	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,20 @@
+# $Id$
+# 
+# Copyright (C) 2011 Stephane GALLAND.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# This program is free software; you can redistribute it and/or modify
+
+NATIVE_NOT_SUPPORTED = Votre syst\xE8me d'exploitation ne supporte pas les fonctions natives d\xE9finies dans OperatingSystem. Ces fonctions retourneront la valeur null. 


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/main/resources/org/arakhne/vmutil/OperatingSystem_fr.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/CallerTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/CallerTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/CallerTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,159 @@
+/* $Id$
+ * 
+ * Copyright (C) 2007-09 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import junit.framework.TestCase;
+
+/**
+ * @author $Author: galland$
+ * @version $Name$ $Revision$ $Date$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneVmutils
+ */
+public class CallerTest extends TestCase {
+
+	private InnerCallerTest caller;
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		this.caller = new InnerCallerTest();
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void tearDown() throws Exception {
+		this.caller = null;
+		super.tearDown();
+	}
+	
+	/**
+	 * @return caller
+	 */
+	static String innerTestGetCallerMethod() {
+		String m = Caller.getCallerMethod();
+		assertNotNull(m);
+		return m;
+	}
+
+	/**
+	 * @return caller
+	 */
+	static Class<?> innerTestGetCallerClass() {
+		Class<?> c = Caller.getCallerClass();
+		assertNotNull(c);
+		return c;
+	}
+
+	/**
+	 * @param level
+	 * @return caller
+	 */
+	static Class<?> innerTestGetCallerClass(int level) {
+		Class<?> c = Caller.getCallerClass(level);
+		assertNotNull(c);
+		return c;
+	}
+
+	/**
+	 * @param level
+	 * @return caller
+	 */
+	static String innerTestGetCallerMethod(int level) {
+		String m = Caller.getCallerMethod(level);
+		assertNotNull(m);
+		return m;
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public void testGetCallerMethod() throws Exception {
+    	assertEquals("innerinnerTestGetCallerMethod", //$NON-NLS-1$
+    			this.caller.innerinnerTestGetCallerMethod());
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public void testGetCallerClass() throws Exception {
+    	assertEquals(InnerCallerTest.class, this.caller.innerinnerTestGetCallerClass());
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public void testGetCallerClassInt() throws Exception {
+    	assertEquals(CallerTest.class, this.caller.innerinnerTestGetCallerClass(0));
+    	assertEquals(InnerCallerTest.class, this.caller.innerinnerTestGetCallerClass(1));
+    	assertEquals(CallerTest.class, this.caller.innerinnerTestGetCallerClass(2));
+	}
+	
+	/**
+	 * @throws Exception
+	 */
+	public void testGetCallerMethodInt() throws Exception {
+    	assertEquals("innerTestGetCallerMethod", //$NON-NLS-1$
+    			this.caller.innerinnerTestGetCallerMethod(0));
+    	assertEquals("innerinnerTestGetCallerMethod", //$NON-NLS-1$
+    			this.caller.innerinnerTestGetCallerMethod(1));
+    	assertEquals("testGetCallerMethodInt", //$NON-NLS-1$
+    			this.caller.innerinnerTestGetCallerMethod(2));
+	}
+	
+	/**
+	 * @author StephanStephanStephane GALLAND
+	 * @version $Name$ $Revision$ $Date$
+	 * @mavengroupid org.arakhne.afc
+	 * @mavenartifactid arakhneVmutils
+	 */
+	private class InnerCallerTest {
+
+		/**
+		 */
+		public InnerCallerTest() {
+			//
+		}
+		
+		public String innerinnerTestGetCallerMethod() {
+			return innerTestGetCallerMethod();
+		}
+
+		public Class<?> innerinnerTestGetCallerClass() {
+			return innerTestGetCallerClass();
+		}
+
+		public Class<?> innerinnerTestGetCallerClass(int level) {
+			return innerTestGetCallerClass(level);
+		}
+
+		public String innerinnerTestGetCallerMethod(int level) {
+			return innerTestGetCallerMethod(level);
+		}
+
+	}
+	
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/CallerTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ClasspathUtilTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ClasspathUtilTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ClasspathUtilTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,115 @@
+/* $Id$
+ * 
+ * Copyright (C) 2007-09 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import junit.framework.TestCase;
+
+/**
+ * @author $Author: galland$
+ * @version $Name$ $Revision$ $Date$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneVmutils
+ */
+public class ClasspathUtilTest extends TestCase {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void tearDown() throws Exception {
+		super.tearDown();
+	}
+
+	/**
+	 */
+	public static void testGetStartClasspath() {
+		Iterator<URL> urls = ClasspathUtil.getStartClasspath();
+		assertNotNull(urls);
+		
+		String[] paths = System.getProperty("java.class.path").split( //$NON-NLS-1$
+				Pattern.quote(File.pathSeparator));
+		
+		for(int i=0; i<paths.length; i++) {
+			URL u = FileSystem.convertStringToURL(paths[i], true);
+			assertTrue(urls.hasNext());
+			assertEquals(u, urls.next());
+		}
+	}
+	
+	/**
+	 */
+	public static void testGetCurrentClasspath_standardClassLoader() {
+		Iterator<URL> urls = ClasspathUtil.getClasspath();
+		assertNotNull(urls);
+		
+		String[] paths = System.getProperty("java.class.path").split( //$NON-NLS-1$
+				Pattern.quote(File.pathSeparator));
+		List<String> list = new ArrayList<>(Arrays.asList(paths));
+
+		while (urls.hasNext()) {
+			URL u2 = urls.next();
+			assertUrl(list, u2);
+		}
+	}
+	
+	private static void assertUrl(List<String> expected, URL actual) {
+		assertNotNull("An url cannot be null", actual); //$NON-NLS-1$
+		Iterator<String> iterator = expected.iterator();
+		String u;
+		if (iterator.hasNext()) {
+			while (iterator.hasNext()) {
+				u = iterator.next();
+				URL url = FileSystem.convertStringToURL(u, true);
+				if (isEquals(url, actual)) {
+					iterator.remove();
+					return;
+				}
+			}
+		}
+		
+		System.out.println("Additional class path: "+actual); //$NON-NLS-1$
+	}
+		
+	private static boolean isEquals(URL expected, URL actual) {
+		String u1 = expected==null ? null : expected.toExternalForm().replaceFirst("/$", ""); //$NON-NLS-1$ //$NON-NLS-2$
+		String u2 = actual==null ? null : actual.toExternalForm().replaceFirst("/$", ""); //$NON-NLS-1$ //$NON-NLS-2$
+		if (u1==u2) return true;
+		if (u1==null || u2==null) return false;
+		return u1.equals(u2);
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ClasspathUtilTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/FileSystemTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/FileSystemTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/FileSystemTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,1656 @@
+/* $Id$
+ * 
+ * Copyright (C) 2007-09 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/**
+ * @author $Author: galland$
+ * @version $Name$ $Revision$ $Date$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneVmutils
+ */
+public class FileSystemTest extends TestCase {
+
+	private static final File f1 = new File("/home/test.x.z.z"); //$NON-NLS-1$
+	private static final File f2 = new File("/home"); //$NON-NLS-1$
+	private static final File pf1 = f1.getParentFile();
+	private static final File pf2 = f2.getParentFile();
+	private static final URL u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u13, u14, u15;
+	private static final URL pu1, pu2, pu3, pu7, pu13;
+	private static final String TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z.z?toto#frag";; //$NON-NLS-1$
+	private static final String JOIN_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z.z/home/test.x.z.z?toto#frag";; //$NON-NLS-1$
+	private static final String PARENT_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/";; //$NON-NLS-1$
+	private static final String WOEXT_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z?toto#frag";; //$NON-NLS-1$
+	private static final String REPEXT_TEST_URL1 = "http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z.toto?toto#frag";; //$NON-NLS-1$
+	private static final String TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z.z"; //$NON-NLS-1$
+	private static final String PARENT_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/"; //$NON-NLS-1$
+	private static final String JOIN_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z.z/home/test.x.z.z"; //$NON-NLS-1$
+	private static final String WOEXT_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z"; //$NON-NLS-1$
+	private static final String REPEXT_TEST_URL2 = "jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z.toto"; //$NON-NLS-1$
+	private static final String JARPART_TEST_URL2 = "file:/home/test/j.jar"; //$NON-NLS-1$
+	private static final File f3 = new File("/home/test/j.jar"); //$NON-NLS-1$
+	private static final File f4 = new File("/org/arakhne/vmutil/file.x.z.z"); //$NON-NLS-1$
+	private static final String TEST_URL3 = "jar:jar:http://www.arakhne.org/j.jar!/inner/myjar.jar!/org/arakhne/vmutil/file.x.z.z";; //$NON-NLS-1$
+	private static final String PARENT_TEST_URL3 = "jar:jar:http://www.arakhne.org/j.jar!/inner/myjar.jar!/org/arakhne/vmutil/";; //$NON-NLS-1$
+	private static final String JARPART_TEST_URL3 = "jar:http://www.arakhne.org/j.jar!/inner/myjar.jar";; //$NON-NLS-1$
+	private static final String JOIN_TEST_URL3 = "jar:jar:http://www.arakhne.org/j.jar!/inner/myjar.jar!/org/arakhne/vmutil/file.x.z.z/home/test.x.z.z";; //$NON-NLS-1$
+
+	private static final String STRING_WITH_SPACE = "/the path/to/file with space.toto"; //$NON-NLS-1$
+	private static final URL URL_WITH_SPACE;
+	
+	static {
+		try {
+			u1 = f1.toURI().toURL();
+			u2 = f2.toURI().toURL();
+			u3 = new URL(TEST_URL1);
+			u4 = new URL(JOIN_TEST_URL1);
+			u5 = new URL(WOEXT_TEST_URL1);
+			u6 = new URL(REPEXT_TEST_URL1);
+			u7 = new URL(TEST_URL2);
+			u8 = new URL(JOIN_TEST_URL2);
+			u9 = new URL(WOEXT_TEST_URL2);
+			u10 = new URL(REPEXT_TEST_URL2);
+			u11 = new URL(JARPART_TEST_URL2);
+			u13 = new URL(TEST_URL3);
+			u14 = new URL(JARPART_TEST_URL3);
+			u15 = new URL(JOIN_TEST_URL3);
+			pu1 = pf1.toURI().toURL();
+			pu2 = pf2.toURI().toURL();
+			pu3 = new URL(PARENT_TEST_URL1);
+			pu7 = new URL(PARENT_TEST_URL2);
+			pu13 = new URL(PARENT_TEST_URL3);
+			URL_WITH_SPACE = new File(STRING_WITH_SPACE).toURI().toURL();
+		}
+		catch(Throwable e) {
+			throw new AssertionFailedError(e.getLocalizedMessage());
+		}
+	}
+
+	private boolean oldLibraryLoaderState;
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		// Disable native library loading during unit tests
+		this.oldLibraryLoaderState = LibraryLoader.isEnable();
+		LibraryLoader.setEnable(false);
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void tearDown() throws Exception {
+		// Restore library loading state
+		LibraryLoader.setEnable(this.oldLibraryLoaderState);
+		super.tearDown();
+	}
+	
+	/**
+	 */
+	public static void testIsWindowNativeFilename() {
+		assertFalse(FileSystem.isWindowsNativeFilename("D:/vivus_test/export dae/yup/terrain_physx.dae")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("D:\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("/vivus_test/export dae/yup/terrain_physx.dae")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("/")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("\\\\")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("\\\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("\\\\\\\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$
+
+		assertTrue(FileSystem.isWindowsNativeFilename("file:C:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file://C:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file:C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file://C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file://\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file:a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file://a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file:\\\\host\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file://\\\\host\\a\\b\\c.txt")); //$NON-NLS-1$
+
+		assertTrue(FileSystem.isWindowsNativeFilename("C:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file://C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("a\\b\\c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("\\\\host\\a\\b\\c.txt")); //$NON-NLS-1$
+
+		assertFalse(FileSystem.isWindowsNativeFilename("file:C:/a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file://C:/a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file:C:a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file://C:a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file:/a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file:///a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file:a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file://a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file://host/a/b/c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file:////host/a/b/c.txt")); //$NON-NLS-1$
+
+		assertTrue(FileSystem.isWindowsNativeFilename("C:c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file:C:c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file:c.txt")); //$NON-NLS-1$
+		assertTrue(FileSystem.isWindowsNativeFilename("file://C:c.txt")); //$NON-NLS-1$
+		assertFalse(FileSystem.isWindowsNativeFilename("file://c.txt")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static void testNormalizeWindowNativeFilename() {
+		assertEquals(new File("C:/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file:C:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("C:/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file://C:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("C:a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file:C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("C:a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file://C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file://\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file:a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file://a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("//host/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file:\\\\host\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("//host/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file://\\\\host\\a\\b\\c.txt")); //$NON-NLS-1$
+
+		assertEquals(new File("C:/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("C:\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("C:a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("C:a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file://C:a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("\\a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("a\\b\\c.txt")); //$NON-NLS-1$
+		assertEquals(new File("//host/a/b/c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("\\\\host\\a\\b\\c.txt")); //$NON-NLS-1$
+
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file:C:/a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file://C:/a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file:C:a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file://C:a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file:/a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file:///a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file:a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file://a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file://host/a/b/c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file:////host/a/b/c.txt")); //$NON-NLS-1$
+
+		assertEquals(new File("C:c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("C:c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("c.txt")); //$NON-NLS-1$
+		assertEquals(new File("C:c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file:C:c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file:c.txt")); //$NON-NLS-1$
+		assertEquals(new File("C:c.txt"), //$NON-NLS-1$
+				FileSystem.normalizeWindowsNativeFilename("file://C:c.txt")); //$NON-NLS-1$
+		assertNull(FileSystem.normalizeWindowsNativeFilename("file://c.txt")); //$NON-NLS-1$
+	}
+	
+	/**
+	 * @throws Exception
+	 */
+	public static void testIsJarURLURL() throws Exception {
+		assertFalse(FileSystem.isJarURL(u1));
+		assertFalse(FileSystem.isJarURL(u2));
+		assertFalse(FileSystem.isJarURL(u3));
+		assertTrue(FileSystem.isJarURL(u7));
+		assertTrue(FileSystem.isJarURL(u13));
+
+		assertFalse(FileSystem.isJarURL(new URL("file:"+STRING_WITH_SPACE)));  //$NON-NLS-1$
+		assertFalse(FileSystem.isJarURL(URL_WITH_SPACE));
+	}
+	
+	/**
+	 * @throws Exception
+	 */
+	public static void testGetJarURLURL() throws Exception {
+		assertNull(FileSystem.getJarURL(u1));
+		assertNull(FileSystem.getJarURL(u2));
+		assertNull(FileSystem.getJarURL(u3));
+		assertEquals(u11, FileSystem.getJarURL(u7));
+		assertEquals(u14, FileSystem.getJarURL(u13));
+
+		assertEquals(new URL("file:"+STRING_WITH_SPACE),  //$NON-NLS-1$
+				FileSystem.getJarURL(new URL("jar:file:"+STRING_WITH_SPACE+"!/titi")));  //$NON-NLS-1$//$NON-NLS-2$
+		assertNull(FileSystem.getJarFile(URL_WITH_SPACE));
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testGetJarFileURL() throws Exception {
+		assertNull(FileSystem.getJarFile(u1));
+		assertNull(FileSystem.getJarFile(u2));
+		assertNull(FileSystem.getJarFile(u3));
+		assertEquals(f4, FileSystem.getJarFile(u7));
+		assertEquals(f4, FileSystem.getJarFile(u13));
+
+		assertEquals(new File("/titi"),  //$NON-NLS-1$
+				FileSystem.getJarFile(new URL("jar:file:"+STRING_WITH_SPACE+"!/titi")));  //$NON-NLS-1$//$NON-NLS-2$
+		assertNull(FileSystem.getJarFile(URL_WITH_SPACE));
+	}
+
+	/**
+	 * @throws MalformedURLException
+	 */
+	public static void testToJarURLFileFile() throws MalformedURLException {
+		assertEquals(u7, FileSystem.toJarURL(f3, f4));
+	}
+
+	/**
+	 * @throws MalformedURLException
+	 */
+	public static void testToJarURLFileString() throws MalformedURLException {
+		assertEquals(u7, FileSystem.toJarURL(f3, f4.getPath()));
+	}
+
+	/**
+	 * @throws MalformedURLException
+	 */
+	public static void testToJarURLURLFile() throws MalformedURLException {
+		assertEquals(u7, FileSystem.toJarURL(u11, f4));
+	}
+
+	/**
+	 * @throws MalformedURLException
+	 */
+	public static void testToJarURLURLString() throws MalformedURLException {
+		assertEquals(u7, FileSystem.toJarURL(u11, f4.getPath()));
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testDirnameFile() throws Exception {
+		assertEquals(new URL("file", "", "/home"),  //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+				FileSystem.dirname(f1));
+		assertEquals(new URL("file", "", "/"),  //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+				FileSystem.dirname(f2));
+		assertNull(FileSystem.dirname(new File("/"))); //$NON-NLS-1$
+
+		assertEquals(new URL("file:/the path/to"),  //$NON-NLS-1$
+				FileSystem.dirname(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 * @throws MalformedURLException 
+	 */
+	public static void testDirnameURL() throws MalformedURLException {
+		assertEquals(new URL("file", "", "."), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.dirname(new URL("file", "", "marbre.jpg"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertEquals(new URL("http", "www.arakhne.org", "."), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.dirname(new URL("http", "www.arakhne.org", "marbre.jpg"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertEquals(pu1, FileSystem.dirname(u1));
+		assertEquals(pu2, FileSystem.dirname(u2));
+		assertEquals(pu3, FileSystem.dirname(u3));
+		assertEquals(pu7, FileSystem.dirname(u7));
+		assertEquals(pu13, FileSystem.dirname(u13));
+		assertEquals(new URL("file", "", "/"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.dirname(new URL("file:///a/"))); //$NON-NLS-1$
+		assertNull(FileSystem.dirname(new URL("file://"))); //$NON-NLS-1$
+		
+		assertEquals(new URL("file", "", "/a/b%20c/"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.dirname(new File("/a/b c/d.txt").toURI().toURL())); //$NON-NLS-1$
+
+		assertEquals(new URL("file:/the%20path/to/"),  //$NON-NLS-1$
+				FileSystem.dirname(new URL("file:"+STRING_WITH_SPACE))); //$NON-NLS-1$
+		assertEquals(new URL("file:/the%20path/to/"),  //$NON-NLS-1$
+				FileSystem.dirname(URL_WITH_SPACE));
+	}
+
+	/**
+	 */
+	public static void testLargeBasenameString() {
+		assertEquals("test.x.z.z", FileSystem.largeBasename(f1.getAbsolutePath())); //$NON-NLS-1$
+		assertEquals("home", FileSystem.largeBasename(f2.getAbsolutePath())); //$NON-NLS-1$
+		assertEquals("a.b.c", FileSystem.largeBasename("file:///a.b.c/")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("file:", FileSystem.largeBasename("file://")); //$NON-NLS-1$ //$NON-NLS-2$
+
+		try {
+			assertEquals("terrain_physx.dae", FileSystem.largeBasename("D:\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$ //$NON-NLS-2$
+			fail("expecting assertion failure"); //$NON-NLS-1$
+		}
+		catch(AssertionError _) {
+			//
+		}
+		try {
+			assertEquals("terrain_physx.dae", FileSystem.largeBasename("file:D:\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$ //$NON-NLS-2$
+			fail("expecting assertion failure"); //$NON-NLS-1$
+		}
+		catch(AssertionError _) {
+			//
+		}
+
+		assertEquals("file with space.toto",  //$NON-NLS-1$
+				FileSystem.largeBasename(STRING_WITH_SPACE));
+	}
+
+	/**
+	 */
+	public static void testLargeBasenameFile() {
+		assertEquals("test.x.z.z", FileSystem.largeBasename(f1)); //$NON-NLS-1$
+		assertEquals("home", FileSystem.largeBasename(f2)); //$NON-NLS-1$
+		assertEquals("a.b.c", FileSystem.largeBasename(new File("/a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.largeBasename(new File("/"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+		assertEquals("file with space.toto",  //$NON-NLS-1$
+				FileSystem.largeBasename(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 * @throws MalformedURLException 
+	 */
+	public static void testLargeBasenameURL() throws MalformedURLException {
+		assertEquals("test.x.z.z", FileSystem.largeBasename(u1)); //$NON-NLS-1$
+		assertEquals("home", FileSystem.largeBasename(u2)); //$NON-NLS-1$
+		assertEquals("file.x.z.z", FileSystem.largeBasename(u3)); //$NON-NLS-1$
+		assertEquals("file.x.z.z", FileSystem.largeBasename(u7)); //$NON-NLS-1$
+		assertEquals("a.b.c", FileSystem.largeBasename(new URL("file:///a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.largeBasename(new URL("file://"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+		URL url = new URL("file", "", "D:\\vivus_test\\export dae\\yup\\terrain_physx.dae"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		try {
+			assertEquals("terrain_physx.dae", FileSystem.largeBasename(url)); //$NON-NLS-1$
+			fail("expecting assertion failure"); //$NON-NLS-1$
+		}
+		catch(AssertionError _) {
+			//
+		}
+
+		assertEquals("file with space.toto",  //$NON-NLS-1$
+				FileSystem.largeBasename(new URL("file:"+STRING_WITH_SPACE))); //$NON-NLS-1$
+		assertEquals("file with space.toto",  //$NON-NLS-1$
+				FileSystem.largeBasename(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 */
+	public static void testBasenameString() {
+		assertEquals("test.x.z", FileSystem.basename(f1.getAbsolutePath())); //$NON-NLS-1$
+		assertEquals("home", FileSystem.basename(f2.getAbsolutePath())); //$NON-NLS-1$
+		assertEquals("a.b", FileSystem.basename("/a.b.c/")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.basename("")); //$NON-NLS-1$ //$NON-NLS-2$
+
+		try {
+			assertEquals("terrain_physx", FileSystem.basename("D:\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$ //$NON-NLS-2$
+			fail("expecting assertion failure"); //$NON-NLS-1$
+		}
+		catch(AssertionError _) {
+			//
+		}
+		try {
+			assertEquals("terrain_physx", FileSystem.basename("file:D:\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$ //$NON-NLS-2$
+			fail("expecting assertion failure"); //$NON-NLS-1$
+		}
+		catch(AssertionError _) {
+			//
+		}
+
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.basename(STRING_WITH_SPACE));
+	}
+
+	/**
+	 */
+	public static void testBasenameFile() {
+		assertEquals("test.x.z", FileSystem.basename(f1)); //$NON-NLS-1$
+		assertEquals("home", FileSystem.basename(f2)); //$NON-NLS-1$
+		assertEquals("a.b", FileSystem.basename(new File("/a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.basename(new File("/"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.basename(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 * @throws MalformedURLException 
+	 */
+	public static void testBasenameURL() throws MalformedURLException {
+		assertEquals("test.x.z", FileSystem.basename(u1)); //$NON-NLS-1$
+		assertEquals("home", FileSystem.basename(u2)); //$NON-NLS-1$
+		assertEquals("file.x.z", FileSystem.basename(u3)); //$NON-NLS-1$
+		assertEquals("file.x.z", FileSystem.basename(u7)); //$NON-NLS-1$
+		assertEquals("a.b", FileSystem.basename(new URL("file:///a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.basename(new URL("file://"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+		URL url = new URL("file", "", "D:\\vivus_test\\export dae\\yup\\terrain_physx.dae"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		try {
+			assertEquals("terrain_physx", FileSystem.basename(url)); //$NON-NLS-1$
+			fail("expecting assertion failure"); //$NON-NLS-1$
+		}
+		catch(AssertionError _) {
+			//
+		}
+
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.basename(new URL("file:"+STRING_WITH_SPACE))); //$NON-NLS-1$
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.basename(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 */
+	public static void testShortBasenameString() {
+		assertEquals("test", FileSystem.shortBasename(f1.getAbsolutePath())); //$NON-NLS-1$
+		assertEquals("home", FileSystem.shortBasename(f2.getAbsolutePath())); //$NON-NLS-1$
+		assertEquals("a", FileSystem.shortBasename("/a.b.c/")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.shortBasename("")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("terrain_physx", FileSystem.shortBasename("D:\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("terrain_physx", FileSystem.shortBasename("file:D:\\vivus_test\\export dae\\yup\\terrain_physx.dae")); //$NON-NLS-1$ //$NON-NLS-2$
+
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.shortBasename(STRING_WITH_SPACE));
+	}
+
+	/**
+	 */
+	public static void testShortBasenameFile() {
+		assertEquals("test", FileSystem.shortBasename(f1)); //$NON-NLS-1$
+		assertEquals("home", FileSystem.shortBasename(f2)); //$NON-NLS-1$
+		assertEquals("a", FileSystem.shortBasename(new File("/a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.shortBasename(new File("/"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.shortBasename(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 * @throws MalformedURLException 
+	 */
+	public static void testShortBasenameURL() throws MalformedURLException {
+		assertEquals("test", FileSystem.shortBasename(u1)); //$NON-NLS-1$
+		assertEquals("home", FileSystem.shortBasename(u2)); //$NON-NLS-1$
+		assertEquals("file", FileSystem.shortBasename(u3)); //$NON-NLS-1$
+		assertEquals("file", FileSystem.shortBasename(u7)); //$NON-NLS-1$
+		assertEquals("a", FileSystem.shortBasename(new URL("file:///a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.shortBasename(new URL("file://"))); //$NON-NLS-1$ //$NON-NLS-2$
+		
+		URL url = new URL("file", "", "D:\\vivus_test\\export dae\\yup\\terrain_physx.dae"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		try {
+			assertEquals("terrain_physx", FileSystem.shortBasename(url)); //$NON-NLS-1$
+			fail("expecting assertion failure"); //$NON-NLS-1$
+		}
+		catch(AssertionError _) {
+			//
+		}
+
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.shortBasename(new URL("file:"+STRING_WITH_SPACE))); //$NON-NLS-1$
+		assertEquals("file with space",  //$NON-NLS-1$
+				FileSystem.shortBasename(URL_WITH_SPACE));
+	}
+
+	/**
+	 */
+	public static void testExtensionFile() {
+		assertEquals(".z", FileSystem.extension(f1)); //$NON-NLS-1$
+		assertEquals("", FileSystem.extension(f2)); //$NON-NLS-1$
+		assertEquals(".c", FileSystem.extension(new File("/a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.extension(new File("/"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+		assertEquals(".toto",  //$NON-NLS-1$
+				FileSystem.extension(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 * @throws MalformedURLException 
+	 */
+	public static void testExtensionURL() throws MalformedURLException {
+		assertEquals(".z", FileSystem.extension(u1)); //$NON-NLS-1$
+		assertEquals("", FileSystem.extension(u2)); //$NON-NLS-1$
+		assertEquals(".z", FileSystem.extension(u3)); //$NON-NLS-1$
+		assertEquals(".z", FileSystem.extension(u7)); //$NON-NLS-1$
+		assertEquals(".z", FileSystem.extension(u13)); //$NON-NLS-1$
+		assertEquals(".c", FileSystem.extension(new URL("file:///a.b.c/"))); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("", FileSystem.extension(new URL("file://"))); //$NON-NLS-1$ //$NON-NLS-2$
+
+		assertEquals(".toto",  //$NON-NLS-1$
+				FileSystem.extension(new URL("file:"+STRING_WITH_SPACE))); //$NON-NLS-1$
+		assertEquals(".toto",  //$NON-NLS-1$
+				FileSystem.extension(URL_WITH_SPACE));
+	}
+
+	/**
+	 */
+	public static void testExtensionsFile() {
+		assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(f1))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(Arrays.equals(new String[0], FileSystem.extensions(f2)));
+		assertTrue(Arrays.equals(new String[]{"b","c"}, FileSystem.extensions(new File("/a.b.c/")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(Arrays.equals(new String[0], FileSystem.extensions(new File("/")))); //$NON-NLS-1$
+
+		assertTrue(Arrays.equals(new String[] {"toto"},  //$NON-NLS-1$
+				FileSystem.extensions(new File(STRING_WITH_SPACE))));
+	}
+
+	/**
+	 * @throws MalformedURLException 
+	 */
+	public static void testExtensionsURL() throws MalformedURLException {
+		assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(u1))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(Arrays.equals(new String[0], FileSystem.extensions(u2)));
+		assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(u3))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(Arrays.equals(new String[]{"x","z","z"}, FileSystem.extensions(u7))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(Arrays.equals(new String[]{"b","c"}, FileSystem.extensions(new URL("file:///a.b.c/")))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(Arrays.equals(new String[0], FileSystem.extensions(new URL("file://")))); //$NON-NLS-1$
+
+		assertTrue(Arrays.equals(new String[] {"toto"},  //$NON-NLS-1$
+				FileSystem.extensions(new File(STRING_WITH_SPACE))));
+	}
+
+	/**
+	 */
+	public static void testSplitFile() {
+		assertTrue(Arrays.equals(
+				new String[] {
+					"", //$NON-NLS-1$
+					"home", //$NON-NLS-1$
+					"test.x.z.z", //$NON-NLS-1$
+				},
+				FileSystem.split(f1)));
+		assertTrue(Arrays.equals(
+				new String[] {
+					"", //$NON-NLS-1$
+					"home", //$NON-NLS-1$
+				},
+				FileSystem.split(f2)));
+
+		assertTrue(Arrays.equals(
+				new String[] {
+							"", //$NON-NLS-1$
+							"the path", //$NON-NLS-1$
+							"to", //$NON-NLS-1$
+							"file with space.toto" //$NON-NLS-1$
+				},
+				FileSystem.split(new File(STRING_WITH_SPACE))));
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testSplitURL() throws Exception {
+		String[] tab;
+		
+		tab = FileSystem.split(u1);
+		assertTrue(Arrays.equals(
+				new String[] {
+					"", //$NON-NLS-1$
+					"home", //$NON-NLS-1$
+					"test.x.z.z", //$NON-NLS-1$
+				},
+				tab));
+		
+		tab = FileSystem.split(u2);
+		assertTrue(Arrays.equals(
+				new String[] {
+					"", //$NON-NLS-1$
+					"home", //$NON-NLS-1$
+				},
+				tab));
+		
+		tab = FileSystem.split(u7);
+		assertTrue(Arrays.equals(
+				new String[] {
+					"", //$NON-NLS-1$
+					"org", //$NON-NLS-1$
+					"arakhne", //$NON-NLS-1$
+					"vmutil", //$NON-NLS-1$
+					"file.x.z.z", //$NON-NLS-1$
+				},
+				tab));
+		
+		tab = FileSystem.split(u13);
+		assertTrue(Arrays.equals(
+				new String[] {
+					"", //$NON-NLS-1$
+					"org", //$NON-NLS-1$
+					"arakhne", //$NON-NLS-1$
+					"vmutil", //$NON-NLS-1$
+					"file.x.z.z", //$NON-NLS-1$
+				},
+				tab));
+
+		assertTrue(Arrays.equals(
+				new String[] {
+							"", //$NON-NLS-1$
+							"the path", //$NON-NLS-1$
+							"to", //$NON-NLS-1$
+							"file with space.toto" //$NON-NLS-1$
+				},
+				FileSystem.split(new URL("file:"+STRING_WITH_SPACE)))); //$NON-NLS-1$
+		assertTrue(Arrays.equals(
+				new String[] {
+							"", //$NON-NLS-1$
+							"the path", //$NON-NLS-1$
+							"to", //$NON-NLS-1$
+							"file with space.toto" //$NON-NLS-1$
+				},
+				FileSystem.split(URL_WITH_SPACE)));
+	}
+
+	/**
+	 */
+	public static void testJoinFileStringArray() {
+		assertEquals(new File(new File(f1, "home"), "test.x.z.z"), //$NON-NLS-1$ //$NON-NLS-2$
+				FileSystem.join(f1,
+				"", //$NON-NLS-1$
+				"home", //$NON-NLS-1$
+				"test.x.z.z")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static void testJoinFileFileArray() {
+		assertEquals(new File(new File(f1, "home"), "test.x.z.z"), //$NON-NLS-1$ //$NON-NLS-2$
+				FileSystem.join(f1,
+				new File("home"), //$NON-NLS-1$
+				new File("test.x.z.z"))); //$NON-NLS-1$
+		assertEquals(new File(new File(f1, "home"), "test.x.z.z"), //$NON-NLS-1$ //$NON-NLS-2$
+				FileSystem.join(f1,
+				new File(File.separator+"home"), //$NON-NLS-1$
+				new File("test.x.z.z"))); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testJoinURLStringArray() throws Exception {
+		assertEquals(new File(new File(f1, "home"), "test.x.z.z").toURI().toURL(), //$NON-NLS-1$ //$NON-NLS-2$
+				FileSystem.join(u1,
+				"", //$NON-NLS-1$
+				"home", //$NON-NLS-1$
+				"test.x.z.z")); //$NON-NLS-1$
+
+		assertEquals(u4,
+				FileSystem.join(u3,
+				"", //$NON-NLS-1$
+				"home", //$NON-NLS-1$
+				"test.x.z.z")); //$NON-NLS-1$
+
+		assertEquals(u8,
+				FileSystem.join(u7,
+				"", //$NON-NLS-1$
+				"home", //$NON-NLS-1$
+				"test.x.z.z")); //$NON-NLS-1$
+
+		assertEquals(u15,
+				FileSystem.join(u13,
+				"", //$NON-NLS-1$
+				"home", //$NON-NLS-1$
+				"test.x.z.z")); //$NON-NLS-1$
+
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto/a/b"),  //$NON-NLS-1$
+				FileSystem.join(new URL("file:"+STRING_WITH_SPACE), "a", "b"));  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto/a/b"),  //$NON-NLS-1$
+				FileSystem.join(URL_WITH_SPACE, "a", "b")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testJoinURLFileArray() throws Exception {
+		assertEquals(new File(new File(f1, "home"), "test.x.z.z").toURI().toURL(), //$NON-NLS-1$ //$NON-NLS-2$
+				FileSystem.join(u1,
+				new File("home"), //$NON-NLS-1$
+				new File("test.x.z.z"))); //$NON-NLS-1$
+		assertEquals(new File(new File(f1, "home"), "test.x.z.z").toURI().toURL(), //$NON-NLS-1$ //$NON-NLS-2$
+				FileSystem.join(u1,
+				new File(File.separator+"home"), //$NON-NLS-1$
+				new File("test.x.z.z"))); //$NON-NLS-1$
+		assertEquals(u4,
+				FileSystem.join(u3,
+				new File(File.separator+"home"), //$NON-NLS-1$
+				new File("test.x.z.z"))); //$NON-NLS-1$
+		assertEquals(u8,
+				FileSystem.join(u7,
+				new File(File.separator+"home"), //$NON-NLS-1$
+				new File("test.x.z.z"))); //$NON-NLS-1$
+		assertEquals(u15,
+				FileSystem.join(u13,
+				new File(File.separator+"home"), //$NON-NLS-1$
+				new File("test.x.z.z"))); //$NON-NLS-1$
+		
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto/a/b"),  //$NON-NLS-1$
+				FileSystem.join(new URL("file:"+STRING_WITH_SPACE), new File("a"), new File("b"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto/a/b"),  //$NON-NLS-1$
+				FileSystem.join(URL_WITH_SPACE, new File("a"), new File("b"))); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 */
+	public static void testHasExtensionFileString() {
+		assertTrue(FileSystem.hasExtension(f1, ".z")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(f1, "z")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(f1, ".x")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(f1, "")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(f2, "")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(f2, ".z")); //$NON-NLS-1$
+
+		assertTrue(FileSystem.hasExtension(new File(STRING_WITH_SPACE), ".toto"));  //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(new File(STRING_WITH_SPACE), "toto"));  //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(new File(STRING_WITH_SPACE), ".zip"));  //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(new File(STRING_WITH_SPACE), "zip"));  //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testHasExtensionURLString() throws Exception {
+		assertTrue(FileSystem.hasExtension(u1, ".z")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(u1, "z")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(u1, ".x")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(u1, "")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(u2, "")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(u2, ".z")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(u3, ".z")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(u3, "z")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(u3, ".x")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(u3, "")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(u7, ".z")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(u7, "z")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(u7, ".x")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(u7, "")); //$NON-NLS-1$
+
+		assertTrue(FileSystem.hasExtension(new URL("file:"+STRING_WITH_SPACE), ".toto"));  //$NON-NLS-1$ //$NON-NLS-2$
+		assertTrue(FileSystem.hasExtension(new URL("file:"+STRING_WITH_SPACE), "toto"));  //$NON-NLS-1$ //$NON-NLS-2$
+		assertFalse(FileSystem.hasExtension(new URL("file:"+STRING_WITH_SPACE), ".zip"));  //$NON-NLS-1$ //$NON-NLS-2$
+		assertFalse(FileSystem.hasExtension(new URL("file:"+STRING_WITH_SPACE), "zip"));  //$NON-NLS-1$ //$NON-NLS-2$
+		assertTrue(FileSystem.hasExtension(URL_WITH_SPACE, ".toto")); //$NON-NLS-1$
+		assertTrue(FileSystem.hasExtension(URL_WITH_SPACE, "toto")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(URL_WITH_SPACE, ".zip")); //$NON-NLS-1$
+		assertFalse(FileSystem.hasExtension(URL_WITH_SPACE, "zip")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static void testRemoveExtensionFile() {
+		assertEquals(new File("/home/test.x.z"), FileSystem.removeExtension(f1)); //$NON-NLS-1$
+		assertEquals(new File("/home"), FileSystem.removeExtension(f2)); //$NON-NLS-1$
+
+		assertEquals(new File("/the path/to/file with space"),  //$NON-NLS-1$
+				FileSystem.removeExtension(new File(STRING_WITH_SPACE)));
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testRemoveExtensionURL() throws Exception {
+		assertEquals(new File("/home/test.x.z").toURI().toURL(), //$NON-NLS-1$
+				FileSystem.removeExtension(u1));
+		assertEquals(new File("/home").toURI().toURL(), //$NON-NLS-1$ 
+				FileSystem.removeExtension(u2));
+		assertEquals(u5, FileSystem.removeExtension(u3));
+		assertEquals(u9, FileSystem.removeExtension(u7));
+
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space"),  //$NON-NLS-1$
+				FileSystem.removeExtension(new URL("file:"+STRING_WITH_SPACE))); //$NON-NLS-1$
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space"),  //$NON-NLS-1$
+				FileSystem.removeExtension(URL_WITH_SPACE));
+	}
+
+	/**
+	 */
+	public static void testReplaceExtensionFileString() {
+		assertEquals(new File("/home/test.x.z.toto"), FileSystem.replaceExtension(f1, ".toto")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(new File("/home.toto"), FileSystem.replaceExtension(f2, ".toto")); //$NON-NLS-1$ //$NON-NLS-2$
+
+		assertEquals(new File("/the path/to/file with space.zip"),  //$NON-NLS-1$
+				FileSystem.replaceExtension(new File(STRING_WITH_SPACE), ".zip")); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testReplaceExtensionURLString() throws Exception {
+		assertEquals(new File("/home/test.x.z.toto").toURI().toURL(), //$NON-NLS-1$ 
+				FileSystem.replaceExtension(u1, ".toto")); //$NON-NLS-1$
+		assertEquals(new File("/home.toto").toURI().toURL(), //$NON-NLS-1$ 
+				FileSystem.replaceExtension(u2, ".toto")); //$NON-NLS-1$
+		assertEquals(u6, FileSystem.replaceExtension(u3, ".toto")); //$NON-NLS-1$
+		assertEquals(u10, FileSystem.replaceExtension(u7, ".toto")); //$NON-NLS-1$
+
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.zip"),  //$NON-NLS-1$
+				FileSystem.replaceExtension(new URL("file:"+STRING_WITH_SPACE), ".zip")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.zip"),  //$NON-NLS-1$
+				FileSystem.replaceExtension(URL_WITH_SPACE, ".zip")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static void testAddExtensionFileString() {
+		assertEquals(new File("/home/test.x.z.z"), FileSystem.addExtension(f1, ".z")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(new File("/home/test.x.z.z.toto"), FileSystem.addExtension(f1, ".toto")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(new File("/home.toto"), FileSystem.addExtension(f2, ".toto")); //$NON-NLS-1$ //$NON-NLS-2$
+		
+		assertEquals(new File(STRING_WITH_SPACE+".zip"), //$NON-NLS-1$
+				FileSystem.addExtension(new File(STRING_WITH_SPACE), "zip")); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testAddExtensionURLString() throws Exception {
+		assertEquals(new File("/home/test.x.z.z").toURI().toURL(), //$NON-NLS-1$ 
+				FileSystem.addExtension(u1, ".z")); //$NON-NLS-1$
+		assertEquals(new File("/home/test.x.z.z.toto").toURI().toURL(), //$NON-NLS-1$ 
+				FileSystem.addExtension(u1, ".toto")); //$NON-NLS-1$
+		assertEquals(new File("/home.toto").toURI().toURL(), //$NON-NLS-1$ 
+				FileSystem.addExtension(u2, ".toto")); //$NON-NLS-1$
+		
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto.zip"), //$NON-NLS-1$
+				FileSystem.addExtension(new URL("file:"+STRING_WITH_SPACE), ".zip")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testConvertStringToUrl() throws Exception {
+		URL rr;
+
+		// The following test permits to check if a specifical behaviour of URL
+		// is still present in the JRE.
+		rr = new URL("file://marbre.jpg"); //$NON-NLS-1$
+		assertEquals("file", rr.getProtocol()); //$NON-NLS-1$
+		assertEquals("marbre.jpg", rr.getAuthority()); //$NON-NLS-1$
+		assertEquals("", rr.getPath()); //$NON-NLS-1$
+		//-----
+		
+		assertNull(FileSystem.convertStringToURL(null, true));
+		assertNull(FileSystem.convertStringToURL("", true)); //$NON-NLS-1$
+		assertNull(FileSystem.convertStringToURL(null, false));
+		assertNull(FileSystem.convertStringToURL("", false)); //$NON-NLS-1$
+
+		rr = FileSystem.convertStringToURL("file://marbre.jpg", false); //$NON-NLS-1$
+		assertNotNull(rr);
+		assertEquals("file", rr.getProtocol()); //$NON-NLS-1$
+		assertEquals("", rr.getAuthority()); //$NON-NLS-1$s
+		assertEquals("", rr.getHost()); //$NON-NLS-1$
+		assertNull(rr.getQuery());
+		assertEquals("marbre.jpg", rr.getPath()); //$NON-NLS-1$
+
+		assertEquals(new URL("http", "www.arakhne.org", "/"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					 FileSystem.convertStringToURL("http://www.arakhne.org/";, true)); //$NON-NLS-1$
+		assertEquals(new URL("http", "www.arakhne.org", "/"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				 FileSystem.convertStringToURL("http://www.arakhne.org/";, false)); //$NON-NLS-1$
+
+		assertEquals(new URL("file", "", f1.getAbsolutePath()), //$NON-NLS-1$ //$NON-NLS-2$
+				 FileSystem.convertStringToURL("file:"+f1.getAbsolutePath(), true)); //$NON-NLS-1$
+		assertEquals(new URL("file", "", f1.getAbsolutePath()), //$NON-NLS-1$ //$NON-NLS-2$
+			 FileSystem.convertStringToURL("file:"+f1.getAbsolutePath(), false)); //$NON-NLS-1$
+		assertEquals(new URL("file", "", "./toto"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				 FileSystem.convertStringToURL("file:./toto", false)); //$NON-NLS-1$
+
+		// CAUTION: testing right-formed jar URL.
+		assertEquals(new URL("jar", "", "file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.convertStringToURL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", true)); //$NON-NLS-1$
+		assertEquals(new URL("jar", "", "file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.convertStringToURL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", false)); //$NON-NLS-1$
+
+		// CAUTION: testing malformed jar URL. Right syntax is: jar:{url}!/{entry}
+		assertEquals(new URL("file", "", "/home/test/j.jar"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.convertStringToURL("jar:/home/test/j.jar", true)); //$NON-NLS-1$
+		assertEquals(new URL("file", "", "/home/test/j.jar"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.convertStringToURL("jar:/home/test/j.jar", false)); //$NON-NLS-1$
+
+		// CAUTION: testing malformed jar URL. Right syntax is: jar:{url}!/{entry}
+		assertEquals(new URL("jar", "", "file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.convertStringToURL("jar:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", true)); //$NON-NLS-1$
+		assertEquals(new URL("jar", "", "file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				FileSystem.convertStringToURL("jar:/home/test/j.jar!/org/arakhne/vmutil/ff.properties", false)); //$NON-NLS-1$
+		
+		URL testResource = Resources.getResource("/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+		assertNotNull(testResource);
+		URL testResourceFileRel = new URL("file","", "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		URL testResourceFileAbs = new File("/org/arakhne/vmutil/test.txt").toURI().toURL(); //$NON-NLS-1$
+		
+		assertEquals(testResource,
+				 FileSystem.convertStringToURL("resource:/org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+		assertEquals(null,
+				 FileSystem.convertStringToURL("resource:/org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+
+		assertEquals(testResource,
+				 FileSystem.convertStringToURL("resource:org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+		assertEquals(null,
+				 FileSystem.convertStringToURL("resource:org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+
+		assertEquals(testResource,
+				 FileSystem.convertStringToURL("/org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+		assertEquals(testResourceFileAbs,
+				 FileSystem.convertStringToURL("/org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+
+		assertEquals(testResource,
+				 FileSystem.convertStringToURL("org/arakhne/vmutil/test.txt", true)); //$NON-NLS-1$
+		assertEquals(testResourceFileRel,
+				 FileSystem.convertStringToURL("org/arakhne/vmutil/test.txt", false)); //$NON-NLS-1$
+
+		assertEquals(new URL("file:"+STRING_WITH_SPACE),  //$NON-NLS-1$
+				FileSystem.convertStringToURL(STRING_WITH_SPACE, false));
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testConvertURLToFile() throws Exception {
+		assertEquals(f1,
+				 FileSystem.convertURLToFile(new URL("file:"+f1.getAbsolutePath()))); //$NON-NLS-1$
+
+		try {
+			FileSystem.convertURLToFile(new URL("http://www.arakhne.org";)); //$NON-NLS-1$
+			fail("not a file URL"); //$NON-NLS-1$
+		}
+		catch(IllegalArgumentException _) {
+			//
+		}
+		
+		assertEquals(new File("toto").getCanonicalPath(), //$NON-NLS-1$
+				 FileSystem.convertURLToFile(new URL("file:./toto")).getCanonicalPath()); //$NON-NLS-1$
+
+		assertEquals(new File("toto").getCanonicalPath(), //$NON-NLS-1$
+				 FileSystem.convertURLToFile(new URL("file:toto")).getCanonicalPath()); //$NON-NLS-1$
+
+		assertEquals(new File("toto").getCanonicalPath(), //$NON-NLS-1$
+				 FileSystem.convertURLToFile(new URL("file:./abs/../toto")).getCanonicalPath()); //$NON-NLS-1$
+
+		assertEquals(new File("/toto").getCanonicalPath(), //$NON-NLS-1$
+				 FileSystem.convertURLToFile(new URL("file:/toto")).getCanonicalPath()); //$NON-NLS-1$
+
+		assertEquals(new File(STRING_WITH_SPACE),
+				FileSystem.convertURLToFile(new URL("file:"+STRING_WITH_SPACE))); //$NON-NLS-1$
+		assertEquals(new File(STRING_WITH_SPACE),
+				FileSystem.convertURLToFile(URL_WITH_SPACE));
+	}
+	
+	/**
+	 */
+	public static void testMakeAbsoluteFileFile() {
+		File root = new File(File.separator+"myroot"); //$NON-NLS-1$
+
+		assertNull(FileSystem.makeAbsolute((File)null, (File)null));
+		assertNull(FileSystem.makeAbsolute((File)null, root));
+
+		assertEquals(new File(File.separator+"toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File(File.separator+"toto"), (File)null)); //$NON-NLS-1$
+		assertEquals(new File("toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("toto"), (File)null)); //$NON-NLS-1$
+
+		assertEquals(new File(File.separator+"toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File(File.separator+"toto"), root)); //$NON-NLS-1$
+		assertEquals(new File(File.separator+"myroot"+File.separator+"toto"), //$NON-NLS-1$ //$NON-NLS-2$
+				FileSystem.makeAbsolute(new File("toto"), root)); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testMakeAbsoluteURLFile() throws Exception {
+		File root = new File(File.separator+"myroot"); //$NON-NLS-1$
+
+		assertNull(FileSystem.makeAbsolute((URL)null, (File)null));
+		assertNull(FileSystem.makeAbsolute((URL)null, root));
+
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:/toto"), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:toto"), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:/toto"), root)); //$NON-NLS-1$
+		assertEquals(new URL("file:/myroot/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:toto"), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("http://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto";), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto";), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("https://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto";), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto";), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("ftp://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto";), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto";), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (File)null)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:/myroot/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testMakeAbsoluteURLURL_withfileroot() throws Exception {
+		URL root = new File(File.separator+"myroot").toURI().toURL(); //$NON-NLS-1$
+
+		assertNull(FileSystem.makeAbsolute((URL)null, (URL)null));
+		assertNull(FileSystem.makeAbsolute((URL)null, root));
+
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:/toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:/toto"), root)); //$NON-NLS-1$
+		assertEquals(new URL("file:/myroot/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:toto"), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("http://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("https://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("ftp://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:/myroot/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+	}
+	
+	/**
+	 * @throws Exception
+	 */
+	public static void testMakeAbsoluteURLURL_withhttproot() throws Exception {
+		URL root = new URL("http://maven.arakhne.org";); //$NON-NLS-1$
+
+		assertNull(FileSystem.makeAbsolute((URL)null, (URL)null));
+		assertNull(FileSystem.makeAbsolute((URL)null, root));
+
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:/toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:/toto"), root)); //$NON-NLS-1$
+		assertEquals(new URL("http://maven.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("file:toto"), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("http://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("http://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("http://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("https://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("https://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("https://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("ftp://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto";), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/toto";), root)); //$NON-NLS-1$
+		assertEquals(new URL("ftp://www.arakhne.org/./toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("ftp://www.arakhne.org/./toto";), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+		assertEquals(new URL("jar:http://maven.arakhne.org/home/test/j.jar!/org/arakhne/vmutil/ff.properties";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new URL("jar:file:home/test/j.jar!/org/arakhne/vmutil/ff.properties"), root)); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testMakeAbsoluteFileURL_withfileroot() throws Exception {
+		URL root = new URL("http://maven.arakhne.org/myroot";); //$NON-NLS-1$
+
+		assertNull(FileSystem.makeAbsolute((File)null, (URL)null));
+		assertNull(FileSystem.makeAbsolute((File)null, root));
+
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("/toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("/toto"), root)); //$NON-NLS-1$
+		assertEquals(new URL("http://maven.arakhne.org/myroot/toto";), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("toto"), root)); //$NON-NLS-1$
+
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto/a/b/c"),  //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("a/b/c"), new URL("file:"+STRING_WITH_SPACE)));  //$NON-NLS-1$//$NON-NLS-2$
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto/a/b/c"),  //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("a/b/c"), URL_WITH_SPACE));  //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testMakeAbsoluteFileURL_withhttproot() throws Exception {
+		URL root = new File(File.separator+"myroot").toURI().toURL(); //$NON-NLS-1$
+
+		assertNull(FileSystem.makeAbsolute((File)null, (URL)null));
+		assertNull(FileSystem.makeAbsolute((File)null, root));
+
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("/toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("toto"), (URL)null)); //$NON-NLS-1$
+		assertEquals(new URL("file:/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("/toto"), root)); //$NON-NLS-1$
+		assertEquals(new URL("file:/myroot/toto"), //$NON-NLS-1$
+				FileSystem.makeAbsolute(new File("toto"), root)); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public static void testGetParentURLURL() throws Exception {
+		assertEquals(
+				new URL("http://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("http://www.arakhne.org";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("http://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("http://www.arakhne.org/";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("http://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("http://www.arakhne.org/toto";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("http://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("http://www.arakhne.org/toto/";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("http://www.arakhne.org/toto/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("http://www.arakhne.org/toto/titi";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("http://www.arakhne.org/toto/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("http://www.arakhne.org/toto/titi/";))); //$NON-NLS-1$
+
+		assertEquals(
+				new URL("https://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("https://www.arakhne.org";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("https://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("https://www.arakhne.org/";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("https://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("https://www.arakhne.org/toto";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("https://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("https://www.arakhne.org/toto/";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("https://www.arakhne.org/toto/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("https://www.arakhne.org/toto/titi";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("https://www.arakhne.org/toto/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("https://www.arakhne.org/toto/titi/";))); //$NON-NLS-1$
+
+		assertEquals(
+				new URL("ftp://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("ftp://www.arakhne.org";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("ftp://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("ftp://www.arakhne.org/";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("ftp://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("ftp://www.arakhne.org/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto/";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("ftp://www.arakhne.org/toto/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto/titi";))); //$NON-NLS-1$
+		assertEquals(
+				new URL("ftp://www.arakhne.org/toto/";), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("ftp://www.arakhne.org/toto/titi/";))); //$NON-NLS-1$
+
+		assertEquals(
+				new URL("file:/toto/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:/toto/titi"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:/toto/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:/toto/titi/"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:/toto"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:/toto/"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:./toto/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:./toto/titi"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:./toto/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:./toto/titi/"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:./"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:./toto"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:./"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:./toto/"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:../"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:."))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:../"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:./"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:../"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:toto"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("file:../"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:toto/"))); //$NON-NLS-1$
+
+		assertEquals(
+				new URL("jar:file:test.jar!/toto/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("jar:file:test.jar!/toto/titi"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("jar:file:test.jar!/toto/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("jar:file:test.jar!/toto/titi/"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("jar:file:test.jar!/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("jar:file:test.jar!/toto"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("jar:file:test.jar!/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("jar:file:test.jar!/toto/"))); //$NON-NLS-1$
+		assertEquals(
+				new URL("jar:file:test.jar!/"), //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("jar:file:test.jar!/"))); //$NON-NLS-1$
+
+		assertEquals(new URL("file:/the path/to/"),  //$NON-NLS-1$
+				FileSystem.getParentURL(new URL("file:"+STRING_WITH_SPACE)));  //$NON-NLS-1$
+		assertEquals(new URL("file:/the%20path/to/"),  //$NON-NLS-1$
+				FileSystem.getParentURL(URL_WITH_SPACE));
+	}
+	
+	/**
+	 * @throws Exception
+	 */
+	public static void testConvertFileToURLFile() throws Exception {
+		URLHandlerUtil.installArakhneHandlers();
+		try {
+			File f1 = new File("/toto"); //$NON-NLS-1$
+			URL u1 = f1.toURI().toURL();
+			URL u2 = Resources.getResource("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+			URL u2e = new URL("resource:org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+			File f2 = FileSystem.convertURLToFile(u2);
+			
+			URL actual;
+			
+			actual = FileSystem.convertFileToURL(f1);
+			assertEqualUrls(u1, actual);
+
+			actual = FileSystem.convertFileToURL(f2);
+			assertEqualUrls(u2e, actual);
+		}
+		finally {
+			URLHandlerUtil.uninstallArakhneHandlers();
+		}
+
+		assertEquals(new URL("file:/the%20path/to/file%20with%20space.toto"),  //$NON-NLS-1$
+				FileSystem.convertFileToURL(new File(STRING_WITH_SPACE)));
+	}
+	
+	/**
+	 * @throws Exception
+	 */
+	public static void testToShortestURLURL() throws Exception {
+		URLHandlerUtil.installArakhneHandlers();
+		try {
+			File f1 = new File("/toto"); //$NON-NLS-1$
+			URL u1 = f1.toURI().toURL();
+			URL u2 = Resources.getResource("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+			URL u2e = new URL("resource:org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+			
+			URL actual;
+			
+			actual = FileSystem.toShortestURL(u1);
+			assertEqualUrls(u1, actual);
+
+			actual = FileSystem.toShortestURL(u2);
+			assertEqualUrls(u2e, actual);
+		}
+		finally {
+			URLHandlerUtil.uninstallArakhneHandlers();
+		}
+	}
+
+	private static void assertEqualUrls(URL expected, URL actual) {
+		String u1 = expected==null ? null : expected.toExternalForm().replaceAll("/$", ""); //$NON-NLS-1$//$NON-NLS-2$
+		String u2 = actual==null ? null : actual.toExternalForm().replaceAll("/$", ""); //$NON-NLS-1$//$NON-NLS-2$
+		assertEquals(u1, u2);
+	}
+	
+	/**
+	 * @throws Exception 
+	 */
+	public static void testMakeRelativeFileFile() throws Exception {
+		File root, abs, rel;
+		
+		root = FileSystem.getUserHomeDirectory();
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"); //$NON-NLS-1$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator+"a"); //$NON-NLS-1$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"+File.separator+"b"); //$NON-NLS-1$ //$NON-NLS-2$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator+"a","b"); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		abs = new File("a","b"); //$NON-NLS-1$//$NON-NLS-2$
+		rel = new File("a","b"); //$NON-NLS-1$//$NON-NLS-2$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		
+		
+		root = new File(FileSystem.getUserHomeDirectory(), "zz"+File.separator+"abc"); //$NON-NLS-1$ //$NON-NLS-2$
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"); //$NON-NLS-1$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+"a"); //$NON-NLS-1$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+	
+	
+		root = new File(FileSystem.getUserHomeDirectory(), "zz"+File.separator+"abc"); //$NON-NLS-1$//$NON-NLS-2$
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"+File.separator+"zz"+File.separator+"bc"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+"a"+File.separator+"zz"+File.separator+"bc"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+	}
+
+	/**
+	 * @throws Exception 
+	 */
+	public static void testMakeRelativeFileURL() throws Exception {
+		File abs, rel;
+		URL root;
+		
+		root = FileSystem.getUserHomeDirectory().toURI().toURL();
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"); //$NON-NLS-1$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator+"a"); //$NON-NLS-1$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"+File.separator+"b"); //$NON-NLS-1$ //$NON-NLS-2$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator+"a","b"); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		abs = new File("a","b"); //$NON-NLS-1$//$NON-NLS-2$
+		rel = new File("a","b"); //$NON-NLS-1$//$NON-NLS-2$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		
+		
+		root = FileSystem.join(FileSystem.getUserHomeDirectory().toURI().toURL(), "zz", "abc"); //$NON-NLS-1$ //$NON-NLS-2$
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"); //$NON-NLS-1$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+"a"); //$NON-NLS-1$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+	
+	
+		root = FileSystem.join(FileSystem.getUserHomeDirectory().toURI().toURL(), "zz", "abc"); //$NON-NLS-1$//$NON-NLS-2$
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"+File.separator+"zz"+File.separator+"bc"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+"a"+File.separator+"zz"+File.separator+"bc"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+	}
+
+	/**
+	 * @throws Exception 
+	 */
+	public static void testMakeRelativeURLURL() throws Exception {
+		File rel;
+		URL root, abs;
+		
+		root = FileSystem.getUserHomeDirectory().toURI().toURL();
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a").toURI().toURL(); //$NON-NLS-1$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator+"a"); //$NON-NLS-1$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"+File.separator+"b").toURI().toURL(); //$NON-NLS-1$ //$NON-NLS-2$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator+"a","b"); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+		
+		
+		root = FileSystem.join(FileSystem.getUserHomeDirectory().toURI().toURL(), "zz", "abc"); //$NON-NLS-1$ //$NON-NLS-2$
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a").toURI().toURL(); //$NON-NLS-1$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+"a"); //$NON-NLS-1$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+
+	
+	
+		root = FileSystem.join(FileSystem.getUserHomeDirectory().toURI().toURL(), "zz", "abc"); //$NON-NLS-1$//$NON-NLS-2$
+		
+		abs = new File(FileSystem.getUserHomeDirectory(), "a"+File.separator+"zz"+File.separator+"bc").toURI().toURL(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		rel = new File(FileSystem.CURRENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+FileSystem.PARENT_DIRECTORY+File.separator
+				+"a"+File.separator+"zz"+File.separator+"bc"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		assertEquals(rel, FileSystem.makeRelative(abs, root));
+	}
+	
+	/**
+	 * @throws MalformedURLException
+	 */
+	public static void testMakeCanonicalURL() throws MalformedURLException {
+		assertEquals(
+				new URL("http://toto:titi@xxxxxxxxxxxxxxx/path/to/file.x.z.z?toto#frag";), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL(TEST_URL1)));
+
+		assertEquals(
+				new URL("jar:file:/home/test/j.jar!/org/arakhne/vmutil/file.x.z.z"), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL(TEST_URL2)));
+
+		assertEquals(
+				new URL("jar:jar:http://www.arakhne.org/j.jar!/inner/myjar.jar!/org/arakhne/vmutil/file.x.z.z";), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL(TEST_URL3)));
+		
+		assertEquals(
+				new URL("file:/a/b/c/d/e"), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL("file:/a/b/./c/./d/e"))); //$NON-NLS-1$
+		
+		assertEquals(
+				new URL("file:/a/d/e"), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL("file:/a/b/../c/../d/e"))); //$NON-NLS-1$
+
+		assertEquals(
+				new URL("file:/a/b/d/e"), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL("file:/a/b/./c/../d/e"))); //$NON-NLS-1$
+
+		assertEquals(
+				new URL("file:../a/b/c/d/e"), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL("file:../a/b/./c/./d/e"))); //$NON-NLS-1$
+
+		assertEquals(
+				new URL("file:../a/c/d/e"), //$NON-NLS-1$
+				FileSystem.makeCanonicalURL(new URL("file:../a/b/../c/./d/e"))); //$NON-NLS-1$
+	}
+	
+	private static String readInputStream(InputStream is) throws IOException {
+		StringBuilder b = new StringBuilder();
+		byte[] buffer = new byte[2048];
+		int len;
+		while ((len=is.read(buffer))>0) {
+			b.append(new String(buffer, 0, len));
+		}
+		is.close();
+		return b.toString();
+	}
+	
+	private static void createZip(File testArchive) throws IOException {
+		File testDir = FileSystem.createTempDirectory("unittest", null); //$NON-NLS-1$
+		FileSystem.deleteOnExit(testDir);
+		FileSystem.copy(FileSystemTest.class.getResource("test.txt"), testDir); //$NON-NLS-1$
+		FileSystem.copy(FileSystemTest.class.getResource("test2.txt"), testDir); //$NON-NLS-1$
+		File subdir = new File(testDir, "subdir"); //$NON-NLS-1$
+		subdir.mkdirs();
+		FileSystem.copy(FileSystemTest.class.getResource("test.txt"), subdir); //$NON-NLS-1$
+		FileSystem.zipFile(testDir, testArchive);
+	}
+	
+	/**
+	 * @throws IOException
+	 */
+	public static void testZipFileFile() throws IOException {
+		File testArchive = File.createTempFile("unittest", ".zip"); //$NON-NLS-1$ //$NON-NLS-2$
+		testArchive.deleteOnExit();
+		
+		createZip(testArchive);
+		
+		try (ZipFile zipFile = new ZipFile(testArchive)) {
+
+			ZipEntry zipEntry = zipFile.getEntry("test.txt"); //$NON-NLS-1$
+			assertNotNull(zipEntry);
+			assertEquals("TEST1: FOR UNIT TEST ONLY", readInputStream(zipFile.getInputStream(zipEntry))); //$NON-NLS-1$
+	
+			zipEntry = zipFile.getEntry("test2.txt"); //$NON-NLS-1$
+			assertNotNull(zipEntry);
+			assertEquals("TEST2: FOR UNIT TEST ONLY", readInputStream(zipFile.getInputStream(zipEntry))); //$NON-NLS-1$
+			
+			zipEntry = zipFile.getEntry("subdir/test.txt"); //$NON-NLS-1$
+			assertNotNull(zipEntry);
+			assertEquals("TEST1: FOR UNIT TEST ONLY", readInputStream(zipFile.getInputStream(zipEntry))); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * @throws IOException
+	 */
+	public static void testUnzipFileFile() throws IOException {
+		File testArchive = File.createTempFile("unittest", ".zip"); //$NON-NLS-1$ //$NON-NLS-2$
+		testArchive.deleteOnExit();
+		createZip(testArchive);
+
+		File testDir = FileSystem.createTempDirectory("unittest", null); //$NON-NLS-1$
+		FileSystem.deleteOnExit(testDir);
+		File subDir = new File(testDir, "subdir"); //$NON-NLS-1$
+		
+		FileSystem.unzipFile(testArchive, testDir);
+		
+		assertTrue(testDir.isDirectory());
+		assertTrue(subDir.isDirectory());
+		
+		String txt;
+		
+		File file = new File(testDir, "test.txt"); //$NON-NLS-1$
+		try (FileInputStream fis = new FileInputStream(file)) {
+			txt = readInputStream(fis);
+		}
+		assertEquals("TEST1: FOR UNIT TEST ONLY", txt); //$NON-NLS-1$
+		
+		file = new File(testDir, "test2.txt"); //$NON-NLS-1$
+		try (FileInputStream fis = new FileInputStream(file)) {
+			txt = readInputStream(fis);
+		}
+		assertEquals("TEST2: FOR UNIT TEST ONLY", txt); //$NON-NLS-1$
+
+		file = new File(subDir, "test.txt"); //$NON-NLS-1$
+		try (FileInputStream fis = new FileInputStream(file)) {
+			txt = readInputStream(fis);
+		}
+		assertEquals("TEST1: FOR UNIT TEST ONLY", txt); //$NON-NLS-1$
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/FileSystemTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ResourcesTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ResourcesTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ResourcesTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,247 @@
+/* $Id$
+ * 
+ * Copyright (C) 2007-09 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+/**
+ * @author $Author: galland$
+ * @version $Name$ $Revision$ $Date$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneVmutils
+ */
+public class ResourcesTest extends TestCase {
+
+    /**
+     */
+    public static void testGetResourceString() {
+    	assertNull(Resources.getResource(null));
+
+    	URL u1 = Resources.getResource("/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u1);
+    	
+    	URL u2 = Resources.getResource("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u2);
+    	
+    	assertEquals(u1,u2);
+    }
+
+   	/**
+     */
+    public static void testGetResourceClassString() {
+    	assertNull(Resources.getResource(ResourcesTest.class, null));
+    	
+    	URL u1 = Resources.getResource(ResourcesTest.class, "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u1);
+    	
+    	URL u2 = Resources.getResource(ResourcesTest.class, "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u2);
+    	
+    	URL u3 = Resources.getResource(ResourcesTest.class, "test.txt"); //$NON-NLS-1$
+    	assertNotNull(u3);
+
+    	assertEquals(u1,u2);
+    	assertEquals(u1,u3);
+
+    	assertNull(Resources.getResource((Class<?>)null, null));
+    	
+    	u1 = Resources.getResource((Class<?>)null, "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNull(u1);
+    	
+    	u2 = Resources.getResource((Class<?>)null, "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNull(u2);
+    }
+
+   	/**
+     */
+    public static void testGetResourcePackageString() {
+    	ClassLoader l = ResourcesTest.class.getClassLoader();
+    	Package p = Package.getPackage("org.arakhne.vmutil"); //$NON-NLS-1$
+    	assertNull(Resources.getResource(ResourcesTest.class, null));
+    	
+    	URL u1 = Resources.getResource(l, p, "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNull(u1);
+    	
+    	URL u2 = Resources.getResource(l, p, "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNull(u2);
+    	
+    	URL u3 = Resources.getResource(l, p, "test.txt"); //$NON-NLS-1$
+    	assertNotNull(u3);
+
+    	URL u4 = Resources.getResource(l, p, "/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u4);
+    	
+    	assertEquals(u3, u4);
+
+    	assertNull(Resources.getResource(l, (Package)null, null));
+    	
+    	u1 = Resources.getResource(l, (Package)null, "test.txt"); //$NON-NLS-1$
+    	assertNull(u1);
+    	
+    	u2 = Resources.getResource(l, (Package)null, "/test.txt"); //$NON-NLS-1$
+    	assertNull(u2);
+    }
+
+    /**
+     */
+    public static void testGetResourceClassLoaderString() {
+    	assertNull(Resources.getResource(ResourcesTest.class.getClassLoader(), null));    	
+    	
+    	URL u1 = Resources.getResource(ResourcesTest.class.getClassLoader(), "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u1);
+    	
+    	URL u2 = Resources.getResource(ResourcesTest.class.getClassLoader(), "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u2);
+    	
+    	assertEquals(u1,u2);
+
+    	assertNull(Resources.getResource((ClassLoader)null, null));    	
+    	
+    	u1 = Resources.getResource((ClassLoader)null, "/org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u1);
+    	
+    	u2 = Resources.getResource((ClassLoader)null, "org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+    	assertNotNull(u2);
+    	
+    	assertEquals(u1,u2);
+    }
+    
+    /**
+     * @throws IOException 
+     */
+    public static void testGetResourceAsStreamString() throws IOException {
+    	assertNull(Resources.getResourceAsStream(null));
+
+    	try (InputStream is = Resources.getResourceAsStream("/org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+    	
+    	try (InputStream is = Resources.getResourceAsStream("org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+    }
+
+   	/**
+   	 * @throws IOException 
+     */
+    public static void testGetResourceAsStreamClassString() throws IOException {
+    	assertNull(Resources.getResourceAsStream(ResourcesTest.class, null));
+
+    	try (InputStream is = Resources.getResourceAsStream(ResourcesTest.class, "/org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+    	
+    	try (InputStream is = Resources.getResourceAsStream(ResourcesTest.class, "org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+
+    	try (InputStream is = Resources.getResourceAsStream(ResourcesTest.class, "/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+
+    	try (InputStream is = Resources.getResourceAsStream(ResourcesTest.class, "test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+
+    	assertNull(Resources.getResourceAsStream((Class<?>)null, null));
+
+    	try (InputStream is = Resources.getResourceAsStream((Class<?>)null, "/org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+    	
+    	try (InputStream is = Resources.getResourceAsStream((Class<?>)null, "org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+
+    	try (InputStream is = Resources.getResourceAsStream((Class<?>)null, "test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+    }
+
+   	/**
+   	 * @throws IOException 
+     */
+    public static void testGetResourceAsStreamPackageString() throws IOException {
+    	ClassLoader l = ResourcesTest.class.getClassLoader();
+    	Package p = Package.getPackage("org.arakhne.vmutil"); //$NON-NLS-1$
+    	assertNull(Resources.getResourceAsStream(ResourcesTest.class, null));
+
+    	try (InputStream is = Resources.getResourceAsStream(l, p, "/org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+    	
+    	try (InputStream is = Resources.getResourceAsStream(l, p, "org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+
+    	try (InputStream is = Resources.getResourceAsStream(l, p, "/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+
+    	try (InputStream is = Resources.getResourceAsStream(l, p, "test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+    	
+    	assertNull(Resources.getResourceAsStream(l, (Package)null, null));
+
+    	try (InputStream is = Resources.getResourceAsStream(l, (Package)null, "/org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+    	
+    	try (InputStream is = Resources.getResourceAsStream(l, (Package)null, "org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+
+    	try (InputStream is = Resources.getResourceAsStream(l, (Package)null, "test.txt")) { //$NON-NLS-1$
+    		assertNull(is);
+    	}
+    }
+
+    /**
+     * @throws IOException 
+     */
+    public static void testGetResourceAsStreamClassLoaderString() throws IOException {
+    	assertNull(Resources.getResourceAsStream(ResourcesTest.class.getClassLoader(), null));
+    	
+    	try (InputStream is = Resources.getResourceAsStream(ResourcesTest.class.getClassLoader(), "/org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+    	
+    	try (InputStream is = Resources.getResourceAsStream(ResourcesTest.class.getClassLoader(), "org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+
+    	assertNull(Resources.getResourceAsStream((ClassLoader)null, null));
+    	
+    	try (InputStream is = Resources.getResourceAsStream((ClassLoader)null, "/org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+    	
+    	try (InputStream is = Resources.getResourceAsStream((ClassLoader)null, "org/arakhne/vmutil/test.txt")) { //$NON-NLS-1$
+    		assertNotNull(is);
+    	}
+    }
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/ResourcesTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,297 @@
+/* $Id$
+ * 
+ * Copyright (C) 2007-09 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+/**
+* @author $Author: galland$
+* @version $Name$ $Revision$ $Date$
+* @mavengroupid org.arakhne.afc
+* @mavenartifactid arakhneVmutils
+*/
+public class VMCommandLineTest extends TestCase {
+
+	private static final String[] commandLine = new String[] { 
+			"-D=true", "-v", "clean", "-v", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+			"-F", "-b", "-v", "package", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+			"-F", "123", "-nob", "installters", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+			"-S", "-b", "--", "-v"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+	
+	private static final String[] commandLine2 = new String[] {"-D=true"}; //$NON-NLS-1$
+
+	private static final String[] optionDefinitions = new String[] {
+			"D=b", "S=s", "F:f", "v+", "b!"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		VMCommandLine.saveVMParameters((Class<?>)null, new String[0]);
+	}
+	
+	/**
+	 */
+	public static final void testSaveVMParameters() {
+		assertTrue(Arrays.equals(new String[0], VMCommandLine.getCommandLineParameters()));
+		VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+		assertTrue(Arrays.equals(commandLine, VMCommandLine.getCommandLineParameters()));
+		VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine2);
+		assertTrue(Arrays.equals(commandLine2, VMCommandLine.getCommandLineParameters()));
+	}
+
+	/**
+	 */
+	public static final void testSaveVMParametersIfNotSet() {
+		assertTrue(Arrays.equals(new String[0], VMCommandLine.getCommandLineParameters()));
+		VMCommandLine.saveVMParametersIfNotSet(VMCommandLineTest.class, commandLine);
+		assertTrue(Arrays.equals(commandLine, VMCommandLine.getCommandLineParameters()));
+		VMCommandLine.saveVMParametersIfNotSet(VMCommandLineTest.class, commandLine2);
+		assertTrue(Arrays.equals(commandLine, VMCommandLine.getCommandLineParameters()));
+	}
+
+	/**
+	 */
+	public static final void testShiftCommandLineParameters() {
+		VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+		assertEquals("-D=true", VMCommandLine.shiftCommandLineParameters()); //$NON-NLS-1$
+		assertTrue(Arrays.equals(new String[] { 
+				"-v", "clean", "-v", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+				"-F", "-b", "-v", "package", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+				"-F", "123", "-nob", "installters", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+				"-S", "-b", "--", "-v"}, //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+				VMCommandLine.getCommandLineParameters()));
+	}
+
+	/**
+	 */
+	public static final void testGetCommandLineOptions() {
+		assertEquals(Collections.emptyMap(), VMCommandLine.getCommandLineOptions());
+	}
+
+	/**
+	 */
+	public static final void testSplitOptionsAndParameters() {
+		VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+		VMCommandLine.splitOptionsAndParameters(optionDefinitions);
+
+		Map<String,List<Object>> options = VMCommandLine.getCommandLineOptions();
+		String[] parameters = VMCommandLine.getCommandLineParameters();
+		List<Object> values;
+		
+		assertNotNull(options);
+		assertEquals(5, options.size());
+		
+		assertTrue(options.containsKey("D")); //$NON-NLS-1$
+		values = options.get("D"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals(true, values.get(0));
+
+		assertTrue(options.containsKey("v")); //$NON-NLS-1$
+		values = options.get("v"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals((long)3, values.get(0));
+
+		assertTrue(options.containsKey("F")); //$NON-NLS-1$
+		values = options.get("F"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(2, values.size());
+		assertEquals(0., values.get(0));
+		assertEquals(123., values.get(1));
+
+		assertTrue(options.containsKey("b")); //$NON-NLS-1$
+		values = options.get("b"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals(false, values.get(0));
+
+		assertTrue(options.containsKey("S")); //$NON-NLS-1$
+		values = options.get("S"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals("-b", values.get(0)); //$NON-NLS-1$
+		
+		values = options.get("nob"); //$NON-NLS-1$
+		assertNull(values);
+
+		assertNotNull(parameters);
+		assertEquals(4, parameters.length);
+		assertEquals("clean", parameters[0]); //$NON-NLS-1$
+		assertEquals("package", parameters[1]); //$NON-NLS-1$
+		assertEquals("installters", parameters[2]); //$NON-NLS-1$
+		assertEquals("-v", parameters[3]); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static final void testGetCommandLineOption() {
+		assertNull(VMCommandLine.getCommandLineOption("S")); //$NON-NLS-1$
+		
+		VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+		VMCommandLine.splitOptionsAndParameters(optionDefinitions);
+		
+		List<Object> values;
+		values = VMCommandLine.getCommandLineOption("S"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals("-b", values.get(0)); //$NON-NLS-1$
+
+		assertNull(VMCommandLine.getCommandLineOption("nob")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static final void testHasCommandLineOption() {
+		assertFalse(VMCommandLine.hasCommandLineOption("S")); //$NON-NLS-1$
+		
+		VMCommandLine.saveVMParameters(VMCommandLineTest.class, commandLine);
+		VMCommandLine.splitOptionsAndParameters(optionDefinitions);
+		
+		assertTrue(VMCommandLine.hasCommandLineOption("S")); //$NON-NLS-1$
+		assertFalse(VMCommandLine.hasCommandLineOption("nob")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static final void testVMCommandLineClassOfQStringArray() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, commandLine);
+		assertTrue(Arrays.equals(commandLine, c.getParameters()));
+	}
+
+	/**
+	 */
+	public static final void testVMCommandLineClassOfQStringArrayStringArray() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertTrue(Arrays.equals(new String[] {
+				"clean", "package", "installters", "-v" //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+		}, c.getParameters()));
+	}
+
+	/**
+	 */
+	public static final void testHasOption() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertTrue(c.hasOption("S")); //$NON-NLS-1$
+		assertTrue(c.hasOption("b")); //$NON-NLS-1$
+		assertFalse(c.hasOption("nob")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static final void testGetFirstOptionValue() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertEquals("-b", c.getFirstOptionValue("S")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(false, c.getFirstOptionValue("b")); //$NON-NLS-1$
+		assertEquals(0., c.getFirstOptionValue("F")); //$NON-NLS-1$
+		assertNull(c.getFirstOptionValue("nob")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static final void testGetOptionValues() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		List<Object> values;
+		
+		values = c.getOptionValues("D"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals(true, values.get(0));
+
+		values = c.getOptionValues("v"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals((long)3, values.get(0));
+
+		values = c.getOptionValues("F"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(2, values.size());
+		assertEquals(0., values.get(0));
+		assertEquals(123., values.get(1));
+
+		values = c.getOptionValues("b"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals(false, values.get(0));
+
+		values = c.getOptionValues("S"); //$NON-NLS-1$
+		assertNotNull(values);
+		assertEquals(1, values.size());
+		assertEquals("-b", values.get(0)); //$NON-NLS-1$
+
+		assertNull(c.getOptionValues("nob")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static final void testGetParameters() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertNotSame(commandLine, c.getParameters());
+		assertTrue(Arrays.equals(new String[] {
+				"clean", "package", "installters", "-v" //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+		}, c.getParameters()));
+	}
+
+	/**
+	 */
+	public static final void testShiftParameters() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertEquals("clean", c.shiftParameters()); //$NON-NLS-1$
+		assertNotSame(commandLine, c.getParameters());
+		assertTrue(Arrays.equals(new String[] {
+				"package", "installters", "-v" //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		}, c.getParameters()));
+	}
+
+	/**
+	 */
+	public static final void testGetParameterCount() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertEquals(4, c.getParameterCount());
+	}
+
+	/**
+	 */
+	public static final void testGetParameterAt() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertEquals("clean", c.getParameterAt(0)); //$NON-NLS-1$
+		assertEquals("package", c.getParameterAt(1)); //$NON-NLS-1$
+		assertEquals("installters", c.getParameterAt(2)); //$NON-NLS-1$
+		assertEquals("-v", c.getParameterAt(3)); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public static final void testIsParameterExists() {
+		VMCommandLine c = new VMCommandLine(VMCommandLineTest.class, optionDefinitions, commandLine);
+		assertTrue(c.isParameterExists(0));
+		assertTrue(c.isParameterExists(1));
+		assertTrue(c.isParameterExists(2));
+		assertTrue(c.isParameterExists(3));
+		assertFalse(c.isParameterExists(5));
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/VMCommandLineTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/file/URLConnectionTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/file/URLConnectionTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/file/URLConnectionTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,152 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.file;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Map;
+
+import org.arakhne.vmutil.Resources;
+import org.arakhne.vmutil.URLHandlerUtil;
+
+import junit.framework.TestCase;
+
+/**
+ * @author $Author: galland$
+ * @version $Name$ $Revision$ $Date$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneVmutils
+ */
+public class URLConnectionTest extends TestCase {
+
+	private URLConnection connection;
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		URLHandlerUtil.installArakhneHandlers();
+		URL resourceUrl = Resources.getResource("org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+		assertNotNull(resourceUrl);
+		this.connection = new URLConnection(resourceUrl);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void tearDown() throws Exception {
+		this.connection = null;
+		URLHandlerUtil.uninstallArakhneHandlers();
+		super.tearDown();
+	}
+
+	/**
+	 */
+	public void testGetHeaderFieldKeyInt() {
+		assertEquals("content-type", this.connection.getHeaderFieldKey(0)); //$NON-NLS-1$
+		assertEquals("content-length", this.connection.getHeaderFieldKey(1)); //$NON-NLS-1$
+		assertEquals("last-modified", this.connection.getHeaderFieldKey(2)); //$NON-NLS-1$
+		assertNull(this.connection.getHeaderFieldKey(3));
+	}
+
+	/**
+	 */
+	public void testGetHeaderFieldInt() {
+		assertEquals("application/octet-stream", this.connection.getHeaderField(0)); //$NON-NLS-1$
+		assertEquals("25", this.connection.getHeaderField(1)); //$NON-NLS-1$
+		assertNotNull(this.connection.getHeaderField(2));
+		assertNull(this.connection.getHeaderField(3));
+	}
+
+	/**
+	 */
+	public void testGetHeaderFieldString() {
+		assertEquals("application/octet-stream", this.connection.getHeaderField("content-type")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals("25", this.connection.getHeaderField("content-length")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertNotNull(this.connection.getHeaderField("last-modified")); //$NON-NLS-1$
+		assertNull(this.connection.getHeaderField("expires")); //$NON-NLS-1$
+	}
+
+	/**
+	 */
+	public void testGetHeaderFields() {
+		Map<?,?> map = this.connection.getHeaderFields();
+		assertNotNull(map);
+		assertEquals(3, map.size());
+		assertEquals(Collections.singletonList("application/octet-stream"), map.get("content-type")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertEquals(Collections.singletonList("25"), map.get("content-length")); //$NON-NLS-1$ //$NON-NLS-2$
+		assertNotNull(map.get("last-modified")); //$NON-NLS-1$
+		assertNull(map.get("expires")); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws IOException
+	 */
+	public void testGetInputStream() throws IOException {
+		String line;
+		try (
+				InputStream is = this.connection.getInputStream();
+				BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
+			line = br.readLine();
+		}
+		assertEquals("TEST1: FOR UNIT TEST ONLY", line); //$NON-NLS-1$
+	}
+
+	/**
+	 * @throws IOException
+	 */
+	public static void testGetOutputStream() throws IOException {
+		File tmpFile = File.createTempFile("unittest", ".txt"); //$NON-NLS-1$ //$NON-NLS-2$
+		tmpFile.deleteOnExit();
+
+		URLConnection con = new URLConnection(tmpFile.toURI().toURL());
+		con.setDoOutput(true);
+
+		try (
+				OutputStream os = con.getOutputStream();
+				OutputStreamWriter osw = new OutputStreamWriter(os);
+				BufferedWriter bw = new BufferedWriter(osw)) {
+			bw.write("HELLO WORLD!"); //$NON-NLS-1$
+		}
+
+		assertEquals(12, tmpFile.length());
+
+		String line;
+		try (BufferedReader br = new BufferedReader(new FileReader(tmpFile))) {
+			line = br.readLine();
+		}
+		assertEquals("HELLO WORLD!", line); //$NON-NLS-1$
+	}
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/file/URLConnectionTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleStub.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleStub.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleStub.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,43 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (c) 2005-10, Multiagent Team,
+ * Laboratoire Systemes et Transports,
+ * Universite de Technologie de Belfort-Montbeliard.
+ * All rights reserved.
+ *
+ * Copyright (C) 2012 Stephane GALLAND, Olivier LAMOTTE.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil.locale;
+
+/**
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+class LocaleStub {
+
+	/**
+	 */
+	public LocaleStub() {
+		//
+	}
+	
+}
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleStub.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,890 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (c) 2005-10, Multiagent Team,
+ * Laboratoire Systemes et Transports,
+ * Universite de Technologie de Belfort-Montbeliard.
+ * All rights reserved.
+ *
+ * Copyright (C) 2012 Stephane GALLAND, Olivier LAMOTTE.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.vmutil.locale;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.MessageFormat;
+
+import junit.framework.TestCase;
+
+/**
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class LocaleTest extends TestCase {
+
+	private final LocaleStub tmp = new LocaleStub();
+	private static final String RESOURCE1 = "org/arakhne/vmutil/locale/LocaleTest"; //$NON-NLS-1$
+	private static final String RESOURCE2 = "org/arakhne/vmutil/locale/LocaleStub"; //$NON-NLS-1$
+	private static final String NOKEY = "NOKEY"; //$NON-NLS-1$
+	private static final String KEY1 = "ONE"; //$NON-NLS-1$
+	private static final String KEY2 = "TWO"; //$NON-NLS-1$
+	private static final String KEY3 = "THREE"; //$NON-NLS-1$
+	private static final String DEFAULT = "DEFAULT"; //$NON-NLS-1$
+	private static final String P1 = "P1"; //$NON-NLS-1$
+	private static final String P2 = "P2"; //$NON-NLS-1$
+	private static final String P3 = "P3"; //$NON-NLS-1$
+	
+    /**
+     */
+    public void testGetStringWithDefaultFromStringStringStringStringArray() {
+    	assert(this.tmp!=null);
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefaultFrom(RESOURCE1,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(RESOURCE1,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(RESOURCE1,KEY1,DEFAULT,P3,P1,P2));
+    	
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefaultFrom(RESOURCE2,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(RESOURCE2,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(RESOURCE2,KEY1,DEFAULT,P3,P1,P2));
+    }
+
+    /**
+     */
+    public static void testGetStringWithDefaultFromClassLoaderStringStringStringStringArray() {
+    	ClassLoader l = LocaleTest.class.getClassLoader();
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefaultFrom(l, RESOURCE1,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(l, RESOURCE1,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(l, RESOURCE1,KEY1,DEFAULT,P3,P1,P2));
+    	
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefaultFrom(l, RESOURCE2,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(l, RESOURCE2,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefaultFrom(l, RESOURCE2,KEY1,DEFAULT,P3,P1,P2));
+    }
+
+    /**
+     */
+    public static void testGetStringFromStringStringStringArray() {
+    	assertEquals(NOKEY,
+    			Locale.getStringFrom(RESOURCE1,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(RESOURCE1,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(RESOURCE1,KEY1,P3,P1,P2));
+    	
+    	assertEquals(
+    			NOKEY,
+    			Locale.getStringFrom(RESOURCE2,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(RESOURCE2,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(RESOURCE2,KEY1,P3,P1,P2));
+    }
+    
+    /**
+     */
+    public static void testGetStringFromClassLoaderStringStringStringArray() {
+    	ClassLoader l = LocaleTest.class.getClassLoader();
+    	
+    	assertEquals(NOKEY,
+    			Locale.getStringFrom(l, RESOURCE1,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(l, RESOURCE1,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(l, RESOURCE1,KEY1,P3,P1,P2));
+    	
+    	assertEquals(
+    			NOKEY,
+    			Locale.getStringFrom(l, RESOURCE2,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(l, RESOURCE2,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringFrom(l, RESOURCE2,KEY1,P3,P1,P2));
+    }
+
+    /**
+     */
+    public static void testGetStringClassStringStringArray() {
+    	assertEquals(NOKEY,
+    			Locale.getString(LocaleTest.class,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getString(LocaleTest.class,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getString(LocaleTest.class,KEY1,P3,P1,P2));
+    	
+    	assertEquals(
+    			NOKEY,
+    			Locale.getString(LocaleStub.class,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getString(LocaleStub.class,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getString(LocaleStub.class,KEY1,P3,P1,P2));
+    }
+    
+    /**
+     */
+    public static void testGetStringClassLoaderClassStringStringArray() {
+    	ClassLoader l = LocaleTest.class.getClassLoader();
+    	
+    	assertEquals(NOKEY,
+    			Locale.getString(l, LocaleTest.class,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getString(l, LocaleTest.class,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getString(l, LocaleTest.class,KEY1,P3,P1,P2));
+    	
+    	assertEquals(
+    			NOKEY,
+    			Locale.getString(l, LocaleStub.class,NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getString(l, LocaleStub.class,KEY1,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getString(l, LocaleStub.class,KEY1,P3,P1,P2));
+    }
+
+    /**
+     */
+    public static void testGetStringWithDefaultClassStringStringStringArray() {
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefault(LocaleTest.class,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(LocaleTest.class,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(LocaleTest.class,KEY1,DEFAULT,P3,P1,P2));
+    	
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefault(LocaleStub.class,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(LocaleStub.class,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(LocaleStub.class,KEY1,DEFAULT,P3,P1,P2));
+    }
+
+    /**
+     */
+    public static void testGetStringWithDefaultClassLoaderClassStringStringStringArray() {
+    	ClassLoader l = LocaleTest.class.getClassLoader();
+    	
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefault(l, LocaleTest.class,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(l, LocaleTest.class,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(l, LocaleTest.class,KEY1,DEFAULT,P3,P1,P2));
+    	
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefault(l, LocaleStub.class,NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(l, LocaleStub.class,KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"DEF P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(l, LocaleStub.class,KEY1,DEFAULT,P3,P1,P2));
+    }
+
+    /**
+     */
+    public static void testGetStringStringStringArray() {
+    	assertEquals(
+    			NOKEY,
+    			Locale.getString(NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getString(KEY1,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getString(KEY1,P3,P1,P2));
+    	try {
+    		Locale.getString(KEY2);
+    		fail("expecting IllegalArgumentException"); //$NON-NLS-1$
+    	}
+    	catch(IllegalArgumentException _) {
+    		// expected exception
+    	}
+    	assertEquals(
+    			"(d92b87b0-efe9-4dd9-903f-7c994b8e2a9f)", //$NON-NLS-1$
+    			Locale.getString(KEY3));
+    }
+    
+    /**
+     */
+    public static void testGetStringClassLoaderStringStringArray() {
+    	ClassLoader l = LocaleTest.class.getClassLoader();
+    	
+    	assertEquals(
+    			NOKEY,
+    			Locale.getString(l, NOKEY,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getString(l, KEY1,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getString(l, KEY1,P3,P1,P2));
+    	try {
+    		Locale.getString(l, KEY2);
+    		fail("expecting IllegalArgumentException"); //$NON-NLS-1$
+    	}
+    	catch(IllegalArgumentException _) {
+    		// expected exception
+    	}
+    	assertEquals(
+    			"(d92b87b0-efe9-4dd9-903f-7c994b8e2a9f)", //$NON-NLS-1$
+    			Locale.getString(l, KEY3));
+    }
+
+    /**
+     */
+    public static void testGetStringWithDefaultStringStringStringArray() {
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefault(NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(KEY1,DEFAULT,P3,P1,P2));
+    	try {
+    		Locale.getStringWithDefault(KEY2,DEFAULT);
+    		fail("expecting IllegalArgumentException"); //$NON-NLS-1$
+    	}
+    	catch(IllegalArgumentException _) {
+    		//expected exception
+    	}
+    	assertEquals(
+    			"(d92b87b0-efe9-4dd9-903f-7c994b8e2a9f)", //$NON-NLS-1$
+    			Locale.getStringWithDefault(KEY3,DEFAULT));
+    }
+
+    /**
+     */
+    public static void testGetStringWithDefaultClassLoaderStringStringStringArray() {
+    	ClassLoader l = LocaleTest.class.getClassLoader();
+    	
+    	assertEquals(
+    			DEFAULT,
+    			Locale.getStringWithDefault(l, NOKEY,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P1 'P2' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(l, KEY1,DEFAULT,P1,P2,P3));
+    	assertEquals(
+    			"ABC P3 'P1' {2}", //$NON-NLS-1$
+    			Locale.getStringWithDefault(l, KEY1,DEFAULT,P3,P1,P2));
+    	try {
+    		Locale.getStringWithDefault(l, KEY2, DEFAULT);
+    		fail("expecting IllegalArgumentException"); //$NON-NLS-1$
+    	}
+    	catch(IllegalArgumentException _) {
+    		// expected exception
+    	}
+    	assertEquals(
+    			"(d92b87b0-efe9-4dd9-903f-7c994b8e2a9f)", //$NON-NLS-1$
+    			Locale.getStringWithDefault(l, KEY3, DEFAULT));
+    }
+    
+    /**
+     */
+    public static void testGetStringWithRawFormatStyle() {
+    	Number data;
+    	String raw, localized;
+    	
+    	data = Double.valueOf(123.456);
+    	raw = Double.toString(123.456);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	raw = Double.toString(-123.456);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	raw = Long.toString(123456);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	raw = Long.toString(-123456);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	raw = Short.toString((short)123);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	raw = Short.toString((short)-123);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	raw = "123456789123456789123456789.123456789"; //$NON-NLS-1$
+    	data = new BigDecimal(raw);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	raw = "-123456789123456789123456789.123456789"; //$NON-NLS-1$
+    	data = new BigDecimal(raw);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	raw = "123456789123456789123456789123456789"; //$NON-NLS-1$
+    	data = new BigInteger(raw);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+
+    	raw = "-123456789123456789123456789123456789"; //$NON-NLS-1$
+    	data = new BigInteger(raw);
+    	localized = MessageFormat.format("{0}", data); //$NON-NLS-1$
+    	assertEquals(
+    			localized+" "+raw, //$NON-NLS-1$
+    			Locale.getString("FOUR", data)); //$NON-NLS-1$
+    }
+    
+    /**
+     */
+    public static void testGetStringWithRawFormatStyleWithFormat1() {
+    	Number data;
+    	
+    	data = Double.valueOf(123.456);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	assertEquals(
+    			"123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	assertEquals(
+    			"-123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("-123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_1", data)); //$NON-NLS-1$
+    }
+ 
+    /**
+     */
+    public static void testGetStringWithRawFormatStyleWithFormat2() {
+    	Number data;
+    	
+    	data = Double.valueOf(123.456);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	assertEquals(
+    			"123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	assertEquals(
+    			"-123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("-123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_2", data)); //$NON-NLS-1$
+    }
+   
+    /**
+     */
+    public static void testGetStringWithRawFormatStyleWithFormat3() {
+    	Number data;
+    	
+    	data = Double.valueOf(123.456);
+    	assertEquals(
+    			"123.5", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	assertEquals(
+    			"-123.5", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	assertEquals(
+    			"123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	assertEquals(
+    			"-123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789.1", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456790.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789.1", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456790.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("-123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_3", data)); //$NON-NLS-1$
+    }
+
+    /**
+     */
+    public static void testGetStringWithRawFormatStyleWithFormat4() {
+    	Number data;
+    	
+    	data = Double.valueOf(123.456);
+    	assertEquals(
+    			"123.46", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	assertEquals(
+    			"-123.46", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	assertEquals(
+    			"123456.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	assertEquals(
+    			"-123456.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	assertEquals(
+    			"123.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	assertEquals(
+    			"-123.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789.12", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789.99", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789.12", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789.99", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789123456789.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("-123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789123456789.0", //$NON-NLS-1$
+    			Locale.getString("FORMAT_4", data)); //$NON-NLS-1$
+    }
+    
+    /**
+     */
+    public static void testGetStringWithRawFormatStyleWithFormat5() {
+    	Number data;
+    	
+    	data = Double.valueOf(123.456);
+    	assertEquals(
+    			"123.456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	assertEquals(
+    			"-123.456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	assertEquals(
+    			"123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	assertEquals(
+    			"-123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789.123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789.988", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789.123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789.988", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("-123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_5", data)); //$NON-NLS-1$
+    }
+    
+    /**
+     */
+    public static void testGetStringWithRawFormatStyleWithFormat6() {
+    	Number data;
+    	
+    	data = Double.valueOf(123.456);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	assertEquals(
+    			"123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	assertEquals(
+    			"-123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("-123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_6", data)); //$NON-NLS-1$
+    }
+    
+    /**
+     */
+    public static void testGetStringWithRawFormatStyleWithFormat7() {
+    	Number data;
+    	
+    	data = Double.valueOf(123.456);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = Double.valueOf(-123.456);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(123456);
+    	assertEquals(
+    			"123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = Long.valueOf(-123456);
+    	assertEquals(
+    			"-123456", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)123);
+    	assertEquals(
+    			"123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = Short.valueOf((short)-123);
+    	assertEquals(
+    			"-123", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = new BigDecimal("-123456789123456789123456789.987654321"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456790", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+
+    	data = new BigInteger("-123456789123456789123456789123456789"); //$NON-NLS-1$
+    	assertEquals(
+    			"-123456789123456789123456789123456789", //$NON-NLS-1$
+    			Locale.getString("FORMAT_7", data)); //$NON-NLS-1$
+    }
+    
+}
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/locale/LocaleTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/resource/URLConnectionTest.java
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/resource/URLConnectionTest.java	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/resource/URLConnectionTest.java	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,79 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2010 Stephane GALLAND.
+ * Copyright (C) 2012 Stephane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.vmutil.resource;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import org.arakhne.vmutil.URLHandlerUtil;
+
+import junit.framework.TestCase;
+
+/**
+ * @author $Author: galland$
+ * @version $Name$ $Revision$ $Date$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneVmutils
+ */
+public class URLConnectionTest extends TestCase {
+
+	private URLConnection connection;
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		URLHandlerUtil.installArakhneHandlers();
+		URL resourceUrl = new URL("resource:org/arakhne/vmutil/test.txt"); //$NON-NLS-1$
+		assertNotNull(resourceUrl);
+		this.connection = new URLConnection(resourceUrl);
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void tearDown() throws Exception {
+		this.connection = null;
+		URLHandlerUtil.uninstallArakhneHandlers();
+		super.tearDown();
+	}
+	
+	/**
+	 * @throws IOException
+	 */
+	public void testGetInputStream() throws IOException {
+		String line;
+		try (
+				InputStream is = this.connection.getInputStream();
+				BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
+			line = br.readLine();
+		}
+		assertEquals("TEST1: FOR UNIT TEST ONLY", line); //$NON-NLS-1$
+    }
+
+}


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/java/org/arakhne/vmutil/resource/URLConnectionTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleStub.properties
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleStub.properties	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleStub.properties	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,25 @@
+# $Id$
+# 
+# Copyright (c) 2010, Multiagent Team,
+# Laboratoire Systemes et Transports,
+# Universite de Technologie de Belfort-Montbeliard.
+# All rights reserved.
+#
+# Copyright (c) 2012, Stephane GALLAND, Olivier LAMOTTE.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# This program is free software; you can redistribute it and/or modify
+
+ONE = DEF {0} ''{1}'' '{2}'
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleStub.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleTest.properties
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleTest.properties	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleTest.properties	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1,35 @@
+# $Id$
+# 
+# Copyright (c) 2010, Multiagent Team,
+# Laboratoire Systemes et Transports,
+# Universite de Technologie de Belfort-Montbeliard.
+# All rights reserved.
+#
+# Copyright (c) 2012, Stephane GALLAND, Olivier LAMOTTE.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# This program is free software; you can redistribute it and/or modify
+
+ONE = ABC {0} ''{1}'' '{2}'
+TWO = {d92b87b0-efe9-4dd9-903f-7c994b8e2a9f}
+THREE = (d92b87b0-efe9-4dd9-903f-7c994b8e2a9f)
+FOUR = {0} {0,number,raw}
+FORMAT_1 = {0,number,raw,#}
+FORMAT_2 = {0,number,raw,#.}
+FORMAT_3 = {0,number,raw,#.#}
+FORMAT_4 = {0,number,raw,0.0#}
+FORMAT_5 = {0,number,raw,#.###}
+FORMAT_6 = {0,number,raw,#0.}
+FORMAT_7 = {0,number,raw,#0}
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/locale/LocaleTest.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test.txt
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test.txt	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test.txt	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1 @@
+TEST1: FOR UNIT TEST ONLY
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test2.txt
===================================================================
--- trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test2.txt	                        (rev 0)
+++ trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test2.txt	2012-07-09 20:15:00 UTC (rev 343)
@@ -0,0 +1 @@
+TEST2: FOR UNIT TEST ONLY
\ No newline at end of file


Property changes on: trunk/arakhneVmutils/arakhneVmutils-java/src/test/resources/org/arakhne/vmutil/test2.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/