diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/IMessageConveyor.java b/cal10n-api/src/main/java/ch/qos/cal10n/IMessageConveyor.java
index 02abc0e..8314d19 100644
--- a/cal10n-api/src/main/java/ch/qos/cal10n/IMessageConveyor.java
+++ b/cal10n-api/src/main/java/ch/qos/cal10n/IMessageConveyor.java
@@ -29,7 +29,7 @@ import java.text.MessageFormat;
 // which locale to use.
 
 /**
- * Retrieve a localized message by its key as specified by an enum.
+ * Provides access to localized messages based on search keys as specified by an enum.
  * 
  * <p>
  * The strategy in retrieving messages may vary from implementation to
@@ -40,7 +40,7 @@ import java.text.MessageFormat;
 public interface IMessageConveyor {
 
   /**
-   * Retrieve a localized message by its key as specified by an enum.
+   * Retrieves a localized message by its key as specified by an enum.
    * 
    * <p>
    * Note that any further arguments passed in 'args' will be interpolated using
@@ -58,8 +58,7 @@ public interface IMessageConveyor {
   <E extends Enum<?>> String getMessage(E key, Object... args) throws MessageConveyorException;
 
   /**
-   * Syntactic sugar for the case where the massage is contained in a
-   * {@link MessageParameterObj}.
+   * Retrieves a localized message from a {@link MessageParameterObj}.
    * 
    * <p>
    * Equivalent to calling
diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java b/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java
index ff9033e..4a20330 100644
--- a/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java
+++ b/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java
@@ -32,22 +32,34 @@ import ch.qos.cal10n.util.CAL10NResourceBundle;
 import ch.qos.cal10n.util.CAL10NResourceBundleFinder;
 
 /**
- * The default implementation for {@link IMessageConveyor} based on resource
- * bundles.
+ * Provides the default implementation for {@link IMessageConveyor} based on
+ * resource bundles.
  * 
  * <p>
  * See also {@link #getMessage(Enum, Object...)} for details.
  * 
+ * <p>
+ * For efficiency's sake, each instance holds a cache of resource bundles. The
+ * benefit is that the underlying properties files are only ever read once
+ * (unless they are externally changed). However, for the cache to be effective,
+ * it is necessary not to create short-lived <tt>MessageConveyor</tt> instances,
+ * but instead to hold instances that will last for the whole time they will be
+ * needed (typically the lifetime of the application).
+ * 
+ * <p>
+ * Instances can safely be shared between threads.
+ *  
  * @author Ceki G&uuml;lc&uuml;
  */
 public class MessageConveyor implements IMessageConveyor {
 
-	final Locale locale;
+	private final Locale locale;
 
-	final Map<String, CAL10NResourceBundle> cache = new ConcurrentHashMap<String, CAL10NResourceBundle>();
+	private final Map<String, CAL10NResourceBundle> cache = new ConcurrentHashMap<String, CAL10NResourceBundle>();
 
 	/**
-	 * The {@link Locale} associated with this instance.
+	 * Constructs an instance with a {@link Locale} associated with this
+	 * instance.
 	 * 
 	 * @param locale
 	 */
@@ -55,31 +67,18 @@ public class MessageConveyor implements IMessageConveyor {
 		this.locale = locale;
 	}
 
-	/**
-	 * Given an enum as key, find the corresponding resource bundle and return
-	 * the corresponding internationalized.
-	 * 
-	 * <p>
-	 * The name of the resource bundle is defined via the {@link BaseName}
-	 * annotation whereas the locale is specified in this MessageConveyor
-	 * instance's constructor.
-	 * 
-	 * @param key
-	 *            an enum instance used as message key
-	 * 
-	 */
 	public <E extends Enum<?>> String getMessage(E key, Object... args)
 			throws MessageConveyorException {
 
-		String declararingClassName = key.getDeclaringClass().getName();
+		final String declararingClassName = key.getDeclaringClass().getName();
 		CAL10NResourceBundle rb = cache.get(declararingClassName);
 		if (rb == null || rb.hasChanged()) {
-			rb = lookup(key);
+			rb = getBundle(key);
 			cache.put(declararingClassName, rb);
 		}
 
-		String keyAsStr = key.toString();
-		String value = rb.getString(keyAsStr);
+		final String keyAsStr = key.toString();
+		final String value = rb.getString(keyAsStr);
 		if (value == null) {
 			return "No key found for " + keyAsStr;
 		} else {
@@ -91,11 +90,11 @@ public class MessageConveyor implements IMessageConveyor {
 		}
 	}
 
-	private <E extends Enum<?>> CAL10NResourceBundle lookup(E key)
+	private <E extends Enum<?>> CAL10NResourceBundle getBundle(E key)
 			throws MessageConveyorException {
-		Class<?> declaringClass = key.getDeclaringClass();
+		final Class<?> declaringClass = key.getDeclaringClass();
 
-		String baseName = AnnotationExtractor.getBaseName(key
+		final String baseName = AnnotationExtractor.getBaseName(key
 				.getDeclaringClass());
 		if (baseName == null) {
 			throw new MessageConveyorException(
@@ -104,11 +103,11 @@ public class MessageConveyor implements IMessageConveyor {
 							+ Cal10nConstants.MISSING_BN_ANNOTATION_URL);
 		}
 
-		String charset = AnnotationExtractor.getCharset(declaringClass, locale);
+		final String charset = AnnotationExtractor.getCharset(declaringClass, locale);
 		// use the declaring class' loader instead of
 		// this.getClass().getClassLoader()
 		// see also http://jira.qos.ch/browse/CAL-8
-		CAL10NResourceBundle rb = CAL10NResourceBundleFinder.getBundle(
+		final CAL10NResourceBundle rb = CAL10NResourceBundleFinder.getBundle(
 				declaringClass.getClassLoader(), baseName, locale, charset);
 
 		if (rb == null) {
diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundle.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundle.java
index d584cd7..3dc5114 100644
--- a/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundle.java
+++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundle.java
@@ -37,27 +37,25 @@ import java.util.concurrent.ConcurrentHashMap;
  */
 public class CAL10NResourceBundle extends ResourceBundle {
 
-  static long CHECK_DELAY = 10 * 60 * 1000; // 10 minutes delay
+	private static long CHECK_DELAY = 10 * 60 * 1000; // 10 minutes delay
 
-  Map<String, String> map = new ConcurrentHashMap<String, String>();
-  File hostFile;
-  volatile long nextCheck;
-  long lastModified;
-  CAL10NResourceBundle parent;
+	private final Map<String, String> map = new ConcurrentHashMap<String, String>();
+	private File hostFile;
+	private volatile long nextCheck;
+	private long lastModified;
+	private CAL10NResourceBundle parent;
   
-  public CAL10NResourceBundle(Reader r, File file)
-      throws IOException {
+	public CAL10NResourceBundle(Reader r, File file) throws IOException {
     read(r);
     this.hostFile = file;
     nextCheck = System.currentTimeMillis() + CHECK_DELAY;
   }
 
   void read(Reader r) throws IOException {
-    Parser p = new Parser(r, map);
+		final Parser p = new Parser(r, map);
     p.parseAndPopulate();
   }
 
-
   public void setParent(CAL10NResourceBundle parent) {
     this.parent = (parent);
     //super.setParent(parent);
@@ -73,7 +71,7 @@ public class CAL10NResourceBundle extends ResourceBundle {
     if (now < nextCheck) {
       return false;
     } else {
-      nextCheck = now + CHECK_DELAY;
+			nextCheck += CHECK_DELAY;
       if (lastModified != hostFile.lastModified()) {
         lastModified = hostFile.lastModified();
         return true;
@@ -91,11 +89,19 @@ public class CAL10NResourceBundle extends ResourceBundle {
     lastModified = 0;
   } 
 
+	private Hashtable<String, String> getMap() {
+		final Hashtable<String, String> ht = new Hashtable<String, String>(map);
+		if (parent != null) {
+			ht.putAll(parent.getMap());
+		}
+		return ht;
+	}
+
   @Override
   public Enumeration<String> getKeys() {
-    Hashtable<String, String> ht = new Hashtable<String, String>(map);
+		final Hashtable<String, String> ht = getMap();
     if(parent != null) {
-      ht.putAll(parent.map);
+			ht.putAll(parent.getMap());
     }
     return ht.keys();
   }
