Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/Literal.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/Literal.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/Literal.java	(working copy)
@@ -5,6 +5,8 @@
  */
 package org.openrdf.model;
 
+import java.util.Calendar;
+
 /**
  * An RDF literal consisting of a label (the value) and optionally a
  * language tag or a datatype (but not both).
@@ -51,4 +53,61 @@
 	 * @return A hash code for the literal.
 	 */
 	public int hashCode();
+    
+    /**
+     * The bye value of this literal if it can be parsed into a byte.
+     * 
+     * @return the byte value of the literal.
+     */
+    public byte byteValue();
+    
+    /**
+     * The short value of this literal if it can be parsed into a short.
+     * 
+     * @return the short value of the literal.
+     */
+    public short shortValue();
+    
+    /**
+     * The int value of this literal if it can be parsed into an int.
+     * 
+     * @return the int value of the literal.
+     */
+    public int intValue();
+    
+    /**
+     * The long value of this literal if it can be parsed into a long.
+     * 
+     * @return the long value of the literal.
+     */
+    public long longValue();
+    
+    /**
+     * The float value of this literal if it can be parsed into a float.
+     * 
+     * @return the float value of the literal.
+     */
+    public float floatValue();
+    
+    /**
+     * The double value of this literal if it can be parsed into a double.
+     * 
+     * @return the double value of the literal.
+     */
+    public double doubleValue();
+    
+    /**
+     * The boolean value of this literal if it can be parsed into a boolean.
+     * 
+     * @return the long value of the literal.
+     */
+    public boolean booleanValue();
+    
+    /**
+     * The Calendar value of this literal if it can be parsed into a Calendar value.
+     * Note that a Calendar value includes a time zone.
+     * 
+     * @return the Calendar value of the literal.
+     */
+    public Calendar dateTimeValue();
 }
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/ValueFactory.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/ValueFactory.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/ValueFactory.java	(working copy)
@@ -5,6 +5,8 @@
  */
 package org.openrdf.model;
 
+import java.util.Calendar;
+
 /**
  * A factory for creating URIs, blank nodes, literals and statements.
  */
@@ -150,6 +152,16 @@
 	 */
 	public Literal createLiteral(float value);
 
+    /**
+     * Creates a new <tt>xsd:dateTime</tt>-typed literal representing the
+     * specified value.
+     * 
+     * @param value
+     *        The value for the literal
+     * @return An <tt>xsd:dateTime</tt>-typed literal for the specified value.
+     */
+    public Literal createLiteral(Calendar calendar);
+
 	/**
 	 * Creates a new statement with the supplied subject, predicate and object.
 	 * 
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/datatypes/XMLDatatypeUtil.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/datatypes/XMLDatatypeUtil.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/datatypes/XMLDatatypeUtil.java	(working copy)
@@ -8,7 +8,14 @@
 import java.util.StringTokenizer;
 
 
+import org.openrdf.model.Literal;
+import org.openrdf.model.Statement;
 import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.impl.BooleanLiteralImpl;
+import org.openrdf.model.impl.CalendarLiteralImpl;
+import org.openrdf.model.impl.NumericLiteralImpl;
+import org.openrdf.model.impl.StatementImpl;
 import org.openrdf.model.vocabulary.XMLSchema;
 
 /**
@@ -120,6 +127,19 @@
 			datatype.equals(XMLSchema.UNSIGNED_BYTE);
 	}
 
+    /**
+     * Checks whether the supplied datatype is equal to 
+     * xsd:long, xsd:int, xsd:short, or xsd:byte.
+     */
+    public static boolean isJavaIntegerDatatype(URI datatype) {
+        return
+            datatype.equals(XMLSchema.LONG) ||
+            datatype.equals(XMLSchema.INT) ||
+            datatype.equals(XMLSchema.INTEGER) ||
+            datatype.equals(XMLSchema.SHORT) ||
+            datatype.equals(XMLSchema.BYTE);
+    }
+    
 	/**
 	 * Checks whether the supplied datatype is equal to xsd:float or
 	 * xsd:double.
@@ -127,9 +147,29 @@
 	public static boolean isFloatingPointDatatype(URI datatype) {
 		return
 			datatype.equals(XMLSchema.FLOAT) ||
-			datatype.equals(XMLSchema.DOUBLE);
+			datatype.equals(XMLSchema.DOUBLE) ||
+            datatype.equals(XMLSchema.DECIMAL);
 	}
 
+    /**
+     * Checks whether the supplied datatype is equal to 
+     * xsd:double, or xsd:float.
+     */
+    public static boolean isJavaFloatingPointDatatype(URI datatype) {
+        return
+            datatype.equals(XMLSchema.FLOAT) ||
+            datatype.equals(XMLSchema.DOUBLE);
+    }
+    
+    /**
+     * Checks whether the supplied datatype is a native Java 
+     * Number datatype.
+     */
+    public static boolean isJavaNumberDatatype(URI datatype) {
+        return isJavaIntegerDatatype(datatype) ||
+            isJavaFloatingPointDatatype(datatype);
+    }
+    
 	/**
 	 * Checks whether the supplied datatype is equal to xsd:dateTime.
 	 */
@@ -1479,6 +1519,100 @@
 		return dateTime1.compareTo(dateTime2);
 	}
 
+    /*------------------*
+     * Guessing methods *
+     *------------------*/
+    
+    /**
+     * Guesses the datatype of the given literal based on its label and returns a new
+     * literal if the datatype can be guessed, or the same literal otherwise.
+     * 
+     * @param l
+     * @return same or new literal with the guessed datatype
+     */
+    public static Literal guessLiteralDatatype(Literal l) {
+        guess: if (l.getDatatype() == null) {
+            try {
+                l = new NumericLiteralImpl(l.intValue());
+                break guess;
+            }
+            catch (Exception e) {
+                // continue guessing
+            }
+            
+            try {
+                l = new NumericLiteralImpl(l.floatValue());
+                break guess;
+            }
+            catch (Exception e) {
+                // continue guessing
+            }
+            
+            try {
+                l = new NumericLiteralImpl(l.longValue());
+                break guess;
+            }
+            catch (Exception e) {
+                // continue guessing
+            }
+            
+            try {
+                l = new NumericLiteralImpl(l.doubleValue());
+                break guess;
+            }
+            catch (Exception e) {
+                // continue guessing
+            }
+            
+            try {
+                l = new CalendarLiteralImpl(l.dateTimeValue());
+                break guess;
+            }
+            catch (Exception e) {
+                // continue guessing
+            }
+            
+            try {
+                l = new BooleanLiteralImpl(l.booleanValue());
+                break guess;
+            }
+            catch (Exception e) {
+                // continue guessing
+            }
+        }
+        return l;
+    }
+    
+    /**
+     * Guesses the datatype of the given value if based on its label if it's a literal, 
+     * and returns a new literal if the datatype can be guessed, or the same value otherwise.
+     * 
+     * @param v
+     * @return same value or new literal value with the guessed datatype
+     */
+    public static Value guessValueDatatype(Value v) {
+        return v instanceof Literal ? guessLiteralDatatype((Literal) v) : v;
+    }
+    
+    /**
+     * Guesses the datatype of the object of the given statement based on the object's label
+     * if the object is a literal, and returns a new statement with a new literal of that datatype
+     * if the datatype can be guessed, or the same statement otherwise.
+     * 
+     * @param st
+     * @return same or new statement with a new literal object with the guessed datatype
+     */
+    public static Statement guessObjectDatatype(Statement st) {
+        Value object = st.getObject();
+        if (object instanceof Literal) {
+            Value object2 = guessLiteralDatatype((Literal) object);
+            if (object2 != object) {
+                st = new StatementImpl(st.getSubject(), st.getPredicate(), object2);
+            }
+        }
+        return st;
+    }
+    
 	/*-----------------*
 	 * Utility methods *
 	 *-----------------*/
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/datatypes/XMLDateTime.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/datatypes/XMLDateTime.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/datatypes/XMLDateTime.java	(working copy)
@@ -9,6 +9,7 @@
 import java.util.GregorianCalendar;
 import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
+import java.util.TimeZone;
 
 /**
  * This class provides utility functions for comparisons operating on
@@ -480,4 +481,88 @@
 			throw new RuntimeException(e);
 		}
 	}
+    
+    
+    /**
+     * Returns the xsd:dateTime string-representation of the given Calendar object.
+     * 
+     * @return An xsd:dateTime value, e.g. <tt>1999-05-31T13:20:00-05:00</tt>.
+     */
+    static public String calendarToString(Calendar calendar) {
+        StringBuilder sb = new StringBuilder(32);
+        
+        int year = calendar.get(Calendar.YEAR);
+
+        if (year < 0) {
+            sb.append('-');
+            year = -year;
+        }
+        appendStuffing(sb, year, 4);
+        sb.append('-');
+        appendStuffing(sb, calendar.get(Calendar.MONTH) + 1, 2);
+        sb.append('-');
+        appendStuffing(sb, calendar.get(Calendar.DAY_OF_MONTH) + 1, 2);
+        
+        sb.append('T');
+        
+        appendStuffing(sb, calendar.get(Calendar.HOUR_OF_DAY), 2);
+        sb.append(':');
+        appendStuffing(sb, calendar.get(Calendar.MINUTE), 2);
+        sb.append(':');
+        appendStuffing(sb, calendar.get(Calendar.SECOND), 2);
+        sb.append('.');
+        appendStuffing(sb, calendar.get(Calendar.MILLISECOND), 3);
+
+        TimeZone timezone = calendar.getTimeZone();
+        int offset = timezone.getRawOffset();
+        if (offset == 0) {
+            sb.append('Z');
+        } else {
+            offset /= 60000;
+            if (offset < 0) {
+                sb.append('-');
+                offset = -offset;
+            } else {
+                sb.append('+');
+            }
+            
+            appendStuffing(sb, offset / 60, 2);
+            sb.append(':');
+            appendStuffing(sb, offset % 60, 2);
+        }
+
+        return sb.toString();
+    }
+    
+    /**
+     * Parses a string that encodes date/time in ISO 8601 into a Calendar object.
+     * @param s
+     * @return a Calendar object
+     */
+    static public Calendar stringToCalendar(String s) {
+        XMLDateTime dateTime = new XMLDateTime(s);
+        
+        TimeZone timezone = TimeZone.getDefault();
+        timezone.setRawOffset((dateTime._iHoursTimezone * 60 + dateTime._iMinutesTimezone) * 60000);
+        
+        Calendar calendar = Calendar.getInstance(timezone);
+        calendar.set(dateTime._iYear, dateTime._iMonths - 1, dateTime._iDays, dateTime._iHours, dateTime._iMinutes, dateTime._iSeconds);
+        calendar.set(Calendar.MILLISECOND, (int) (dateTime._iFractionalSeconds * 1000));
+        
+        return calendar;
+    }
+
+    static private void appendStuffing(StringBuilder sb, int n, int width) {
+        int factor = 1;
+        int i = 0;
+        while (factor < n && i < width) {
+            factor *= 10;
+            i++;
+        }
+        while (i < width) {
+            sb.append('0');
+            i++;
+        }
+        sb.append(n);
+    }
 }
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/BooleanLiteralImpl.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/BooleanLiteralImpl.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/BooleanLiteralImpl.java	(revision 0)
@@ -0,0 +1,62 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.model.impl;
+
+import java.util.Calendar;
+
+import org.openrdf.model.vocabulary.XMLSchema;
+
+/**
+ * An extension of {@link LiteralImpl} that stores a boolean value to avoid parsing.
+ */
+public class BooleanLiteralImpl extends LiteralImpl {
+    protected boolean _b;
+    
+    public BooleanLiteralImpl(boolean b) {
+        super(Boolean.toString(b), XMLSchema.BOOLEAN);
+        _b = b;
+    }
+    
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        return _b;
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        return (byte) (_b ? 1 : 0);
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        throw new IllegalArgumentException("Cannot parse a byte into a Calendar");
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        return _b ? 1.0 : 0.0;
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        return _b ? 1.0f : 0.0f;
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        return _b ? 1 : 0;
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        return _b ? 1l : 0l;
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        return (short) (_b ? 1 : 0);
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/CalendarLiteralImpl.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/CalendarLiteralImpl.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/CalendarLiteralImpl.java	(revision 0)
@@ -0,0 +1,63 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.model.impl;
+
+import java.util.Calendar;
+
+import org.openrdf.model.datatypes.XMLDateTime;
+import org.openrdf.model.vocabulary.XMLSchema;
+
+/**
+ * An extension of {@link LiteralImpl} that stores a Calendar value to avoid parsing.
+ */
+public class CalendarLiteralImpl extends LiteralImpl {
+    protected Calendar _c;
+    
+    public CalendarLiteralImpl(Calendar c) {
+        super(XMLDateTime.calendarToString(c), XMLSchema.DATETIME);
+        _c = c;
+    }
+    
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        throw new IllegalArgumentException("Cannot cast a Calendar into a boolean");
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a byte");
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        return _c;
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a double");
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a float");
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into an int");
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a long");
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a short");
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/LiteralImpl.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/LiteralImpl.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/LiteralImpl.java	(working copy)
@@ -5,8 +5,13 @@
  */
 package org.openrdf.model.impl;
 
+import java.util.Calendar;
+import java.util.Date;
+
 import org.openrdf.model.Literal;
 import org.openrdf.model.URI;
+import org.openrdf.model.datatypes.XMLDatatypeUtil;
+import org.openrdf.model.datatypes.XMLDateTime;
 
 /**
  * An implementation of the {@link Literal} interface.
@@ -151,4 +156,93 @@
 	public String toString() {
 		return _label;
 	}
+
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        String label = getLabel();
+        label = XMLDatatypeUtil.normalizeBoolean(label);
+        return Boolean.parseBoolean(label);
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        try {
+            String label = getLabel();
+            label = XMLDatatypeUtil.normalizeByte(label);
+            return Byte.parseByte(label);
+        }
+        catch (IllegalArgumentException e) {
+            throw new NumberFormatException(e.getMessage());
+        }
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        return XMLDateTime.stringToCalendar(getLabel());
+    }
+
+    // implements Literal.dateValue()
+    public Date dateValue() {
+        return dateTimeValue().getTime();
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        try {
+            String label = getLabel();
+            label = XMLDatatypeUtil.normalizeDouble(label);
+            return Double.parseDouble(label);
+        }
+        catch (IllegalArgumentException e) {
+            throw new NumberFormatException(e.getMessage());
+        }
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        try {
+            String label = getLabel();
+            label = XMLDatatypeUtil.normalizeFloat(label);
+            return Float.parseFloat(label);
+        }
+        catch (IllegalArgumentException e) {
+            throw new NumberFormatException(e.getMessage());
+        }
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        try {
+            String label = getLabel();
+            label = XMLDatatypeUtil.normalizeInt(label);
+            return Integer.parseInt(label);
+        }
+        catch (IllegalArgumentException e) {
+            throw new NumberFormatException(e.getMessage());
+        }
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        try {
+            String label = getLabel();
+            label = XMLDatatypeUtil.normalizeLong(label);
+            return Long.parseLong(label);
+        }
+        catch (IllegalArgumentException e) {
+            throw new NumberFormatException(e.getMessage());
+        }
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        try {
+            String label = getLabel();
+            label = XMLDatatypeUtil.normalizeShort(label);
+            return Short.parseShort(label);
+        }
+        catch (IllegalArgumentException e) {
+            throw new NumberFormatException(e.getMessage());
+        }
+    }
 }
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/NumericLiteralImpl.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/NumericLiteralImpl.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/NumericLiteralImpl.java	(revision 0)
@@ -0,0 +1,93 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.model.impl;
+
+import java.util.Calendar;
+
+import org.openrdf.model.URI;
+import org.openrdf.model.vocabulary.XMLSchema;
+
+/**
+ * An extension of {@link LiteralImpl} that stores a numeric value to avoid parsing.
+ */
+public class NumericLiteralImpl extends LiteralImpl {
+    protected Number _n;
+    
+    public NumericLiteralImpl(Number n, URI datatype) {
+        super(String.valueOf(n), datatype);
+        _n = n;
+    }
+    
+    public NumericLiteralImpl(byte n) {
+        super(Byte.toString(n), XMLSchema.BYTE);
+        _n = n;
+    }
+    
+    public NumericLiteralImpl(short n) {
+        super(Short.toString(n), XMLSchema.SHORT);
+        _n = n;
+    }
+    
+    public NumericLiteralImpl(int n) {
+        super(Integer.toString(n), XMLSchema.INT);
+        _n = n;
+    }
+    
+    public NumericLiteralImpl(long n) {
+        super(Long.toString(n), XMLSchema.LONG);
+        _n = n;
+    }
+    
+    public NumericLiteralImpl(float n) {
+        super(Float.toString(n), XMLSchema.FLOAT);
+        _n = n;
+    }
+    
+    public NumericLiteralImpl(double n) {
+        super(Double.toString(n), XMLSchema.DOUBLE);
+        _n = n;
+    }
+    
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        throw new IllegalArgumentException("Cannot parse a number into a boolean");
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        return _n.byteValue();
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        throw new IllegalArgumentException("Cannot parse a double into a Calendar");
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        return _n.doubleValue();
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        return _n.floatValue();
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        return _n.intValue();
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        return _n.longValue();
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        return _n.shortValue();
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/ValueFactoryBase.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/ValueFactoryBase.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/ValueFactoryBase.java	(working copy)
@@ -5,8 +5,12 @@
  */
 package org.openrdf.model.impl;
 
+import java.util.Calendar;
+
 import org.openrdf.model.Literal;
+import org.openrdf.model.URI;
 import org.openrdf.model.ValueFactory;
+import org.openrdf.model.datatypes.XMLDateTime;
 import org.openrdf.model.vocabulary.XMLSchema;
 
 /**
@@ -27,12 +31,11 @@
 
 	/**
 	 * Calls
-	 * {@link ValueFactory#createLiteral(java.lang.String,org.openrdf.model.URI}
-	 * with the String-value of the supplied value and {@link XMLSchema#LONG} as
-	 * datatype.
+	 * {@link #createNumericLiteral(java.lang.Number,org.openrdf.model.URI}
+	 * with the supplied value and {@link XMLSchema#LONG} as datatype.
 	 */
 	public Literal createLiteral(long value) {
-		return createLiteral(String.valueOf(value), XMLSchema.LONG);
+        return createNumericLiteral(value, XMLSchema.LONG);
 	}
 
 	/**
@@ -37,12 +40,11 @@
 
 	/**
 	 * Calls
-	 * {@link ValueFactory#createLiteral(java.lang.String,org.openrdf.model.URI}
-	 * with the String-value of the supplied value and {@link XMLSchema#INT} as
-	 * datatype.
+     * {@link #createNumericLiteral(java.lang.Number,org.openrdf.model.URI}
+	 * with the supplied value and {@link XMLSchema#INT} as datatype.
 	 */
 	public Literal createLiteral(int value) {
-		return createLiteral(String.valueOf(value), XMLSchema.INT);
+        return createNumericLiteral(value, XMLSchema.INT);
 	}
 
 	/**
@@ -47,12 +49,11 @@
 
 	/**
 	 * Calls
-	 * {@link ValueFactory#createLiteral(java.lang.String,org.openrdf.model.URI}
-	 * with the String-value of the supplied value and {@link XMLSchema#SHORT} as
-	 * datatype.
+     * {@link #createNumericLiteral(java.lang.Number,org.openrdf.model.URI}
+	 * with the supplied value and {@link XMLSchema#SHORT} as datatype.
 	 */
 	public Literal createLiteral(short value) {
-		return createLiteral(String.valueOf(value), XMLSchema.SHORT);
+        return createNumericLiteral(value, XMLSchema.SHORT);
 	}
 
 	/**
@@ -57,12 +58,11 @@
 
 	/**
 	 * Calls
-	 * {@link ValueFactory#createLiteral(java.lang.String,org.openrdf.model.URI}
-	 * with the String-value of the supplied value and {@link XMLSchema#BYTE} as
-	 * datatype.
+     * {@link #createNumericLiteral(java.lang.Number,org.openrdf.model.URI}
+	 * with the supplied value and {@link XMLSchema#BYTE} as datatype.
 	 */
 	public Literal createLiteral(byte value) {
-		return createLiteral(String.valueOf(value), XMLSchema.BYTE);
+        return createNumericLiteral(value, XMLSchema.BYTE);
 	}
 
 	/**
@@ -67,12 +67,11 @@
 
 	/**
 	 * Calls
-	 * {@link ValueFactory#createLiteral(java.lang.String,org.openrdf.model.URI}
-	 * with the String-value of the supplied value and {@link XMLSchema#DOUBLE}
-	 * as datatype.
+     * {@link #createNumericLiteral(java.lang.Number,org.openrdf.model.URI}
+	 * with the supplied value and {@link XMLSchema#DOUBLE} as datatype.
 	 */
 	public Literal createLiteral(double value) {
-		return createLiteral(String.valueOf(value), XMLSchema.DOUBLE);
+        return createNumericLiteral(value, XMLSchema.DOUBLE);
 	}
 
 	/**
@@ -77,11 +76,24 @@
 
 	/**
 	 * Calls
-	 * {@link ValueFactory#createLiteral(java.lang.String,org.openrdf.model.URI}
-	 * with the String-value of the supplied value and {@link XMLSchema#FLOAT} as
-	 * datatype.
+     * {@link #createNumericLiteral(java.lang.Number,org.openrdf.model.URI}
+	 * with the supplied value and {@link XMLSchema#FLOAT} as datatype.
 	 */
 	public Literal createLiteral(float value) {
-		return createLiteral(String.valueOf(value), XMLSchema.FLOAT);
+		return createNumericLiteral(value, XMLSchema.FLOAT);
 	}
+    
+    /**
+     * Calls
+     * {@link ValueFactory#createLiteral(java.lang.String,org.openrdf.model.URI}
+     * with the String-value of the supplied value and {@link XMLSchema#DATETIME} as
+     * datatype.
+     */
+    public Literal createLiteral(Calendar calendar) {
+        return createLiteral(XMLDateTime.calendarToString(calendar), XMLSchema.DATETIME);
+    }
+    
+    protected Literal createNumericLiteral(Number n, URI datatype) {
+        return new NumericLiteralImpl(n, datatype);
+    }
 }
Index: C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/ValueFactoryImpl.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/ValueFactoryImpl.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-model/src/main/java/org/openrdf/model/impl/ValueFactoryImpl.java	(working copy)
@@ -11,6 +11,8 @@
 import org.openrdf.model.Statement;
 import org.openrdf.model.URI;
 import org.openrdf.model.Value;
+import org.openrdf.model.datatypes.XMLDateTime;
+import org.openrdf.model.vocabulary.XMLSchema;
 
 /**
  * Default implementation of the ValueFactory interface that uses the RDF model
@@ -77,6 +79,37 @@
 
 	// Implements ValueFactory.createLiteral(String, URI)
 	public Literal createLiteral(String value, URI datatype) {
+        if (datatype != null) {
+            try {
+                if (datatype.equals(XMLSchema.BYTE)) {
+                    return new NumericLiteralImpl(Byte.parseByte(value), datatype);
+                }
+                else if (datatype.equals(XMLSchema.SHORT)) {
+                    return new NumericLiteralImpl(Short.parseShort(value), datatype);
+                }
+                else if (datatype.equals(XMLSchema.INT) || datatype.equals(XMLSchema.INTEGER)) {
+                    return new NumericLiteralImpl(Integer.parseInt(value), datatype);
+                }
+                else if (datatype.equals(XMLSchema.LONG)) {
+                    return new NumericLiteralImpl(Long.parseLong(value), datatype);
+                }
+                else if (datatype.equals(XMLSchema.FLOAT)) {
+                    return new NumericLiteralImpl(Float.parseFloat(value), datatype);
+                }
+                else if (datatype.equals(XMLSchema.DOUBLE) || datatype.equals(XMLSchema.DECIMAL)) {
+                    return new NumericLiteralImpl(Double.parseDouble(value), datatype);
+                }
+                else if (datatype.equals(XMLSchema.BOOLEAN)) {
+                    return new BooleanLiteralImpl(Boolean.parseBoolean(value));
+                }
+                else if (datatype.equals(XMLSchema.DATETIME)) {
+                    return new CalendarLiteralImpl(XMLDateTime.stringToCalendar(value));
+                }
+            }
+            catch (Exception e) {
+                // silent
+            }
+        }
 		return new LiteralImpl(value, datatype);
 	}
 
Index: C:/dev/workspace2/sesame2/openrdf-queryalgebra/openrdf-queryalgebra-evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/EvaluationStrategyImpl.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-queryalgebra/openrdf-queryalgebra-evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/EvaluationStrategyImpl.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-queryalgebra/openrdf-queryalgebra-evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/EvaluationStrategyImpl.java	(working copy)
@@ -31,6 +31,7 @@
 import org.openrdf.model.ValueFactory;
 import org.openrdf.model.datatypes.XMLDatatypeUtil;
 import org.openrdf.model.impl.LiteralImpl;
+import org.openrdf.model.impl.NumericLiteralImpl;
 import org.openrdf.model.vocabulary.XMLSchema;
 import org.openrdf.query.Solution;
 import org.openrdf.query.algebra.And;
@@ -101,9 +102,9 @@
 		EvaluationStrategy {
 
 	private static final Solution EMPTY_SOLUTION = new QuerySolution(0);
+    private static final boolean USE_TYPED_LITERALS = true;
 
-	public static Literal getValue(Literal leftLit, Literal rightLit,
-			Operator op) {
+	public static Literal getValue(Literal leftLit, Literal rightLit, Operator op) {
 		String leftLabel = leftLit.getLabel();
 		URI leftDatatype = leftLit.getDatatype();
 
@@ -109,11 +110,69 @@
 
 		String rightLabel = rightLit.getLabel();
 		URI rightDatatype = rightLit.getDatatype();
+        
+        // Native data types can yield some performance gain.
+        if (USE_TYPED_LITERALS && leftDatatype != null && rightDatatype != null) {
+            URI commonDatatype = null;
+            if (XMLDatatypeUtil.isJavaIntegerDatatype(leftDatatype)) {
+                if (XMLDatatypeUtil.isJavaIntegerDatatype(rightDatatype)) {
+                    commonDatatype = XMLSchema.LONG;
+                } else if (XMLDatatypeUtil.isJavaFloatingPointDatatype(rightDatatype)) {
+                    commonDatatype = XMLSchema.DOUBLE;
+                }
+            }
+            else if (XMLDatatypeUtil.isJavaFloatingPointDatatype(leftDatatype) &&
+                    XMLDatatypeUtil.isJavaNumberDatatype(rightDatatype)) {
+                commonDatatype = XMLSchema.DOUBLE;
+            }
+            
+            if (commonDatatype != null) {
+                if (commonDatatype == XMLSchema.LONG) {
+                    long left = leftLit.longValue();
+                    long right = rightLit.longValue();
+                    
+                    switch (op) {
+                    case PLUS:
+                        return new NumericLiteralImpl(left + right, commonDatatype);
+                    case MINUS:
+                        return new NumericLiteralImpl(left - right, commonDatatype);
+                    case MULTIPLY:
+                        return new NumericLiteralImpl(left * right, commonDatatype);
+                    case DIVIDE:
+                        return new NumericLiteralImpl(left / right, commonDatatype);
+                    case REMAINDER:
+                        return new NumericLiteralImpl(left % right, commonDatatype);
+
+                    default:
+                        throw new IllegalArgumentException("Unknown operator: " + op);
+                    }
+                } else {
+                    double left = leftLit.doubleValue();
+                    double right = rightLit.doubleValue();
+                    
+                    switch (op) {
+                    case PLUS:
+                        return new NumericLiteralImpl(left + right, commonDatatype);
+                    case MINUS:
+                        return new NumericLiteralImpl(left - right, commonDatatype);
+                    case MULTIPLY:
+                        return new NumericLiteralImpl(left * right, commonDatatype);
+                    case DIVIDE:
+                        return new NumericLiteralImpl(left / right, commonDatatype);
+                    case REMAINDER:
+                        return new NumericLiteralImpl(left % right, commonDatatype);
 
-		if (leftDatatype == null
-				|| XMLDatatypeUtil.isIntegerDatatype(leftDatatype)
-				&& rightDatatype == null
-				|| XMLDatatypeUtil.isIntegerDatatype(rightDatatype)) {
+                    default:
+                        throw new IllegalArgumentException("Unknown operator: " + op);
+                    }
+                }
+            }
+        }
+
+		if ((leftDatatype == null
+				|| XMLDatatypeUtil.isIntegerDatatype(leftDatatype)) &&
+			(rightDatatype == null
+				|| XMLDatatypeUtil.isIntegerDatatype(rightDatatype))) {
 			// Both arguments are, or could be, integers. Attempt an integer
 			// operation.
 			try {
@@ -226,7 +285,110 @@
 		String rightLang = rightLit.getLanguage();
 		URI rightDatatype = rightLit.getDatatype();
 
-		// apply type casting if necessary
+        if (USE_TYPED_LITERALS && leftDatatype != null && rightDatatype != null) {
+            URI commonDatatype = null;
+            if (XMLDatatypeUtil.isJavaIntegerDatatype(leftDatatype)) {
+                if (XMLDatatypeUtil.isJavaIntegerDatatype(rightDatatype)) {
+                    commonDatatype = XMLSchema.LONG;
+                } else if (XMLDatatypeUtil.isJavaFloatingPointDatatype(rightDatatype)) {
+                    commonDatatype = XMLSchema.DOUBLE;
+                }
+            }
+            else if (XMLDatatypeUtil.isJavaFloatingPointDatatype(leftDatatype) &&
+                    XMLDatatypeUtil.isJavaNumberDatatype(rightDatatype)) {
+                commonDatatype = XMLSchema.DOUBLE;
+            }
+            else if (XMLDatatypeUtil.isDateTimeDatatype(leftDatatype) &&
+                    XMLDatatypeUtil.isDateTimeDatatype(rightDatatype)) {
+                commonDatatype = XMLSchema.DATETIME;
+            }
+            else if (leftDatatype.equals(XMLSchema.BOOLEAN) &&
+                    rightDatatype.equals(XMLSchema.BOOLEAN)) {
+                commonDatatype = XMLSchema.BOOLEAN;
+            }
+            
+            if (commonDatatype != null) {
+                if (commonDatatype == XMLSchema.LONG) {
+                    long left = leftLit.longValue();
+                    long right = rightLit.longValue();
+                    
+                    switch (operator) {
+                    case LT:
+                        return left < right;
+                    case LE:
+                        return left <= right;
+                    case EQ:
+                        return left == right;
+                    case NE:
+                        return left != right;
+                    case GE:
+                        return left > right;
+                    case GT:
+                        return left >= right;
+                    default:
+                        throw new BooleanExprEvaluationException("Unknown operator: " + operator);
+                    }
+                }
+                else if (commonDatatype == XMLSchema.DOUBLE) {
+                    double left = leftLit.doubleValue();
+                    double right = rightLit.doubleValue();
+                    
+                    switch (operator) {
+                    case LT:
+                        return left < right;
+                    case LE:
+                        return left <= right;
+                    case EQ:
+                        return left == right;
+                    case NE:
+                        return left != right;
+                    case GE:
+                        return left > right;
+                    case GT:
+                        return left >= right;
+                    default:
+                        throw new BooleanExprEvaluationException("Unknown operator: " + operator);
+                    }
+                }
+                else if (commonDatatype == XMLSchema.DATETIME) {
+                    long left = leftLit.dateTimeValue().getTimeInMillis();
+                    long right = rightLit.dateTimeValue().getTimeInMillis();
+                    
+                    switch (operator) {
+                    case LT:
+                        return left < right;
+                    case LE:
+                        return left <= right;
+                    case EQ:
+                        return left == right;
+                    case NE:
+                        return left != right;
+                    case GE:
+                        return left > right;
+                    case GT:
+                        return left >= right;
+                    default:
+                        throw new BooleanExprEvaluationException("Unknown operator: " + operator);
+                    }
+                }
+                else if (commonDatatype == XMLSchema.BOOLEAN) {
+                    boolean left = leftLit.booleanValue();
+                    boolean right = rightLit.booleanValue();
+                    
+                    switch (operator) {
+                    case EQ:
+                        return left == right;
+                    case NE:
+                        return left != right;
+                    default:
+                        throw new BooleanExprEvaluationException(
+                            "Operator " + operator + " not applicable for booleans");
+                    }
+                }
+            }
+        }
+        
+        // apply type casting if necessary
 		if (leftDatatype == null && rightDatatype != null) {
 			// left argument has no datatype, assume it is
 			// of the same datatype as the right argument
Index: C:/dev/workspace2/sesame2/openrdf-repository/openrdf-repository-api/src/main/java/org/openrdf/repository/util/DatatypeGuessingRDFInserter.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-repository/openrdf-repository-api/src/main/java/org/openrdf/repository/util/DatatypeGuessingRDFInserter.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-repository/openrdf-repository-api/src/main/java/org/openrdf/repository/util/DatatypeGuessingRDFInserter.java	(revision 0)
@@ -0,0 +1,23 @@
+package org.openrdf.repository.util;
+
+import org.openrdf.model.Statement;
+import org.openrdf.model.datatypes.XMLDatatypeUtil;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.rio.RDFHandlerException;
+
+public class DatatypeGuessingRDFInserter extends RDFInserter {
+
+    public DatatypeGuessingRDFInserter(RepositoryConnection con) {
+        super(con);
+    }
+
+    @Override
+    public void handleStatement(Statement st) throws RDFHandlerException {
+        _addStatement(
+            st.getSubject(),
+            st.getPredicate(),
+            XMLDatatypeUtil.guessValueDatatype(st.getObject()),
+            st.getContext()
+        );
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-repository/openrdf-repository-api/src/main/java/org/openrdf/repository/util/RDFInserter.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-repository/openrdf-repository-api/src/main/java/org/openrdf/repository/util/RDFInserter.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-repository/openrdf-repository-api/src/main/java/org/openrdf/repository/util/RDFInserter.java	(working copy)
@@ -169,32 +169,40 @@
 	public void handleStatement(Statement st)
 		throws RDFHandlerException
 	{
-		Resource subj = st.getSubject();
-		URI pred = st.getPredicate();
-		Value obj = st.getObject();
-		Resource ctxt = _enforceContext ? _context : st.getContext();
+        _addStatement(
+            st.getSubject(),
+            st.getPredicate(),
+            st.getObject(),
+            st.getContext()
+        );
+	}
+    
+    protected void _addStatement(Resource subj, URI pred, Value obj, Resource ctxt)
+        throws RDFHandlerException
+    {
+        ctxt = _enforceContext ? _context : ctxt;
+        
+        if (!_preserveBNodeIDs) {
+            if (subj instanceof BNode) {
+                subj = _mapBNode((BNode)subj);
+            }
 
-		if (!_preserveBNodeIDs) {
-			if (subj instanceof BNode) {
-				subj = _mapBNode((BNode)subj);
-			}
+            if (obj instanceof BNode) {
+                obj = _mapBNode((BNode)obj);
+            }
 
-			if (obj instanceof BNode) {
-				obj = _mapBNode((BNode)obj);
-			}
+            if (!_enforceContext && ctxt instanceof BNode) {
+                ctxt = _mapBNode((BNode)ctxt);
+            }
+        }
 
-			if (!_enforceContext && ctxt instanceof BNode) {
-				ctxt = _mapBNode((BNode)ctxt);
-			}
-		}
-
-		try {
-			_con.add(subj, pred, obj, ctxt);
-		}
-		catch (RepositoryException e) {
-			throw new RDFHandlerException(e);
-		}
-	}
+        try {
+            _con.add(subj, pred, obj, ctxt);
+        }
+        catch (RepositoryException e) {
+            throw new RDFHandlerException(e);
+        }
+    }
 
 	/**
 	 * Maps the supplied BNode, which comes from the data, to a new BNode object.
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/MemoryStore.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/MemoryStore.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/MemoryStore.java	(working copy)
@@ -910,7 +910,7 @@
 		else if (valueTypeMarker == DATATYPE_LITERAL_MARKER) {
 			String label = dataIn.readUTF();
 			URI datatype = (URI)_readValue(dataIn);
-			return _valueFactory.createLiteral(label, (URI)datatype);
+			return _valueFactory.createLiteral(label, datatype);
 		}
 		else {
 			throw new IOException("Invalid value type marker: " + valueTypeMarker);
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemBooleanLiteral.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemBooleanLiteral.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemBooleanLiteral.java	(revision 0)
@@ -0,0 +1,75 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.sail.memory.model;
+
+import java.util.Calendar;
+
+import org.openrdf.model.vocabulary.XMLSchema;
+
+/**
+ * An extension of MemLiteral that stores a boolean value to avoid parsing.
+ */
+public class MemBooleanLiteral extends MemLiteral {
+
+	/*-----------*
+	 * Variables *
+	 *-----------*/
+
+    private boolean _b;
+
+	/*--------------*
+	 * Constructors *
+	 *--------------*/
+
+    public MemBooleanLiteral(Object creator, boolean b) {
+        super(creator, String.valueOf(b), XMLSchema.BOOLEAN);
+        _b = b;
+    }
+
+	/*---------*
+	 * Methods *
+	 *---------*/
+
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        return _b;
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        return (byte) (_b ? 1 : 0);
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        throw new IllegalArgumentException("Cannot parse a byte into a Calendar");
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        return _b ? 1.0 : 0.0;
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        return _b ? 1.0f : 0.0f;
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        return _b ? 1 : 0;
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        return _b ? 1l : 0l;
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        return (short) (_b ? 1 : 0);
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemCalendarLiteral.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemCalendarLiteral.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemCalendarLiteral.java	(revision 0)
@@ -0,0 +1,76 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.sail.memory.model;
+
+import java.util.Calendar;
+
+import org.openrdf.model.datatypes.XMLDateTime;
+import org.openrdf.model.vocabulary.XMLSchema;
+
+/**
+ * An extension of MemLiteral that stores a Calendar value to avoid parsing.
+ */
+public class MemCalendarLiteral extends MemLiteral {
+
+	/*-----------*
+	 * Variables *
+	 *-----------*/
+
+    protected Calendar _c;
+    
+	/*--------------*
+	 * Constructors *
+	 *--------------*/
+
+    public MemCalendarLiteral(Object creator, Calendar c) {
+        super(creator, XMLDateTime.calendarToString(c), XMLSchema.DATETIME);
+        _c = c;
+    }
+
+	/*---------*
+	 * Methods *
+	 *---------*/
+
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        throw new IllegalArgumentException("Cannot cast a Calendar into a boolean");
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a byte");
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        return _c;
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a double");
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a float");
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into an int");
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a long");
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a short");
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemNumericLiteral.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemNumericLiteral.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemNumericLiteral.java	(revision 0)
@@ -0,0 +1,75 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.sail.memory.model;
+
+import java.util.Calendar;
+
+import org.openrdf.model.URI;
+
+/**
+ * An extension of MemLiteral that stores a numeric value to avoid parsing.
+ */
+public class MemNumericLiteral extends MemLiteral {
+
+	/*-----------*
+	 * Variables *
+	 *-----------*/
+
+    private Number _n;
+
+	/*--------------*
+	 * Constructors *
+	 *--------------*/
+
+    public MemNumericLiteral(Object creator, Number n, URI datatype) {
+        super(creator, String.valueOf(n), datatype);
+        _n = n;
+    }
+
+	/*---------*
+	 * Methods *
+	 *---------*/
+
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        throw new IllegalArgumentException("Cannot parse a number into a boolean");
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        return _n.byteValue();
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        throw new IllegalArgumentException("Cannot parse a double into a Calendar");
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        return _n.doubleValue();
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        return _n.floatValue();
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        return _n.intValue();
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        return _n.longValue();
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        return _n.shortValue();
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemValueFactory.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemValueFactory.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-memory/src/main/java/org/openrdf/sail/memory/model/MemValueFactory.java	(working copy)
@@ -5,6 +5,7 @@
  */
 package org.openrdf.sail.memory.model;
 
+import java.util.Calendar;
 import java.util.Collections;
 import java.util.Set;
 
@@ -15,11 +16,15 @@
 import org.openrdf.model.URI;
 import org.openrdf.model.Value;
 import org.openrdf.model.impl.BNodeImpl;
+import org.openrdf.model.impl.BooleanLiteralImpl;
+import org.openrdf.model.impl.CalendarLiteralImpl;
 import org.openrdf.model.impl.ContextStatementImpl;
 import org.openrdf.model.impl.LiteralImpl;
+import org.openrdf.model.impl.NumericLiteralImpl;
 import org.openrdf.model.impl.StatementImpl;
 import org.openrdf.model.impl.URIImpl;
 import org.openrdf.model.impl.ValueFactoryBase;
+import org.openrdf.model.vocabulary.XMLSchema;
 
 /**
  * A factory for MemValue objects that keeps track of created objects to prevent
@@ -301,8 +306,35 @@
 	public MemLiteral createMemLiteral(Literal literal) {
 		MemLiteral memLiteral = null;
 
-		if (literal.getDatatype() != null) {
-			memLiteral = new MemLiteral(this, literal.getLabel(), literal.getDatatype());
+        URI datatype = literal.getDatatype();
+		if (datatype != null) {
+            if (datatype.equals(XMLSchema.BYTE)) {
+                memLiteral = new MemNumericLiteral(this, literal.byteValue(), datatype);
+            }
+            else if (datatype.equals(XMLSchema.SHORT)) {
+                memLiteral = new MemNumericLiteral(this, literal.shortValue(), datatype);
+            }
+            else if (datatype.equals(XMLSchema.INT) || datatype.equals(XMLSchema.INTEGER)) {
+                memLiteral = new MemNumericLiteral(this, literal.intValue(), datatype);
+            }
+            else if (datatype.equals(XMLSchema.LONG)) {
+                memLiteral = new MemNumericLiteral(this, literal.longValue(), datatype);
+            }
+            else if (datatype.equals(XMLSchema.FLOAT)) {
+                memLiteral = new MemNumericLiteral(this, literal.floatValue(), datatype);
+            }
+            else if (datatype.equals(XMLSchema.DOUBLE) || datatype.equals(XMLSchema.DECIMAL)) {
+                memLiteral = new MemNumericLiteral(this, literal.doubleValue(), datatype);
+            }
+            else if (datatype.equals(XMLSchema.BOOLEAN)) {
+                memLiteral = new MemBooleanLiteral(this, literal.booleanValue());
+            }
+            else if (datatype.equals(XMLSchema.DATETIME)) {
+                memLiteral = new MemCalendarLiteral(this, literal.dateTimeValue());
+            }
+            else {
+                memLiteral = new MemLiteral(this, literal.getLabel(), datatype);
+            }
 		}
 		else if (literal.getLanguage() != null) {
 			memLiteral = new MemLiteral(this, literal.getLabel(), literal.getLanguage());
@@ -389,7 +421,7 @@
 
 	// Implements ValueFactory.createLiteral(String, URI)
 	public Literal createLiteral(String value, URI datatype) {
-		Literal tempLiteral = new LiteralImpl(value, datatype);
+		Literal tempLiteral = new LiteralImpl(value, datatype); // LiteralImpl does the parsing for us
 		MemLiteral memLiteral = getMemLiteral(tempLiteral);
 
 		if (memLiteral == null) {
@@ -399,6 +431,36 @@
 		return memLiteral;
 	}
 
+    // Implements ValueFactory.createLiteral(boolean)
+    public Literal createLiteral(boolean value) {
+        Literal tempLiteral = new BooleanLiteralImpl(value);
+        MemLiteral memLiteral = getMemLiteral(tempLiteral);
+
+        if (memLiteral == null) {
+            memLiteral = new MemBooleanLiteral(this, value);
+            
+            boolean wasNew = _literalRegistry.add(memLiteral);
+            assert wasNew : "Created a duplicate MemLiteral for literal " + tempLiteral;
+        }
+
+        return memLiteral;
+    }
+    
+    // Implements ValueFactory.createLiteral(Calendar)
+    public Literal createLiteral(Calendar calendar) {
+        Literal tempLiteral = new CalendarLiteralImpl(calendar);
+        MemLiteral memLiteral = getMemLiteral(tempLiteral);
+
+        if (memLiteral == null) {
+            memLiteral = new MemCalendarLiteral(this, calendar);
+            
+            boolean wasNew = _literalRegistry.add(memLiteral);
+            assert wasNew : "Created a duplicate MemLiteral for literal " + tempLiteral;
+        }
+
+        return memLiteral;
+    }
+    
 	// Implements ValueFactory.createStatement(Resource, URI, Value)
 	public Statement createStatement(Resource subject, URI predicate, Value object) {
 		return new StatementImpl(subject, predicate, object);
@@ -413,4 +475,19 @@
 			return new ContextStatementImpl(subject, predicate, object, context);
 		}
 	}
+    
+    // Overrides ValueFactoryBase.createNumericLiteral(Number, URI)
+    protected Literal createNumericLiteral(Number n, URI datatype) {
+        Literal tempLiteral = new NumericLiteralImpl(n, datatype);
+        MemLiteral memLiteral = getMemLiteral(tempLiteral);
+
+        if (memLiteral == null) {
+            memLiteral = new MemNumericLiteral(this, n, datatype);
+            
+            boolean wasNew = _literalRegistry.add(memLiteral);
+            assert wasNew : "Created a duplicate MemLiteral for literal " + tempLiteral;
+        }
+
+        return memLiteral;
+    }
 }
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/ValueStore.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/ValueStore.java	(revision 2184)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/ValueStore.java	(working copy)
@@ -7,6 +7,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Calendar;
 
 import info.aduna.concurrent.locks.Lock;
 import info.aduna.concurrent.locks.MultiReadSingleWriteLockManager;
@@ -19,11 +20,16 @@
 import org.openrdf.model.URI;
 import org.openrdf.model.Value;
 import org.openrdf.model.impl.ContextStatementImpl;
+import org.openrdf.model.impl.LiteralImpl;
 import org.openrdf.model.impl.StatementImpl;
 import org.openrdf.model.impl.ValueFactoryBase;
+import org.openrdf.model.vocabulary.XMLSchema;
 import org.openrdf.sail.nativerdf.datastore.DataStore;
 import org.openrdf.sail.nativerdf.model.NativeBNode;
+import org.openrdf.sail.nativerdf.model.NativeBooleanLiteral;
+import org.openrdf.sail.nativerdf.model.NativeCalendarLiteral;
 import org.openrdf.sail.nativerdf.model.NativeLiteral;
+import org.openrdf.sail.nativerdf.model.NativeNumericLiteral;
 import org.openrdf.sail.nativerdf.model.NativeResource;
 import org.openrdf.sail.nativerdf.model.NativeURI;
 import org.openrdf.sail.nativerdf.model.NativeValue;
@@ -585,7 +591,7 @@
 		String label = new String(data, 6 + langLength, data.length - 6 - langLength, "UTF-8");
 
 		if (datatype != null) {
-			return new NativeLiteral(_revision, label, datatype, id);
+            return _getNativeLiteral(new LiteralImpl(label, datatype), id);
 		}
 		else if (lang != null) {
 			return new NativeLiteral(_revision, label, lang, id);
@@ -688,9 +694,20 @@
 
 	// Implements ValueFactory.createLiteral(String, URI)
 	public NativeLiteral createLiteral(String value, URI datatype) {
-		return new NativeLiteral(_revision, value, datatype);
+        // Lets LiteralImpl do the parsing
+        return getNativeLiteral(new LiteralImpl(value, datatype));
 	}
 
+    // Implements ValueFactory.createLiteral(boolean)
+    public Literal createLiteral(boolean value) {
+        return new NativeBooleanLiteral(_revision, value);
+    }
+    
+    // Implements ValueFactory.createLiteral(Calendar)
+    public Literal createLiteral(Calendar calendar) {
+        return new NativeCalendarLiteral(_revision, calendar);
+    }
+    
 	// Implements ValueFactory.createStatement(Resource, URI, Value)
 	public Statement createStatement(Resource subject, URI predicate, Value object) {
 		return new StatementImpl(subject, predicate, object);
@@ -700,7 +717,12 @@
 	public Statement createStatement(Resource subject, URI predicate, Value object, Resource context) {
 		return new ContextStatementImpl(subject, predicate, object, context);
 	}
-
+    
+    // Overrides ValueFactoryBase.createNumericLiteral(Number, URI)
+    protected Literal createNumericLiteral(Number n, URI datatype) {
+        return new NativeNumericLiteral(_revision, n, datatype);
+    }
+    
 	/*----------------------------------------------------------------------*
 	 * Methods for converting model objects to NativeStore-specific objects * 
 	 *----------------------------------------------------------------------*/
@@ -773,17 +795,47 @@
 			return (NativeLiteral)l;
 		}
 
-		if (l.getLanguage() != null) {
-			return new NativeLiteral(_revision, l.getLabel(), l.getLanguage());
-		}
-		else if (l.getDatatype() != null) {
-			NativeURI datatype = getNativeURI(l.getDatatype());
-			return new NativeLiteral(_revision, l.getLabel(), datatype);
-		}
-		else {
-			return new NativeLiteral(_revision, l.getLabel());
-		}
+        return _getNativeLiteral(l, NativeValue.UNKNOWN_ID);
 	}
+    
+    protected NativeLiteral _getNativeLiteral(Literal l, int id) {
+        if (l.getLanguage() != null) {
+            return new NativeLiteral(_revision, l.getLabel(), l.getLanguage(), id);
+        }
+        else if (l.getDatatype() != null) {
+            NativeURI datatype = getNativeURI(l.getDatatype());
+            if (datatype.equals(XMLSchema.BYTE)) {
+                return new NativeNumericLiteral(_revision, l.byteValue(), datatype, id);
+            }
+            else if (datatype.equals(XMLSchema.SHORT)) {
+                return new NativeNumericLiteral(_revision, l.shortValue(), datatype, id);
+            }
+            else if (datatype.equals(XMLSchema.INT) || datatype.equals(XMLSchema.INTEGER)) {
+                return new NativeNumericLiteral(_revision, l.intValue(), datatype, id);
+            }
+            else if (datatype.equals(XMLSchema.LONG)) {
+                return new NativeNumericLiteral(_revision, l.longValue(), datatype, id);
+            }
+            else if (datatype.equals(XMLSchema.FLOAT)) {
+                return new NativeNumericLiteral(_revision, l.floatValue(), datatype, id);
+            }
+            else if (datatype.equals(XMLSchema.DOUBLE) || datatype.equals(XMLSchema.DECIMAL)) {
+                return new NativeNumericLiteral(_revision, l.doubleValue(), datatype, id);
+            }
+            else if (datatype.equals(XMLSchema.BOOLEAN)) {
+                return new NativeBooleanLiteral(_revision, l.booleanValue(), id);
+            }
+            else if (datatype.equals(XMLSchema.DATETIME)) {
+                return new NativeCalendarLiteral(_revision, l.dateTimeValue(), id);
+            }
+            else {
+                return new NativeLiteral(_revision, l.getLabel(), datatype, id);
+            }
+        }
+        else {
+            return new NativeLiteral(_revision, l.getLabel(), id);
+        }
+    }
 
 	/*--------------------*
 	 * Test/debug methods *
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeBooleanLiteral.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeBooleanLiteral.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeBooleanLiteral.java	(revision 0)
@@ -0,0 +1,81 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.sail.nativerdf.model;
+
+import java.util.Calendar;
+
+import org.openrdf.model.vocabulary.XMLSchema;
+import org.openrdf.sail.nativerdf.ValueStoreRevision;
+
+/**
+ * An extension of NativeLiteral that stores a boolean value to avoid parsing.
+ */
+public class NativeBooleanLiteral extends NativeLiteral {
+
+	/*-----------*
+	 * Variables *
+	 *-----------*/
+
+    private boolean _b;
+
+	/*--------------*
+	 * Constructors *
+	 *--------------*/
+
+    public NativeBooleanLiteral(ValueStoreRevision revision, boolean b) {
+        super(revision, String.valueOf(b), XMLSchema.BOOLEAN);
+        _b = b;
+    }
+
+    public NativeBooleanLiteral(ValueStoreRevision revision, boolean b, int id) {
+        super(revision, String.valueOf(b), XMLSchema.BOOLEAN, id);
+        _b = b;
+    }
+
+	/*---------*
+	 * Methods *
+	 *---------*/
+
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        return _b;
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        return (byte) (_b ? 1 : 0);
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        throw new IllegalArgumentException("Cannot parse a byte into a Calendar");
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        return _b ? 1.0 : 0.0;
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        return _b ? 1.0f : 0.0f;
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        return _b ? 1 : 0;
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        return _b ? 1l : 0l;
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        return (short) (_b ? 1 : 0);
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeCalendarLiteral.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeCalendarLiteral.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeCalendarLiteral.java	(revision 0)
@@ -0,0 +1,82 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.sail.nativerdf.model;
+
+import java.util.Calendar;
+
+import org.openrdf.model.datatypes.XMLDateTime;
+import org.openrdf.model.vocabulary.XMLSchema;
+import org.openrdf.sail.nativerdf.ValueStoreRevision;
+
+/**
+ * An extension of NativeLiteral that stores a Calendar value to avoid parsing.
+ */
+public class NativeCalendarLiteral extends NativeLiteral {
+
+	/*-----------*
+	 * Variables *
+	 *-----------*/
+
+    protected Calendar _c;
+    
+	/*--------------*
+	 * Constructors *
+	 *--------------*/
+
+    public NativeCalendarLiteral(ValueStoreRevision revision, Calendar c) {
+        super(revision, XMLDateTime.calendarToString(c), XMLSchema.DATETIME);
+        _c = c;
+    }
+
+    public NativeCalendarLiteral(ValueStoreRevision revision, Calendar c, int id) {
+        super(revision, XMLDateTime.calendarToString(c), XMLSchema.DATETIME, id);
+        _c = c;
+    }
+
+	/*---------*
+	 * Methods *
+	 *---------*/
+
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        throw new IllegalArgumentException("Cannot cast a Calendar into a boolean");
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a byte");
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        return _c;
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a double");
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a float");
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into an int");
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a long");
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        throw new NumberFormatException("Cannot cast a Calendar into a short");
+    }
+}
Index: C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeNumericLiteral.java
===================================================================
--- C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeNumericLiteral.java	(revision 0)
+++ C:/dev/workspace2/sesame2/openrdf-sail/openrdf-sail-nativerdf/src/main/java/org/openrdf/sail/nativerdf/model/NativeNumericLiteral.java	(revision 0)
@@ -0,0 +1,81 @@
+/*
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
+ *
+ * Licensed under the Aduna BSD-style license.
+ */
+package org.openrdf.sail.nativerdf.model;
+
+import java.util.Calendar;
+
+import org.openrdf.model.URI;
+import org.openrdf.sail.nativerdf.ValueStoreRevision;
+
+/**
+ * An extension of NativeLiteral that stores a numeric value to avoid parsing.
+ */
+public class NativeNumericLiteral extends NativeLiteral {
+
+	/*-----------*
+	 * Variables *
+	 *-----------*/
+
+    private Number _n;
+
+	/*--------------*
+	 * Constructors *
+	 *--------------*/
+
+    public NativeNumericLiteral(ValueStoreRevision revision, Number n, URI datatype) {
+        super(revision, String.valueOf(n), datatype);
+        _n = n;
+    }
+
+    public NativeNumericLiteral(ValueStoreRevision revision, Number n, URI datatype, int id) {
+        super(revision, String.valueOf(n), datatype, id);
+        _n = n;
+    }
+    
+	/*---------*
+	 * Methods *
+	 *---------*/
+
+    // implements Literal.booleanValue()
+    public boolean booleanValue() {
+        throw new IllegalArgumentException("Cannot parse a number into a boolean");
+    }
+
+    // implements Literal.byteValue()
+    public byte byteValue() {
+        return _n.byteValue();
+    }
+
+    // implements Literal.calendarValue()
+    public Calendar dateTimeValue() {
+        throw new IllegalArgumentException("Cannot parse a double into a Calendar");
+    }
+
+    // implements Literal.doubleValue()
+    public double doubleValue() {
+        return _n.doubleValue();
+    }
+
+    // implements Literal.floatValue()
+    public float floatValue() {
+        return _n.floatValue();
+    }
+
+    // implements Literal.intValue()
+    public int intValue() {
+        return _n.intValue();
+    }
+
+    // implements Literal.longValue()
+    public long longValue() {
+        return _n.longValue();
+    }
+
+    // implements Literal.shortValue()
+    public short shortValue() {
+        return _n.shortValue();
+    }
+}
