Index: src/work/klao/error.h
===================================================================
--- src/work/klao/error.h	(revision 1068)
+++ src/work/klao/error.h	(revision 1120)
@@ -103,42 +103,50 @@
    */
   class Exception : public std::exception {
-  protected:
-    ///\e
-    const char *message;
-
-  public:
-    ///\e 
-    Exception() throw() : message(0) {}
-    ///\e 
-    explicit Exception(const char *msg) throw()
-      : message(msg) {}
+  public:
+    ///\e 
+    Exception() {}
     ///\e 
     virtual ~Exception() throw() {}
+
+    ///\e
+    virtual const char* exceptionName() const {
+      return "lemon::Exception";
+    }
     
     ///\e 
     virtual const char* what() const throw() {
-      if( message ) return message;
-      return "lemon::Exception";
-    }
-  };
-
-  ///\e 
+      return exceptionName();
+    }
+  };
+
+  /**
+   * \brief One of the two main subclasses of \ref Exception.
+   *
+   * Logic errors represent problems in the internal logic of a program;
+   * in theory, these are preventable, and even detectable before the
+   * program runs (e.g., violations of class invariants).
+   *
+   * For a typical example \see UninitializedParameterError.
+   */
   class LogicError : public Exception {
   public:
-    ///\e 
-    explicit LogicError() {}
-    ///\e 
-    explicit LogicError(const char *s)
-      : Exception(s) {}
-  };
-
-  ///\e 
+    virtual const char* exceptionName() const {
+      return "lemon::LogicError";
+    }
+  };
+
+  
+  /**
+   * \brief One of the two main subclasses of \ref Exception.
+   *
+   * Runtime errors represent problems outside the scope of a program;
+   * they cannot be easily predicted and can generally only be caught as
+   * the program executes.
+   */
   class RuntimeError : public Exception {
   public:
-    ///\e
-    explicit RuntimeError() {}
-    ///\e
-    explicit RuntimeError(const char *s)
-      : Exception(s) {}
+    virtual const char* exceptionName() const {
+      return "lemon::RuntimeError";
+    }
   };
 
@@ -146,7 +154,7 @@
   class RangeError : public RuntimeError {
   public:
-    ///\e 
-    explicit RangeError(const char *s)
-      : RuntimeError(s) {}
+    virtual const char* exceptionName() const {
+      return "lemon::RangeError";
+    }
   };
 
@@ -154,7 +162,7 @@
   class IOError : public RuntimeError {
   public:
-    ///\e 
-    explicit IOError(const char *s)
-      : RuntimeError(s) {}
+    virtual const char* exceptionName() const {
+      return "lemon::IOError";
+    }
   };
 
@@ -162,38 +170,43 @@
   class DataFormatError : public IOError {
   protected:
-    int line;
-    boost::shared_ptr<std::string> file;
-
-  public:
-    ///\e 
-    explicit DataFormatError(const char *message)
-      : IOError(message), line(0) {}
+    const char *_message;
+    int _line;
+    boost::shared_ptr<std::string> _file;
+
+  public:
+    ///\e 
+    explicit DataFormatError(const char *the_message)
+      : _message(the_message), _line(0) {}
     ///\e 
     DataFormatError(const std::string &file_name, int line_num,
-		    const char *message)
-      : IOError(message), line(line_num) { set_file(file_name); }
-
-    ///\e 
-    void set_line(int line_num) { line=line_num; }
-    ///\e 
-    void set_file(const std::string &file_name) {
-      try {
-	file.reset(new std::string);
-	*file = file_name;
+		    const char *the_message)
+      : _message(the_message), _line(line_num) { file(file_name); }
+
+    ///\e 
+    void line(int line_num) { _line=line_num; }
+    ///\e 
+    void message(char *the_message) { _message=the_message; }
+    ///\e 
+    void file(const std::string &file_name) {
+      try {
+	_file.reset(new std::string);
+	*_file = file_name;
       }
       catch(...) {
-	file.reset();
-      }
-    }
-
-    ///\e
-    int get_line() const { return line; }
+	_file.reset();
+      }
+    }
+
+    ///\e
+    int line() const { return _line; }
+    ///\e
+    const char* message() const { return _message; }
 
     /// \brief Returns the filename.
     ///
     /// Returns \e "(unknown)" if the filename was not specified.
-    const char* get_file() const {
-      if( file )
-	return file->c_str();
+    const char* file() const {
+      if( _file )
+	return _file->c_str();
       else
 	return "(unknown)";
@@ -205,10 +218,10 @@
       try {
 	std::ostringstream ostr;
-	ostr << IOError::what();
-	if( file || line ) {
+	ostr << _message;
+	if( _file || _line ) {
 	  ostr << " (";
-	  if( file ) ostr << "in file '" << *file << "'";
-	  if( file && line ) ostr << " ";
-	  if( line ) ostr << "at line " << line;
+	  if( _file ) ostr << "in file '" << *_file << "'";
+	  if( _file && _line ) ostr << " ";
+	  if( _line ) ostr << "at line " << _line;
 	  ostr << ")";
 	}
@@ -217,4 +230,8 @@
       catch(...) {}
       if( mes ) return mes;
+      return exceptionName();
+    }
+
+    virtual const char* exceptionName() const {
       return "lemon::DataFormatError";
     }
@@ -265,4 +282,8 @@
       catch(...) {}
       if( mes ) return mes;
+      return exceptionName();
+    }
+
+    virtual const char* exceptionName() const {
       return "lemon::AssertionFailedError";
     }
@@ -312,5 +333,9 @@
 
 #ifndef LEMON_ASSERT_HANDLER
-#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail
+#  ifdef LEMON_ASSERT_EXCEPTION
+#    define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
+#  else
+#    define LEMON_ASSERT_HANDLER ::lemon::assert_fail
+#  endif
 #endif
 
@@ -323,4 +348,16 @@
 /**
  * \brief Macro for assertions with customizable message
+ *
+ * Macro for assertions with customizable message.
+ *
+ * The behaviour can be customized with LEMON_ASSERT_HANDLER,
+ * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
+ * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
+ *
+ * \todo We should provide some way to reset to the default behaviour,
+ * shouldn't we?
+ *
+ * \todo This whole 'assert' business should be placed in a separate
+ * include file.
  *
  * \todo __PRETTY_FUNCTION__ should be replaced by something
@@ -334,5 +371,5 @@
 			    (msg), #exp, LEMON_ASSERT_ABORT), 0)))
 
-# endif // NDEBUG
+#endif // NDEBUG || LEMON_DISABLE_ASSERTS
 
 /**
Index: src/work/klao/error_test.cc
===================================================================
--- src/work/klao/error_test.cc	(revision 1067)
+++ src/work/klao/error_test.cc	(revision 1120)
@@ -16,6 +16,6 @@
   }
   catch(lemon::DataFormatError &e) {
-    e.set_file(fn);
-    e.set_line(5);
+    e.file(fn);
+    e.line(5);
     throw;
   }
@@ -28,4 +28,9 @@
     parse_file("input.txt");
   }
+  catch(lemon::Exception &e) {
+    cerr << "Exception '" << e.exceptionName()
+	 << "' caught: " << endl;
+    cerr << e.what() << endl;
+  }
   catch(exception &e) {
     cerr << "Exception caught: " << endl;
@@ -34,5 +39,19 @@
 
   try {
+    throw lemon::LogicError();
+  }
+  catch(lemon::Exception &e) {
+    cerr << "Exception '" << e.exceptionName()
+	 << "' caught: " << endl;
+    cerr << e.what() << endl;
+  }
+
+  try {
     fail_assert();
+  }
+  catch(lemon::Exception &e) {
+    cerr << "Exception '" << e.exceptionName()
+	 << "' caught: " << endl;
+    cerr << e.what() << endl;
   }
   catch(exception &e) {
@@ -40,4 +59,6 @@
     cerr << e.what() << endl;
   }
+
+  cerr << endl;
 
   // assert(1==0);
@@ -47,5 +68,5 @@
 
 #undef LEMON_ASSERT_HANDLER
-#define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
+#define LEMON_ASSERT_EXCEPTION
 
 #include <error.h>
