You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2013/09/06 14:27:03 UTC

[11/18] temporarily added a patched version of javolution with fast collections, because the released version has several bugs (see https://java.net/jira/browse/JAVOLUTION-106 and https://java.net/jira/browse/JAVOLUTION-105)

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/text/TextFormat.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/text/TextFormat.java b/commons/marmotta-commons/src/ext/java/javolution/text/TextFormat.java
new file mode 100644
index 0000000..5ba009a
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/text/TextFormat.java
@@ -0,0 +1,125 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.text;
+
+import java.io.IOException;
+
+import javolution.lang.Parallelizable;
+
+/**
+ * <p> The service for plain text parsing and formatting;
+ *     it supports {@link CharSequence} and {@link Appendable} interfaces 
+ *     for greater flexibility.</p>
+ * 
+ * <p> Instances of this class are typically retrieved from the 
+ *     current {@link TextContext} (OSGi service or not).
+ * [code]
+ * @DefaultTextFormat(Complex.Cartesian.class) 
+ * public class Complex extends Number {
+ *     public static Complex valueOf(CharSequence csq) {
+ *         return TextContext.getFormat(Complex.class).parse(csq);
+ *     }
+ *     public String toString() {
+ *         return TextContext.getFormat(Complex.class).format(this);
+ *     }
+ *     public static class Cartesian extends javolution.text.TextFormat<Complex> { ... }
+ *     public static class Polar extends javolution.text.TextFormat<Complex> { ... }
+ * }[/code]</p>
+ * 
+ * <p> Text formats can be locally overridden.
+ * [code]
+ * TextContext ctx = TextContext.enter();
+ * try {
+ *      ctx.setFormat(Complex.class, Complex.Polar.class); // No impact on others threads.
+ *      System.out.println(complexMatrix); // Displays complex numbers in polar coordinates.
+ * } finally {
+ *      ctx.exit(); // Reverts to previous cartesian format for complex numbers.
+ * }[/code]</p>
+ *
+ * <p> For parsing/formatting of primitive types, the {@link TypeFormat}
+ *     utility class is recommended.</p>
+ *     
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle </a>
+ * @version 6.0, July 21, 2013
+ */
+@Parallelizable
+public abstract class TextFormat<T> {
+
+    /**
+     * Reads a portion of the specified <code>CharSequence</code> from the
+     * specified cursor position to produce an object. If parsing succeeds, 
+     * then the index of the <code>cursor</code> argument is updated to the 
+     * index after the last character used. 
+     * 
+     * @param csq the character sequence to parse.
+     * @param cursor the cursor holding the current parsing index.
+     * @return the object parsed.
+     * @throws IllegalArgumentException if the syntax of the specified 
+     *         character sequence is incorrect.
+     * @throws UnsupportedOperationException if parsing is not supported.
+     */
+    public abstract T parse(CharSequence csq, Cursor cursor);
+
+    /**
+     * Formats the specified object into an <code>Appendable</code> 
+     * 
+     * @param obj the object to format.
+     * @param dest the appendable destination.
+     * @return the specified <code>Appendable</code>.
+     */
+    public abstract Appendable format(T obj, Appendable dest)
+            throws IOException;
+
+    /**
+     * Convenience method to parse the whole character sequence; if there are 
+     * unread extraneous characters after parsing then an exception is raised.
+     * 
+     * @param csq the <code>CharSequence</code> to parse from the first character
+     *        to the last.
+     * @throws IllegalArgumentException if the syntax of the specified 
+     *         character sequence is incorrect or if there are extraneous
+     *         characters at the end not parsed.
+     */
+    public T parse(CharSequence csq) throws IllegalArgumentException {
+        Cursor cursor = new Cursor();
+        T obj = parse(csq, cursor);
+        if (!cursor.atEnd(csq))
+            throw new IllegalArgumentException("Extraneous character(s) \""
+                    + cursor.tail(csq) + "\"");
+        return obj;
+    }
+
+    /**
+    * Convenience method to format the specified object to a {@link TextBuilder};
+    * unlike the abstract format method, this method does not throw {@link IOException}.
+    * 
+    * @param obj the object to format.
+    * @param dest the appendable destination.
+    * @return the specified <code>TextBuilder</code>.
+    */
+    public TextBuilder format(T obj, TextBuilder dest) {
+        try {
+            this.format(obj, (Appendable) dest);
+            return dest;
+        } catch (IOException e) {
+            throw new Error(e); // Cannot happens.
+        }
+    }
+
+    /**
+     * Convenience method to format the specified object to a {@link String}.
+     * 
+     * @param obj the object to format.
+     * @return the formatting result as a string.
+     */
+    public String format(T obj) {
+        return this.format(obj, new TextBuilder()).toString();
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/text/TypeFormat.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/text/TypeFormat.java b/commons/marmotta-commons/src/ext/java/javolution/text/TypeFormat.java
new file mode 100644
index 0000000..70207ff
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/text/TypeFormat.java
@@ -0,0 +1,732 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.text;
+
+import java.io.IOException;
+import javolution.lang.MathLib;
+import javolution.lang.Realtime;
+
+/**
+ * <p> Utility class to parse {@link CharSequence} into primitive types and 
+ *     to format primitive types into any {@link Appendable}.</p>
+ *
+ * <p> Methods from this class <b>do not create temporary objects</b> and
+ *     are typically faster than standard library methods.</p>
+ *     
+ * <p> The number of digits when formatting floating point numbers can be 
+ *     specified. The default setting for <code>double</code> is 17 digits 
+ *     or even 16 digits when the conversion is lossless back and forth
+ *     (mimic the standard library formatting).</p>
+ * <p>[code]
+ * TypeFormat.format(0.2, a) = "0.2" // 17 or 16 digits (as long as lossless conversion), remove trailing zeros.
+ * TypeFormat.format(0.2, 17, false, false, a) = "0.20000000000000001" // Closest 17 digits number.
+ * TypeFormat.format(0.2, 19, false, false, a) = "0.2000000000000000111" // Closest 19 digits.
+ * TypeFormat.format(0.2, 4, false, false, a) = "0.2" // Fixed-point notation, remove trailing zeros.
+ * TypeFormat.format(0.2, 4, false, true, a) = "0.2000" // Fixed-point notation, fixed number of digits.
+ * TypeFormat.format(0.2, 4, true, false, a) = "2.0E-1" // Scientific notation, remove trailing zeros.  
+ * TypeFormat.format(0.2, 4, true, true, a) = "2.000E-1" // Scientific notation, fixed number of digits.
+ * [/code]</p>        
+ *
+ * <p> For non-primitive objects, formatting is typically performed using 
+ *     specialized {@link TextFormat} instances.</p>
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 5.3, February 15, 2009
+ */
+@Realtime
+public final class TypeFormat {
+
+    /**
+     * Default constructor (forbids derivation).
+     */
+    private TypeFormat() {}
+
+    /////////////
+    // PARSING //
+    /////////////
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a <code>boolean</code> ignoring cases.
+     *
+     * @param csq the character sequence to parse.
+     * @param cursor the cursor position (being maintained).
+     * @return the next boolean value.
+     * @throws IllegalArgumentException if the character sequence from the 
+     *         specified position is different from "true" or "false" ignoring
+     *         cases.
+     */
+    public static boolean parseBoolean(CharSequence csq, Cursor cursor) {
+        int start = cursor.getIndex();
+        int end = csq.length();
+        if ((end >= start + 5)
+                && (csq.charAt(start) == 'f' || csq.charAt(start) == 'F')) { // False.
+            if ((csq.charAt(++start) == 'a' || csq.charAt(start) == 'A')
+                    && (csq.charAt(++start) == 'l' || csq.charAt(start) == 'L')
+                    && (csq.charAt(++start) == 's' || csq.charAt(start) == 'S')
+                    && (csq.charAt(++start) == 'e' || csq.charAt(start) == 'E')) {
+                cursor.increment(5);
+                return false;
+            }
+        } else if ((end >= start + 4)
+                && (csq.charAt(start) == 't' || csq.charAt(start) == 'T')) // True.
+            if ((csq.charAt(++start) == 'r' || csq.charAt(start) == 'R')
+                    && (csq.charAt(++start) == 'u' || csq.charAt(start) == 'U')
+                    && (csq.charAt(++start) == 'e' || csq.charAt(start) == 'E')) {
+                cursor.increment(4);
+                return true;
+            }
+        throw new IllegalArgumentException("Invalid boolean representation");
+    }
+
+    /**
+     * Parses the whole specified character sequence as a <code>boolean</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @return <code>parseBoolean(csq, new Cursor())</code>
+     * @throws IllegalArgumentException if the specified character sequence 
+     *         is different from "true" or "false" ignoring cases.
+     */
+    public static boolean parseBoolean(CharSequence csq) {
+        Cursor cursor = new Cursor();
+        boolean result = parseBoolean(csq, cursor);
+        if (!cursor.atEnd(csq))
+            throw new IllegalArgumentException("Extraneous characters \""
+                    + cursor.tail(csq) + "\"");
+        return result;
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed <code>byte</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>byte</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>byte</code>.
+     */
+    public static byte parseByte(CharSequence csq, int radix, Cursor cursor) {
+        int i = parseInt(csq, radix, cursor);
+        if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE))
+            throw new NumberFormatException("Overflow");
+        return (byte) i;
+    }
+
+    /**
+     * Parses the whole specified character sequence  
+     * as a signed <code>byte</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @return the corresponding <code>byte</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>byte</code> or contains 
+     *         extraneous characters.
+     */
+    public static byte parseByte(CharSequence csq, int radix) {
+        Cursor cursor = new Cursor();
+        byte result = parseByte(csq, radix, cursor);
+        if (!cursor.atEnd(csq))
+            throw new IllegalArgumentException("Extraneous characters \""
+                    + cursor.tail(csq) + "\"");
+        return result;
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed decimal <code>byte</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>byte</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>byte</code>.
+     */
+    public static byte parseByte(CharSequence csq, Cursor cursor) {
+        return parseByte(csq, 10, cursor);
+    }
+
+    /**
+     * Parses the whole specified character sequence as a signed decimal 
+     * <code>byte</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @return <code>parseByte(csq, 10)</code>
+    *  @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>byte</code> or contains 
+     *         extraneous characters.
+     */
+    public static byte parseByte(CharSequence csq) {
+        return parseByte(csq, 10);
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed <code>short</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>short</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>short</code>.
+     */
+    public static short parseShort(CharSequence csq, int radix, Cursor cursor) {
+        int i = parseInt(csq, radix, cursor);
+        if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE))
+            throw new NumberFormatException("Overflow");
+        return (short) i;
+    }
+
+    /**
+     * Parses the whole specified character sequence  
+     * as a signed <code>short</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @return the corresponding <code>short</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>short</code> or contains 
+     *         extraneous characters.
+     */
+    public static short parseShort(CharSequence csq, int radix) {
+        Cursor cursor = new Cursor();
+        short result = parseShort(csq, radix, cursor);
+        if (!cursor.atEnd(csq))
+            throw new IllegalArgumentException("Extraneous characters \""
+                    + cursor.tail(csq) + "\"");
+        return result;
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed decimal <code>short</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>short</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>short</code>.
+     */
+    public static short parseShort(CharSequence csq, Cursor cursor) {
+        return parseShort(csq, 10, cursor);
+    }
+
+    /**
+     * Parses the whole specified character sequence as a signed decimal 
+     * <code>short</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @return <code>parseShort(csq, 10)</code>
+    *  @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>short</code> or contains 
+     *         extraneous characters.
+     */
+    public static short parseShort(CharSequence csq) {
+        return parseShort(csq, 10);
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed <code>int</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>int</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>int</code>.
+     */
+    public static int parseInt(CharSequence csq, int radix, Cursor cursor) {
+        int start = cursor.getIndex();
+        int end = csq.length();
+        boolean isNegative = false;
+        int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
+        int i = start;
+        for (; i < end; i++) {
+            char c = csq.charAt(i);
+            int digit = (c <= '9') ? c - '0'
+                    : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
+                            : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
+            if ((digit >= 0) && (digit < radix)) {
+                int newResult = result * radix - digit;
+                if (newResult > result)
+                    throw new NumberFormatException("Overflow parsing "
+                            + csq.subSequence(start, end));
+                result = newResult;
+            } else if ((c == '-') && (i == start))
+                isNegative = true;
+            else if ((c == '+') && (i == start)) {
+                // Ok.
+            } else
+                break;
+        }
+        // Requires one valid digit character and checks for opposite overflow.
+        if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
+            throw new NumberFormatException(
+                    "Invalid integer representation for "
+                            + csq.subSequence(start, end));
+        if ((result == Integer.MIN_VALUE) && !isNegative)
+            throw new NumberFormatException("Overflow parsing "
+                    + csq.subSequence(start, end));
+        cursor.increment(i - start);
+        return isNegative ? result : -result;
+    }
+
+    /**
+     * Parses the whole specified character sequence  
+     * as a signed <code>int</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @return the corresponding <code>int</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>int</code> or contains 
+     *         extraneous characters.
+     */
+    public static int parseInt(CharSequence csq, int radix) {
+        Cursor cursor = new Cursor();
+        int result = parseInt(csq, radix, cursor);
+        if (!cursor.atEnd(csq))
+            throw new IllegalArgumentException("Extraneous characters \""
+                    + cursor.tail(csq) + "\"");
+        return result;
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed decimal <code>int</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>int</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>int</code>.
+     */
+    public static int parseInt(CharSequence csq, Cursor cursor) {
+        return parseInt(csq, 10, cursor);
+    }
+
+    /**
+     * Parses the whole specified character sequence as a signed decimal 
+     * <code>int</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @return <code>parseInt(csq, 10)</code>
+    *  @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>int</code> or contains 
+     *         extraneous characters.
+     */
+    public static int parseInt(CharSequence csq) {
+        return parseInt(csq, 10);
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed <code>long</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>long</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>long</code>.
+     */
+    public static long parseLong(CharSequence csq, int radix, Cursor cursor) {
+        final int start = cursor.getIndex();
+        final int end = csq.length();
+        boolean isNegative = false;
+        long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
+        int i = start;
+        for (; i < end; i++) {
+            char c = csq.charAt(i);
+            int digit = (c <= '9') ? c - '0'
+                    : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
+                            : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
+            if ((digit >= 0) && (digit < radix)) {
+                long newResult = result * radix - digit;
+                if (newResult > result)
+                    throw new NumberFormatException("Overflow parsing "
+                            + csq.subSequence(start, end));
+                result = newResult;
+            } else if ((c == '-') && (i == start))
+                isNegative = true;
+            else if ((c == '+') && (i == start)) {
+                // Ok.
+            } else
+                break;
+        }
+        // Requires one valid digit character and checks for opposite overflow.
+        if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
+            throw new NumberFormatException(
+                    "Invalid integer representation for "
+                            + csq.subSequence(start, end));
+        if ((result == Long.MIN_VALUE) && !isNegative)
+            throw new NumberFormatException("Overflow parsing "
+                    + csq.subSequence(start, end));
+        cursor.increment(i - start);
+        return isNegative ? result : -result;
+    }
+
+    /**
+     * Parses the whole specified character sequence  
+     * as a signed <code>long</code> in the specified radix.
+     *
+     * @param  csq the character sequence to parse.
+     * @param  radix the radix to be used while parsing.
+     * @return the corresponding <code>long</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>long</code> or contains 
+     *         extraneous characters.
+     */
+    public static long parseLong(CharSequence csq, int radix) {
+        Cursor cursor = new Cursor();
+        long result = parseLong(csq, radix, cursor);
+        if (!cursor.atEnd(csq))
+            throw new IllegalArgumentException("Extraneous characters \""
+                    + cursor.tail(csq) + "\"");
+        return result;
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a signed decimal <code>long</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @param cursor the cursor position being updated.
+     * @return the corresponding <code>long</code>.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>long</code>.
+     */
+    public static long parseLong(CharSequence csq, Cursor cursor) {
+        return parseLong(csq, 10, cursor);
+    }
+
+    /**
+     * Parses the whole specified character sequence as a signed decimal 
+     * <code>long</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @return <code>parseLong(csq, 10)</code>
+     *  @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>long</code> or contains 
+     *         extraneous characters.
+     */
+    public static long parseLong(CharSequence csq) {
+        return parseLong(csq, 10);
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a <code>float</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @param cursor the cursor position (being maintained) or
+     *        <code>null></code> to parse the whole character sequence.
+     * @return the float number represented by the specified character sequence.
+     */
+    public static float parseFloat(CharSequence csq, Cursor cursor) {
+        return (float) parseDouble(csq, cursor);
+    }
+
+    /**
+     * Parses the whole specified character sequence as a <code>float</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @return the float number represented by the specified character sequence.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>long</code> or contains 
+     *         extraneous characters.
+     */
+    public static float parseFloat(CharSequence csq) {
+        return (float) parseDouble(csq);
+    }
+
+    /**
+     * Parses the specified character sequence from the specified position 
+     * as a <code>double</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @param cursor the cursor position (being maintained) or
+     *        <code>null></code> to parse the whole character sequence.
+     * @return the double number represented by this character sequence.
+     * @throws NumberFormatException if the character sequence does not contain
+     *         a parsable <code>double</code>.
+     */
+    public static double parseDouble(CharSequence csq, Cursor cursor)
+            throws NumberFormatException {
+        final int start = cursor.getIndex();
+        final int end = csq.length();
+        int i = start;
+        char c = csq.charAt(i);
+
+        // Checks for NaN.
+        if ((c == 'N') && match("NaN", csq, i, end)) {
+            cursor.increment(3);
+            return Double.NaN;
+        }
+
+        // Reads sign.
+        boolean isNegative = (c == '-');
+        if ((isNegative || (c == '+')) && (++i < end))
+            c = csq.charAt(i);
+
+        // Checks for Infinity.
+        if ((c == 'I') && match("Infinity", csq, i, end)) {
+            cursor.increment(i + 8 - start);
+            return isNegative ? Double.NEGATIVE_INFINITY
+                    : Double.POSITIVE_INFINITY;
+        }
+
+        // At least one digit or a '.' required.
+        if (((c < '0') || (c > '9')) && (c != '.'))
+            throw new NumberFormatException("Digit or '.' required");
+
+        // Reads decimal and fraction (both merged to a long).
+        long decimal = 0;
+        int decimalPoint = -1;
+        while (true) {
+            int digit = c - '0';
+            if ((digit >= 0) && (digit < 10)) {
+                long tmp = decimal * 10 + digit;
+                if ((decimal > LONG_MAX_DIV10) || (tmp < decimal))
+                    throw new NumberFormatException(
+                            "Too many digits - Overflow");
+                decimal = tmp;
+            } else if ((c == '.') && (decimalPoint < 0))
+                decimalPoint = i;
+            else
+                break;
+            if (++i >= end)
+                break;
+            c = csq.charAt(i);
+        }
+        if (isNegative)
+            decimal = -decimal;
+        int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
+
+        // Reads exponent.
+        int exp = 0;
+        if ((i < end) && ((c == 'E') || (c == 'e'))) {
+            c = csq.charAt(++i);
+            boolean isNegativeExp = (c == '-');
+            if ((isNegativeExp || (c == '+')) && (++i < end))
+                c = csq.charAt(i);
+            if ((c < '0') || (c > '9')) // At least one digit required.  
+                throw new NumberFormatException("Invalid exponent");
+            while (true) {
+                int digit = c - '0';
+                if ((digit >= 0) && (digit < 10)) {
+                    int tmp = exp * 10 + digit;
+                    if ((exp > INT_MAX_DIV10) || (tmp < exp))
+                        throw new NumberFormatException("Exponent Overflow");
+                    exp = tmp;
+                } else
+                    break;
+                if (++i >= end)
+                    break;
+                c = csq.charAt(i);
+            }
+            if (isNegativeExp)
+                exp = -exp;
+        }
+        cursor.increment(i - start);
+        return javolution.lang.MathLib.toDoublePow10(decimal, exp
+                - fractionLength);
+    }
+    private static final int INT_MAX_DIV10 = Integer.MAX_VALUE / 10;
+    private static final long LONG_MAX_DIV10 = Long.MAX_VALUE / 10;
+    
+    /**
+     * Parses the whole specified character sequence as a <code>double</code>.
+     * The format must be of the form:<code>
+     * &lt;decimal&gt;{'.'&lt;fraction&gt;}{'E|e'&lt;exponent&gt;}</code>.
+     *
+     * @param  csq the character sequence to parse.
+     * @return the double number represented by this character sequence.
+     * @throws NumberFormatException if the specified character sequence
+     *         does not contain a parsable <code>long</code> or contains 
+     *         extraneous characters.
+     */
+    public static double parseDouble(CharSequence csq)
+            throws NumberFormatException {
+        Cursor cursor = new Cursor();
+        double result = parseDouble(csq, cursor);
+        if (!cursor.atEnd(csq))
+            throw new IllegalArgumentException("Extraneous characters \""
+                    + cursor.tail(csq) + "\"");
+        return result;
+    }
+
+    static boolean match(String str, CharSequence csq, int start, int length) {
+        for (int i = 0; i < str.length(); i++) {
+            if ((start + i >= length) || csq.charAt(start + i) != str.charAt(i))
+                return false;
+        }
+        return true;
+    }
+
+    static boolean match(String str, String csq, int start, int length) {
+        for (int i = 0; i < str.length(); i++) {
+            if ((start + i >= length) || csq.charAt(start + i) != str.charAt(i))
+                return false;
+        }
+        return true;
+    }
+
+    ////////////////
+    // FORMATTING //
+    ////////////////
+    /**
+     * Formats the specified <code>boolean</code> and appends the resulting
+     * text to the <code>Appendable</code> argument.
+     *
+     * @param  b a <code>boolean</code>.
+     * @param  a the <code>Appendable</code> to append.
+     * @return the specified <code>StringBuffer</code> object.
+     * @throws IOException if an I/O exception occurs.
+     */
+    public static Appendable format(boolean b, Appendable a) throws IOException {
+        return b ? a.append("true") : a.append("false");
+    }
+
+    /**
+     * Formats the specified <code>int</code> and appends the resulting
+     * text (decimal representation) to the <code>Appendable</code> argument.
+     *
+     *
+     * @param  i the <code>int</code> number.
+     * @param  a the <code>Appendable</code> to append.
+     * @return the specified <code>Appendable</code> object.
+     * @throws IOException if an I/O exception occurs.
+     */
+    public static Appendable format(int i, Appendable a) throws IOException {
+        if (a instanceof TextBuilder)
+            return ((TextBuilder) a).append(i);
+        TextBuilder tb = new TextBuilder();
+        tb.append(i);
+        return a.append(tb);
+    }
+
+    /**
+     * Formats the specified <code>int</code> in the specified radix and appends
+     * the resulting text to the <code>Appendable</code> argument.
+     *
+     * @param  i the <code>int</code> number.
+     * @param  radix the radix.
+     * @param  a the <code>Appendable</code> to append.
+     * @return the specified <code>Appendable</code> object.
+     * @throws IllegalArgumentException if radix is not in [2 .. 36] range.
+     * @throws IOException if an I/O exception occurs.
+     */
+    public static Appendable format(int i, int radix, Appendable a)
+            throws IOException {
+        if (a instanceof TextBuilder)
+            return ((TextBuilder) a).append(i, radix);
+        TextBuilder tb = new TextBuilder();
+        tb.append(i, radix);
+        return a.append(tb);
+    }
+
+    /**
+     * Formats the specified <code>long</code> and appends the resulting
+     * text (decimal representation) to the <code>Appendable</code> argument.
+     *
+     * @param  l the <code>long</code> number.
+     * @param  a the <code>Appendable</code> to append.
+     * @return the specified <code>Appendable</code> object.
+     * @throws IOException if an I/O exception occurs.
+     * @see    #parseLong
+     */
+    public static Appendable format(long l, Appendable a) throws IOException {
+        if (a instanceof TextBuilder)
+            return ((TextBuilder) a).append(l);
+        TextBuilder tb = new TextBuilder();
+        tb.append(l);
+        return a.append(tb);
+    }
+
+    /**
+     * Formats the specified <code>long</code> in the specified radix and
+     * appends the resulting text to the <code>Appendable</code> argument.
+     *
+     * @param  l the <code>long</code> number.
+     * @param  radix the radix.
+     * @param  a the <code>Appendable</code> to append.
+     * @return the specified <code>Appendable</code> object.
+     * @throws  IllegalArgumentException if radix is not in [2 .. 36] range.
+     * @throws IOException if an I/O exception occurs.
+     * @see    #parseLong(CharSequence, int)
+     */
+    public static Appendable format(long l, int radix, Appendable a)
+            throws IOException {
+        if (a instanceof TextBuilder)
+            return ((TextBuilder) a).append(l, radix);
+        TextBuilder tb = new TextBuilder();
+        tb.append(l, radix);
+        return a.append(tb);
+    }
+
+    /**
+     * Formats the specified <code>float</code> value.
+     *
+     * @param  f the <code>float</code> value.
+     * @param  a the <code>Appendable</code> to append.
+     * @return <code>TypeFormat.format(f, 10, (MathLib.abs(f) >= 1E7) || (MathLib.abs(f) < 0.001), false, a)</code>
+     * @throws IOException if an I/O exception occurs.
+     */
+    public static Appendable format(float f, Appendable a) throws IOException {
+        return TypeFormat.format(f, 10,
+                (MathLib.abs(f) >= 1E7) || (MathLib.abs(f) < 0.001), false, a);
+    }
+
+    /**
+     * Formats the specified <code>double</code> value (16 or 17 digits output).
+     *
+     * @param  d the <code>double</code> value.
+     * @param  a the <code>Appendable</code> to append.
+     * @return <code>TypeFormat.format(d, -1, (MathLib.abs(d) >= 1E7) || (MathLib.abs(d) < 0.001), false, a)</code>
+     * @throws IOException if an I/O exception occurs.
+     * @see    TextBuilder#append(double)
+     */
+    public static Appendable format(double d, Appendable a) throws IOException {
+        return TypeFormat.format(d, -1,
+                (MathLib.abs(d) >= 1E7) || (MathLib.abs(d) < 0.001), false, a);
+    }
+
+    /**
+     * Formats the specified <code>double</code> value according to the
+     * specified formatting arguments.
+     *
+     * @param  d the <code>double</code> value.
+     * @param  digits the number of significative digits (excludes exponent) or
+     *         <code>-1</code> to mimic the standard library (16 or 17 digits).
+     * @param  scientific <code>true</code> to forces the use of the scientific
+     *         notation (e.g. <code>1.23E3</code>); <code>false</code>
+     *         otherwise.
+     * @param  showZero <code>true</code> if trailing fractional zeros are
+     *         represented; <code>false</code> otherwise.
+     * @param  a the <code>Appendable</code> to append.
+     * @return the specified <code>Appendable</code> object.
+     * @throws IllegalArgumentException if <code>(digits &gt; 19)</code>)
+     * @throws IOException if an I/O exception occurs.
+     * @see    TextBuilder#append(double, int, boolean, boolean)
+     */
+    public static Appendable format(double d, int digits, boolean scientific,
+            boolean showZero, Appendable a) throws IOException {
+        if (a instanceof TextBuilder)
+            return ((TextBuilder) a).append(d, digits, scientific, showZero);
+        TextBuilder tb = new TextBuilder();
+        tb.append(d, digits, scientific, showZero);
+        return a.append(tb);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/text/internal/TextContextImpl.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/text/internal/TextContextImpl.java b/commons/marmotta-commons/src/ext/java/javolution/text/internal/TextContextImpl.java
new file mode 100644
index 0000000..9e92f81
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/text/internal/TextContextImpl.java
@@ -0,0 +1,345 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.text.internal;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import javolution.context.LogContext;
+import javolution.text.CharSet;
+import javolution.text.Cursor;
+import javolution.text.DefaultTextFormat;
+import javolution.text.TextContext;
+import javolution.text.TextFormat;
+import javolution.text.TypeFormat;
+import javolution.util.FastMap;
+
+/**
+ * Holds the default implementation of TextContext.
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 6.0, July 21, 2013
+ */
+public final class TextContextImpl extends TextContext {
+
+    private static final TextFormat<?> OBJECT_FORMAT = new TextFormat<Object>() {
+        ThreadLocal<Object> objToString = new ThreadLocal<Object>();
+
+        public Appendable format(Object obj, Appendable dest)
+                throws IOException {
+            if (obj == null) return dest.append("null");
+            if (objToString.get() == obj) // Circularity in toString !
+            return TypeFormat.format(System.identityHashCode(obj),
+                    dest.append("Object#"));
+            objToString.set(obj);
+            try {
+                String str = obj.toString();
+                return dest.append(str);
+            } finally {
+                objToString.set(null);
+            }
+        }
+
+        public Object parse(CharSequence csq, Cursor cursor) {
+            throw new UnsupportedOperationException(
+                    "Generic object parsing not supported.");
+        }
+
+    };
+    // Holds class->format local mapping. 
+    private final FastMap<Class<?>, TextFormat<?>> localFormats;
+
+    // Caches class->format from class annotations. 
+    private final FastMap<Class<?>, TextFormat<?>> defaultFormats;
+
+    /** Default constructor for root */
+    public TextContextImpl() {
+        localFormats = new FastMap<Class<?>, TextFormat<?>>(); // Updated only during configuration.
+        defaultFormats = new FastMap<Class<?>, TextFormat<?>>().shared(); // Can be updated concurrently.
+        storePrimitiveTypesFormats();
+    }
+
+    /** Inner constructor */
+    public TextContextImpl(TextContextImpl parent) {
+        localFormats = new FastMap<Class<?>, TextFormat<?>>()
+                .putAll(parent.localFormats);
+        defaultFormats = parent.defaultFormats;
+    }
+
+    @Override
+    protected TextContext inner() {
+        return new TextContextImpl(this);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected <T> TextFormat<T> searchFormat(Class<? extends T> type) {
+        Class<?> cls = type;
+        while (cls != null) {
+            TextFormat<?> format;
+            // Search local format first.
+            if (localFormats.size() > 0) {
+                format = localFormats.get(cls);
+                if (format != null) return (TextFormat<T>) format;
+            }
+            // Then search default format.
+            format = defaultFormats.get(cls);
+            if (format != null) return (TextFormat<T>) format;
+
+            // Search annotations.
+            DefaultTextFormat annotation = cls
+                    .getAnnotation(DefaultTextFormat.class);
+            if (annotation != null) { // Found it.
+                try {
+                    format = annotation.value().newInstance();
+                } catch (Throwable error) {
+                    LogContext.warning(error);
+                }
+                // Updates the default mapping.
+                Class<?> mappedClass = type;
+                while (true) {
+                    defaultFormats.put(mappedClass, format);
+                    if (mappedClass.equals(cls)) break;
+                    mappedClass = mappedClass.getSuperclass();
+                }
+                return (TextFormat<T>) format;
+            }
+
+            // Search superclass.
+            cls = cls.getSuperclass();
+        }
+        throw new Error("Object default format not found !");
+    }
+
+    @Override
+    public <T> void setFormat(Class<? extends T> type, TextFormat<T> format) {
+        localFormats.put(type, format);
+    }
+
+    ////////////////////////
+    // PREDEFINED FORMATS //
+    ////////////////////////
+
+    private void storePrimitiveTypesFormats() {
+        defaultFormats.put(Object.class, OBJECT_FORMAT);
+        defaultFormats.put(Boolean.class, new TextFormat<Boolean>() {
+
+            public Appendable format(Boolean obj, Appendable dest)
+                    throws IOException {
+                return TypeFormat.format(obj.booleanValue(), dest);
+            }
+
+            public Boolean parse(CharSequence csq, Cursor cursor) {
+                return TypeFormat.parseBoolean(csq, cursor);
+            }
+
+        });
+        defaultFormats.put(Character.class, new TextFormat<Character>() {
+
+            public Appendable format(Character obj, Appendable dest)
+                    throws IOException {
+                return dest.append(obj.charValue());
+            }
+
+            public Character parse(CharSequence csq, Cursor cursor) {
+                return Character.valueOf(cursor.nextChar(csq));
+            }
+
+        });
+        defaultFormats.put(Byte.class, new TextFormat<Byte>() {
+
+            public Appendable format(Byte obj, Appendable dest)
+                    throws IOException {
+                return TypeFormat.format(obj.byteValue(), dest);
+            }
+
+            public Byte parse(CharSequence csq, Cursor cursor) {
+                return Byte.valueOf(TypeFormat.parseByte(csq, 10, cursor));
+            }
+
+        });
+        defaultFormats.put(Short.class, new TextFormat<Short>() {
+
+            public Appendable format(Short obj, Appendable dest)
+                    throws IOException {
+                return TypeFormat.format(obj.shortValue(), dest);
+            }
+
+            public Short parse(CharSequence csq, Cursor cursor) {
+                return Short.valueOf(TypeFormat.parseShort(csq, 10, cursor));
+            }
+
+        });
+        defaultFormats.put(Integer.class, new TextFormat<Integer>() {
+
+            public Appendable format(Integer obj, Appendable dest)
+                    throws IOException {
+                return TypeFormat.format(obj.intValue(), dest);
+            }
+
+            public Integer parse(CharSequence csq, Cursor cursor) {
+                return Integer.valueOf(TypeFormat.parseInt(csq, 10, cursor));
+            }
+
+        });
+        defaultFormats.put(Long.class, new TextFormat<Long>() {
+
+            public Appendable format(Long obj, Appendable dest)
+                    throws IOException {
+                return TypeFormat.format(obj.longValue(), dest);
+            }
+
+            public Long parse(CharSequence csq, Cursor cursor) {
+                return Long.valueOf(TypeFormat.parseLong(csq, 10, cursor));
+            }
+
+        });
+        defaultFormats.put(Float.class, new TextFormat<Float>() {
+
+            public Appendable format(Float obj, Appendable dest)
+                    throws IOException {
+                return TypeFormat.format(obj.floatValue(), dest);
+            }
+
+            public Float parse(CharSequence csq, Cursor cursor) {
+                return new Float(TypeFormat.parseFloat(csq, cursor));
+            }
+
+        });
+        defaultFormats.put(Double.class, new TextFormat<Double>() {
+
+            public Appendable format(Double obj, Appendable dest)
+                    throws IOException {
+                return TypeFormat.format(obj.doubleValue(), dest);
+            }
+
+            public Double parse(CharSequence csq, Cursor cursor) {
+                return new Double(TypeFormat.parseDouble(csq, cursor));
+            }
+
+        });
+        defaultFormats.put(String.class, new TextFormat<String>() {
+
+            public Appendable format(String obj, Appendable dest)
+                    throws IOException {
+                return dest.append(obj);
+            }
+
+            public String parse(CharSequence csq, Cursor cursor) {
+                CharSequence tmp = csq.subSequence(cursor.getIndex(),
+                        csq.length());
+                cursor.setIndex(csq.length());
+                return tmp.toString();
+            }
+
+        });
+        defaultFormats.put(Class.class, new TextFormat<Class<?>>() {
+
+            public Appendable format(Class<?> obj, Appendable dest)
+                    throws IOException {
+                return dest.append(obj.getName());
+            }
+
+            public Class<?> parse(CharSequence csq, Cursor cursor) {
+                CharSequence name = cursor.nextToken(csq, CharSet.WHITESPACES);
+                try {
+                    return Class.forName(name.toString());
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalArgumentException("Class " + name
+                            + " Not Found");
+                }
+            }
+
+        });
+        defaultFormats.put(Date.class, new TextFormat<Date>() {
+            TimeZone tz = TimeZone.getTimeZone("UTC");
+            DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
+            {
+                df.setTimeZone(tz);
+            }
+
+            public Appendable format(Date obj, Appendable dest)
+                    throws IOException {
+                return dest.append(df.format(obj));
+            }
+
+            public Date parse(CharSequence csq, Cursor cursor) {
+                CharSequence date = cursor.nextToken(csq, CharSet.WHITESPACES);
+                try {
+                    return df.parse(date.toString());
+                } catch (ParseException error) {
+                    throw new IllegalArgumentException(error);
+                }
+            }
+        });
+        defaultFormats.put(BigInteger.class, new TextFormat<BigInteger>() {
+
+            public Appendable format(BigInteger obj, Appendable dest)
+                    throws IOException {
+                return dest.append(obj.toString());
+            }
+
+            public BigInteger parse(CharSequence csq, Cursor cursor) {
+                CharSequence value = cursor.nextToken(csq, CharSet.WHITESPACES);
+                return new BigInteger(value.toString());
+            }
+
+        });
+        defaultFormats.put(BigDecimal.class, new TextFormat<BigDecimal>() {
+
+            public Appendable format(BigDecimal obj, Appendable dest)
+                    throws IOException {
+                return dest.append(obj.toString());
+            }
+
+            public BigDecimal parse(CharSequence csq, Cursor cursor) {
+                CharSequence value = cursor.nextToken(csq, CharSet.WHITESPACES);
+                return new BigDecimal(value.toString());
+            }
+
+        });
+        defaultFormats.put(Font.class, new TextFormat<Font>() {
+
+            public Appendable format(Font obj, Appendable dest)
+                    throws IOException {
+                return dest.append(obj.getName());
+            }
+
+            public Font parse(CharSequence csq, Cursor cursor) {
+                CharSequence name = cursor.nextToken(csq, CharSet.WHITESPACES);
+                return Font.decode(name.toString());
+            }
+
+        });
+        defaultFormats.put(Color.class, new TextFormat<Color>() {
+
+            public Appendable format(Color obj, Appendable dest)
+                    throws IOException {
+                return dest.append('#').append(
+                        Integer.toHexString(obj.getRGB()));
+            }
+
+            public Color parse(CharSequence csq, Cursor cursor) {
+                CharSequence name = cursor.nextToken(csq, CharSet.WHITESPACES);
+                return Color.decode(name.toString());
+            }
+
+        });
+
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/text/package-info.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/text/package-info.java b/commons/marmotta-commons/src/ext/java/javolution/text/package-info.java
new file mode 100644
index 0000000..3c82f97
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/text/package-info.java
@@ -0,0 +1,67 @@
+/**
+<p> Text handling package.</p>
+<h2><a name="FAQ">FAQ:</a></h2>
+<ol>
+    <a name="FAQ-1"></a>
+    <li><b> Is parsing/formatting of floating-points numbers (e.g. <code>double</code>)
+            equivalent to standard String/Double methods?</b>
+    <p> With Javolution 4.1, <code>double</code> formatting/parsing is lossless 
+        and functionally the same as with the standard library. Parsing a character 
+        sequence will always result in the same number whether it is performed with
+        {@link javolution.text.TypeFormat TypeFormat} or using <code>Double.parseDouble(String))</code>.
+        When formatting a <code>double</code> number, the number of digits output 
+        is adjustable. The default (if the number of digits is unspecified) is <code>17</code> 
+        or <code>16</code> when the the 16 digits representation  can be parsed back to
+        the same <code>double</code> (mimic the standard library formatting).</p>
+    <p> Javolution parsing/formatting do not generate garbage and has no adverse
+        effect on GC. Better, it does not force the user to create intermediate <code>String</code>
+        objects, any <code>CharSequence/Appendable</code> can be used! Serial parsing is also supported 
+        (cursor parameter).</p>
+    <p></p>
+    <a name="FAQ-2"></a>
+    <li><b> I'm accumulating a large string, and all I want to do is 
+append to the end of the current string, which is the better class to use, 
+Text or TextBuilder? Bearing in mind that speed is important, but I also want 
+to conserve memory.</b>
+    <p> It all depends of the size of the text to append (the actual size of the
+         document being appended has almost no impact in both cases).</p>
+    <p> If the text being appended is large (or arbitrarily large) then using 
+        {@link javolution.text.Text Text} is preferable.
+[code]
+class FastCollection<T> {
+     public final Text toText() {
+         // We don't know the length of the text representation for
+         // the collection's elements, we use Text concatenation 
+         // to avoid copying what could be quite large.
+         Text text = Text.valueOf("{");
+         boolean isFirst = true;      
+         for (T e : this) {
+              if (!isFirst) { text = text.plus(", "); isFirst = false; }      
+              text = text.plus(e);
+         }
+         return text.plus("}");
+     }
+}[/code]</p>
+    <p></p>
+    <a name="FAQ-3"></a>
+    <li><b> In our project's use of strings, there are a lot of
+           instances of directory path names, such as
+<code>"/proj/lodecase/src/com/lodecase/util/foo.java"</code>, and
+<code>"/proj/lodecase/src/com/lodecase/util/bar.java"</code>.
+Can the 'Text' class save us memory when strings
+have common prefixes?</b>
+    <p> It depends how you build your text. For example in following code:
+[code]
+Text directoryName = Text.valueOf("/proj/lodecase/src/com/lodecase/util/");
+Text fooFileName = directoryName.plus("foo.java");
+Text barFileName = directoryName.plus("bar.java");[/code]
+        The prefix (directoryName)is shared between <code>fooFileName</code> and <code>barFileName</code>.</p>
+    <p> Text is a binary tree of blocks of characters. In the example,
+        above, <code>fooFileName</code> is a node with <code>directoryName</code> for 
+        head and "foo.java" for tail. The tree is maintained balanced automatically 
+        through <a href="http://en.wikipedia.org/wiki/Tree_rotation">tree rotations</a>.</p>
+    <p></p>
+</ol>
+ */
+package javolution.text;
+

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/util/FastBitSet.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/util/FastBitSet.java b/commons/marmotta-commons/src/ext/java/javolution/util/FastBitSet.java
new file mode 100644
index 0000000..f7c6234
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/util/FastBitSet.java
@@ -0,0 +1,361 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.util;
+
+import static javolution.lang.Realtime.Limit.LINEAR;
+import javolution.lang.Realtime;
+import javolution.util.internal.bitset.BitSetServiceImpl;
+import javolution.util.service.BitSetService;
+
+/**
+ * <p> A high-performance bitset with {@link Realtime real-time} behavior.</p>
+ * 
+ * <p> This class is integrated with the collection framework as 
+ *     a set of {@link Index indices} and obeys the collection semantic
+ *     for methods such as {@link #size} (cardinality) or {@link #equals}
+ *     (same set of indices).</p>
+ *   
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 6.0, July 21, 2013
+ */
+public class FastBitSet extends FastSet<Index> {
+
+    private static final long serialVersionUID = 0x600L; // Version.
+
+    /**
+    * Holds the bit set implementation.
+    */
+    private final BitSetService service;
+
+    /**
+    * Creates an empty bit set.
+    */
+    public FastBitSet() {
+        service = new BitSetServiceImpl();
+    }
+
+    /**
+     * Creates a fast bit set based on the specified implementation.
+     */
+    protected FastBitSet(BitSetService impl) {
+        this.service = impl;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Views.
+    //
+
+    @Override
+    public FastBitSet unmodifiable() {
+        throw new UnsupportedOperationException("NOT DONE YET"); // TODO
+    }
+
+    @Override
+    public FastBitSet shared() {
+        throw new UnsupportedOperationException("NOT DONE YET"); // TODO
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // BitSet Operations.
+    //
+
+    /**
+     * Performs the logical AND operation on this bit set and the
+     * given bit set. This means it builds the intersection
+     * of the two sets. The result is stored into this bit set.
+     *
+     * @param that the second bit set.
+     */
+    @Realtime(limit = LINEAR)
+    public void and(FastBitSet that) {
+        service.and(that.service);
+    }
+
+    /**
+     * Performs the logical AND operation on this bit set and the
+     * complement of the given bit set.  This means it
+     * selects every element in the first set, that isn't in the
+     * second set. The result is stored into this bit set.
+     *
+     * @param that the second bit set
+     */
+    @Realtime(limit = LINEAR)
+    public void andNot(FastBitSet that) {
+        service.andNot(that.service);
+    }
+
+    /**
+     * Returns the number of bits set to {@code true} (or the size of this 
+     * set).
+     *
+     * @return the number of bits being set.
+     */
+    public int cardinality() {
+        return service.cardinality();
+    }
+
+    /**
+     * Sets all bits in the set to {@code false} (empty the set).
+     */
+    @Override
+    public void clear() {
+        service.clear();
+    }
+
+    /**
+     * Removes the specified integer value from this set. That is
+     * the corresponding bit is cleared.
+     *
+     * @param bitIndex a non-negative integer.
+     * @throws IndexOutOfBoundsException if {@code index < 0}
+     */
+    public void clear(int bitIndex) {
+        service.clear(bitIndex);
+    }
+
+    /**
+     * Sets the bits from the specified {@code fromIndex} (inclusive) to the
+     * specified {@code toIndex} (exclusive) to {@code false}.
+     *
+     * @param  fromIndex index of the first bit to be cleared.
+     * @param  toIndex index after the last bit to be cleared.
+     * @throws IndexOutOfBoundsException if 
+     *          {@code (fromIndex < 0) | (toIndex < fromIndex)}
+     */
+    @Realtime(limit = LINEAR)
+    public void clear(int fromIndex, int toIndex) {
+        service.clear(fromIndex, toIndex);
+    }
+
+    /**
+     * Sets the bit at the index to the opposite value.
+     *
+     * @param bitIndex the index of the bit.
+     * @throws IndexOutOfBoundsException if {@code bitIndex < 0}
+     */
+    public void flip(int bitIndex) {
+        service.flip(bitIndex);
+    }
+
+    /**
+     * Sets a range of bits to the opposite value.
+     *
+     * @param fromIndex the low index (inclusive).
+     * @param toIndex the high index (exclusive).
+     * @throws IndexOutOfBoundsException if 
+     *          {@code (fromIndex < 0) | (toIndex < fromIndex)}
+     */
+    @Realtime(limit = LINEAR)
+    public void flip(int fromIndex, int toIndex) {
+        service.flip(fromIndex, toIndex);
+    }
+
+    /**
+     * Returns {@code true } if the specified integer is in 
+     * this bit set; {@code false } otherwise.
+     *
+     * @param bitIndex a non-negative integer.
+     * @return the value of the bit at the specified index.
+     * @throws IndexOutOfBoundsException if {@code bitIndex < 0}
+     */
+    public boolean get(int bitIndex) {
+        return service.get(bitIndex);
+    }
+
+    /**
+     * Returns a new bit set composed of a range of bits from this one.
+     *
+     * @param fromIndex the low index (inclusive).
+     * @param toIndex the high index (exclusive).
+     * @return a context allocated bit set instance.
+     * @throws IndexOutOfBoundsException if 
+     *          {@code (fromIndex < 0) | (toIndex < fromIndex)}
+     */
+    @Realtime(limit = LINEAR)
+    public FastBitSet get(int fromIndex, int toIndex) {
+        return new FastBitSet(service.get(fromIndex, toIndex));
+    }
+
+    /**
+     * Returns {@code true} if this bit set shares at least one
+     * common bit with the specified bit set.
+     *
+     * @param that the bit set to check for intersection
+     * @return {@code true} if the sets intersect; {@code false} otherwise.
+     */
+    @Realtime(limit = LINEAR)
+    public boolean intersects(FastBitSet that) {
+        return service.intersects(that.service);
+    }
+
+    /**
+     * Returns the logical number of bits actually used by this bit
+     * set.  It returns the index of the highest set bit plus one.
+     * 
+     * <p> Note: This method does not return the number of set bits
+     *           which is returned by {@link #size} </p>
+     *
+     * @return the index of the highest set bit plus one.
+     */
+    public int length() {
+        return service.length();
+    }
+
+    /**
+     * Returns the index of the next {@code false} bit, from the specified bit
+     * (inclusive).
+     *
+     * @param fromIndex the start location.
+     * @return the first {@code false} bit.
+     * @throws IndexOutOfBoundsException if {@code fromIndex < 0} 
+     */
+    public int nextClearBit(int fromIndex) {
+        return service.nextClearBit(fromIndex);
+    }
+
+    /**
+     * Returns the index of the next {@code true} bit, from the specified bit
+     * (inclusive). If there is none, {@code -1} is returned. 
+     * The following code will iterates through the bit set:[code]
+     *    for (int i=nextSetBit(0); i >= 0; i = nextSetBit(i+1)) {
+     *         ...
+     *    }[/code]
+     *
+     * @param fromIndex the start location.
+     * @return the first {@code false} bit.
+     * @throws IndexOutOfBoundsException if {@code fromIndex < 0} 
+     */
+    public int nextSetBit(int fromIndex) {
+        return service.nextSetBit(fromIndex);
+    }
+
+    /**
+     * Returns the index of the previous {@code false} bit, 
+     * from the specified bit (inclusive).
+     *
+     * @param fromIndex the start location.
+     * @return the first {@code false} bit.
+     * @throws IndexOutOfBoundsException if {@code fromIndex < -1} 
+     */
+    public int previousClearBit(int fromIndex) {
+        return service.previousClearBit(fromIndex);
+    }
+
+    /**
+     * Returns the index of the previous {@code true} bit, from the 
+     * specified bit (inclusive). If there is none, {@code -1} is returned. 
+     * The following code will iterates through the bit set:[code]
+     *     for (int i = length(); (i = previousSetBit(i-1)) >= 0; ) {
+     *        ...
+     *     }[/code]
+     *
+     * @param fromIndex the start location.
+     * @return the first {@code false} bit.
+     * @throws IndexOutOfBoundsException if {@code fromIndex < -1} 
+     */
+    public int previousSetBit(int fromIndex) {
+        return service.previousSetBit(fromIndex);
+    }
+
+    /**
+     * Performs the logical OR operation on this bit set and the one specified.
+     * In other words, builds the union of the two sets.  
+     * The result is stored into this bit set.
+     *
+     * @param that the second bit set.
+     */
+    @Realtime(limit = LINEAR)
+    public void or(FastBitSet that) {
+        service.or(that.service);
+    }
+
+    /**
+     * Adds the specified integer to this set (corresponding bit is set to 
+     * {@code true}.
+     *
+     * @param bitIndex a non-negative integer.
+     * @throws IndexOutOfBoundsException if {@code bitIndex < 0}
+     */
+    public void set(int bitIndex) {
+        service.set(bitIndex);
+    }
+
+    /**
+     * Sets the bit at the given index to the specified value.
+     *
+     * @param bitIndex the position to set.
+     * @param value the value to set it to.
+     * @throws IndexOutOfBoundsException if {@code bitIndex < 0}
+     */
+    public void set(int bitIndex, boolean value) {
+        service.set(bitIndex, value);
+    }
+
+    /**
+     * Sets the bits from the specified {@code fromIndex} (inclusive) to the
+     * specified {@code toIndex} (exclusive) to {@code true}.
+     *
+     * @param  fromIndex index of the first bit to be set.
+     * @param  toIndex index after the last bit to be set.
+     * @throws IndexOutOfBoundsException if 
+     *          {@code (fromIndex < 0) | (toIndex < fromIndex)}
+     */
+    @Realtime(limit = LINEAR)
+    public void set(int fromIndex, int toIndex) {
+        if ((fromIndex < 0) || (toIndex < fromIndex)) throw new IndexOutOfBoundsException();
+        service.set(fromIndex, toIndex);
+    }
+
+    /**
+     * Sets the bits between from (inclusive) and to (exclusive) to the
+     * specified value.
+     *
+     * @param fromIndex the start range (inclusive).
+     * @param toIndex the end range (exclusive).
+     * @param value the value to set it to.
+     * @throws IndexOutOfBoundsException if {@code bitIndex < 0}
+     */
+    @Realtime(limit = LINEAR)
+    public void set(int fromIndex, int toIndex, boolean value) {
+        service.set(fromIndex, toIndex, value);
+    }
+
+    /**
+     * Performs the logical XOR operation on this bit set and the one specified.
+     * In other words, builds the symmetric remainder of the two sets 
+     * (the elements that are in one set, but not in the other).  
+     * The result is stored into this bit set.
+     *
+     * @param that the second bit set.
+     */
+    @Realtime(limit = LINEAR)
+    public void xor(FastBitSet that) {
+        service.xor(that.service);
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Misc.
+    //
+
+    @Override
+    public FastBitSet addAll(Index... elements) {
+        return (FastBitSet) super.addAll(elements);
+    }
+
+    @Override
+    public FastBitSet addAll(FastCollection<? extends Index> elements) {
+        return (FastBitSet) super.addAll(elements);
+    }
+
+    @Override
+    protected BitSetService service() {
+        return service;
+    }
+
+}