diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp
index 105ce593..f789b921 100644
--- a/qse/include/qse/awk/Awk.hpp
+++ b/qse/include/qse/awk/Awk.hpp
@@ -30,6 +30,7 @@
 #include <qse/awk/awk.h>
 #include <qse/cmn/htb.h>
 #include <qse/cmn/chr.h>
+#include <qse/Types.hpp>
 #include <qse/cmn/Mmged.hpp>
 #include <stdarg.h>
 
@@ -44,7 +45,7 @@ QSE_BEGIN_NAMESPACE(QSE)
 /// The Awk class implements an AWK interpreter by wrapping around 
 /// #qse_awk_t and #qse_awk_rtx_t.
 ///
-class QSE_EXPORT Awk: public Mmged
+class QSE_EXPORT Awk: public Types, public Mmged
 {
 public:
 	typedef qse_htb_t htb_t;
diff --git a/qse/include/qse/cmn/ExcMmgr.hpp b/qse/include/qse/cmn/ExcMmgr.hpp
new file mode 100644
index 00000000..884a185b
--- /dev/null
+++ b/qse/include/qse/cmn/ExcMmgr.hpp
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+    Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _QSE_CMN_STDMMGR_HPP_
+#define _QSE_CMN_STDMMGR_HPP_
+
+#include <qse/cmn/Mmgr.hpp>
+
+/////////////////////////////////
+QSE_BEGIN_NAMESPACE(QSE)
+/////////////////////////////////
+
+/// The ExcMmgr class implements the memory manager interface that
+/// raises an exception upon failure. You can use the StdMmgr class
+/// if #QSE_NULL should be returned upon failure.
+
+class QSE_EXPORT ExcMmgr: public Mmgr
+{
+public:
+	void* allocMem (qse_size_t n);
+	void* reallocMem (void* ptr, qse_size_t n);
+	void freeMem (void* ptr);
+
+	static ExcMmgr* getDFL();
+};
+
+/////////////////////////////////
+QSE_END_NAMESPACE(QSE)
+/////////////////////////////////
+
+#endif
diff --git a/qse/include/qse/cmn/LinkedList.hpp b/qse/include/qse/cmn/LinkedList.hpp
index e4984f13..efdb1e86 100644
--- a/qse/include/qse/cmn/LinkedList.hpp
+++ b/qse/include/qse/cmn/LinkedList.hpp
@@ -28,44 +28,54 @@
 #define _QSE_CMN_LINKEDLIST_HPP_
 
 #include <qse/Types.hpp>
-#include <xp/bas/MemoryPool.hpp>
-#include <xp/bas/MemoryPoolable.hpp>
+#include <qse/cmn/Mpool.hpp>
+#include <qse/cmn/Mpoolable.hpp>
 
 
 /////////////////////////////////
 QSE_BEGIN_NAMESPACE(QSE)
 /////////////////////////////////
 
-template <typename T> class LinkedList;
+template <typename T, typename MPOOL> class LinkedList;
 
-template <typename T> 
-class LinkedListNode: protected MemoryPoolable
+template <typename T,typename MPOOL> 
+class LinkedListNode: protected Mpoolable
 {
 public:
-	friend class LinkedList<T>;
+	friend class LinkedList<T,MPOOL>;
+	typedef LinkedListNode<T,MPOOL> Node;
 
-	T value;
+	T value; // you can use this variable or accessor functions below
 
 protected:
-	LinkedListNode<T>* next;
-	LinkedListNode<T>* prev;
+	Node* next;
+	Node* prev;
 
 public:
-	LinkedListNode<T>* getNext () { return this->next; }
-	const LinkedListNode<T>* getNext () const { return this->next; }
+	T& getValue () { return this->value; }
+	const T& getValue () const { return this->value; }
+	void setValue (const T& v) { this->value = v; }
 
-	LinkedListNode<T>* getPrev () { return this->prev; }
-	const LinkedListNode<T>* getPrev () const { return this->prev; }
+	Node* getNext () { return this->next; }
+	const Node* getNext () const { return this->next; }
+	Node* getNextNode () { return this->next; }
+	const Node* getNextNode () const { return this->next; }
+
+	Node* getPrev () { return this->prev; }
+	const Node* getPrev () const { return this->prev; }
+	Node* getPrevNode () { return this->prev; }
+	const Node* getPrevNode () const { return this->prev; }
 
 protected:
-	LinkedListNode () {}
-	LinkedListNode (const T& v): value(v) {}
+	LinkedListNode (): prev(QSE_NULL), next(QSE_NULL)  {}
+	LinkedListNode (const T& v): value(v), prev(QSE_NULL), next(QSE_NULL)  {}
 
-	void setNext (const LinkedListNode<T>* node)
+	void setNext (const Node* node)
 	{
 		this->next = node;
 	}
-	void setPrev (const LinkedListNode<T>* node)
+
+	void setPrev (const Node* node)
 	{
 		this->prev = node;
 	}
@@ -74,10 +84,10 @@ protected:
 ///
 /// The LinkedList<T> class provides a template for a doubly-linked list.
 ///
-template <typename T> class LinkedList
+template <typename T, typename MPOOL = Mpool> class LinkedList
 {
 public:
-	typedef LinkedListNode<T> Node;
+	typedef LinkedListNode<T,MPOOL> Node;
 
 	enum 
 	{
@@ -96,7 +106,7 @@ public:
 		this->tail_node = QSE_NULL;
 	}
 
-	LinkedList (const LinkedList<T>& ll): mp (ll.mp.datumSize(), ll.mp.blockSize())
+	LinkedList (const LinkedList<T>& ll): mp (ll.mp.getDatumSize(), ll.mp.getBlockSize())
 	{
 		this->node_count = 0;
 		this->head_node = QSE_NULL;
@@ -161,9 +171,8 @@ public:
 	// create a new node to hold the value and insert it.
 	Node* insertValue (Node* pos, const T& value)
 	{
-		Node* n = this->mp.isEnabled()? 
-			(new(&mp) Node(value)): (new Node(value));
-		return this->insertNode (pos, n);
+		Node* node = new(&mp) Node(value);
+		return this->insertNode (pos, node);
 	}
 
 	T& insert (Node* node, const T& value)
@@ -186,10 +195,12 @@ public:
 
 	T& prepend (const T& value)
 	{
+		// same as prependValue()
 		return this->insert (this->head_node, value);
 	}
 	T& append (const T& value)
 	{
+		// same as appendValue()
 		return this->insert ((Node*)QSE_NULL, value);
 	}
 
@@ -263,22 +274,45 @@ public:
 	// take extra care when using this method as the node 
 	// can be freed through the memory pool when the list is 
 	// destructed if the memory pool is enabled.
-	Node* yield (Node* node, bool clear_links = true);
+	Node* yield (Node* node, bool clear_links = true)
+	{
+		QSE_ASSERT (node != QSE_NULL);
+		QSE_ASSERT (this->node_count > 0);
 
+		if (node->next)
+			node->next->prev = node->next;
+		else
+			this->tail_node = node->prev;
+
+		if (node->prev)
+			node->prev->next = node->next;
+		else
+			this->head_node = node->next;
+			
+		this->node_count--;
+
+		if (clear_links)
+		{
+			node->next = QSE_NULL;
+			node->prev = QSE_NULL;
+		}
+
+		return node;
+	}
 	// remove a node from the list and free it.
 	void remove (Node* node)
 	{
 		this->yield (node, false);
-		if (mp.isDisabled()) delete node;
-		else 
-		{
-			node->~Node ();
-		#if defined(_MSC_VER)
-			node->operator delete (node, &mp);
-		#else
-			node->dispose (node, &mp);
-		#endif
-		}
+
+		//call the destructor
+		node->~Node (); 
+
+		// cal the deallocator
+	#if defined(_MSC_VER)
+		node->operator delete (node, &this->mp);
+	#else
+		node->dispose (node, &this->mp);
+	#endif
 	}
 
 	void remove (qse_size_t index) 
@@ -298,17 +332,17 @@ public:
 	Node* yieldByValue (const T& value, bool clear_links = true)
 	{
 		Node* p = this->findFirstNode (value);
-		Node* p = this->findFirstNode (value);
-		if (p == QSE_NULL) return -1;
+		if (!p) return QSE_NULL;
 		return this->yield (p, clear_links);
 	}
 
+	/// \return the number of items deleted.
 	qse_size_t removeByValue (const T& value)
 	{
 		Node* p = this->findFirstNode (value);
 		if (!p) return 0;
 		this->remove (p);
-		return 1;
+		return 1; 
 	}
 
 	/// \return the number of items deleted
@@ -463,15 +497,15 @@ public:
 		while (p) 
 		{
 			saved = p->next;
-			
+
 			if (this->mp.isDisabled()) delete p;
 			else 
 			{
 				p->~Node ();
 			#if defined(_MSC_VER)
-				p->operator delete (p, &mp);
+				p->operator delete (p, &this->mp);
 			#else
-				p->dispose (p, &mp);
+				p->dispose (p, &this->mp);
 			#endif
 			}
 
@@ -510,14 +544,15 @@ public:
 	}
 
 protected:
-	MemoryPool  mp;
+	//Mpool       mp;
+	MPOOL       mp;
 	Node*       head_node;
 	Node*       tail_node;
 	qse_size_t  node_count;
 };
 
-template <typename T> 
-inline typename LinkedList<T>::Node* LinkedList<T>::insertNode (Node* pos, Node* node)
+template <typename T,typename MPOOL> 
+inline typename LinkedList<T,MPOOL>::Node* LinkedList<T,MPOOL>::insertNode (Node* pos, Node* node)
 {
 	if (pos == QSE_NULL) 
 	{
@@ -544,33 +579,6 @@ inline typename LinkedList<T>::Node* LinkedList<T>::insertNode (Node* pos, Node*
 	}
 
 	this->node_count++;
-	return n;
-}
-
-template <typename T>
-inline typename LinkedList<T>::Node* LinkedList<T>::yield (Node* node, bool clear_links) 
-{
-	QSE_ASSERT (node != QSE_NULL);
-	QSE_ASSERT (this->node_count > 0);
-
-	if (node->next)
-		node->next->prev = node->next;
-	else
-		this->tail_node = node->prev;
-
-	if (node->prev)
-		node->prev->next = node->next;
-	else
-		this->head_node = node->next;
-		
-	this->node_count--;
-
-	if (clear_links)
-	{
-		node->next = QSE_NULL;
-		node->prev = QSE_NULL;
-	}
-
 	return node;
 }
 
diff --git a/qse/include/qse/cmn/Makefile.am b/qse/include/qse/cmn/Makefile.am
index 03f311db..66578dac 100644
--- a/qse/include/qse/cmn/Makefile.am
+++ b/qse/include/qse/cmn/Makefile.am
@@ -51,7 +51,7 @@ pkginclude_HEADERS = \
 
 if ENABLE_CXX
 pkginclude_HEADERS += \
-	Mmgr.hpp StdMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \
+	Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \
 	LinkedList.hpp
 endif
 
diff --git a/qse/include/qse/cmn/Makefile.in b/qse/include/qse/cmn/Makefile.in
index 689e69a1..1050dc8f 100644
--- a/qse/include/qse/cmn/Makefile.in
+++ b/qse/include/qse/cmn/Makefile.in
@@ -51,7 +51,7 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 @ENABLE_CXX_TRUE@am__append_1 = \
-@ENABLE_CXX_TRUE@	Mmgr.hpp StdMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \
+@ENABLE_CXX_TRUE@	Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \
 @ENABLE_CXX_TRUE@	LinkedList.hpp
 
 subdir = include/qse/cmn
@@ -90,8 +90,8 @@ am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dir.h dll.h \
 	lda.h main.h map.h mb8.h mbwc.h mem.h mux.h nwad.h nwif.h \
 	nwio.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sck.h sio.h \
 	sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \
-	utf8.h xma.h Mmgr.hpp StdMmgr.hpp Mmged.hpp Mpool.hpp \
-	Mpoolable.hpp LinkedList.hpp
+	utf8.h xma.h Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp \
+	Mpool.hpp Mpoolable.hpp LinkedList.hpp
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
diff --git a/qse/include/qse/cmn/Mmged.hpp b/qse/include/qse/cmn/Mmged.hpp
index e3c8531e..3b049555 100644
--- a/qse/include/qse/cmn/Mmged.hpp
+++ b/qse/include/qse/cmn/Mmged.hpp
@@ -27,8 +27,8 @@
 #ifndef _QSE_CMN_MMGED_HPP_
 #define _QSE_CMN_MMGED_HPP_
 
-#include <qse/Types.hpp>
 #include <qse/cmn/Mmgr.hpp>
+#include <qse/cmn/StdMmgr.hpp>
 
 /////////////////////////////////
 QSE_BEGIN_NAMESPACE(QSE)
@@ -39,15 +39,18 @@ QSE_BEGIN_NAMESPACE(QSE)
 /// a subclass that uses a memory manager.
 ///
 
-class QSE_EXPORT Mmged: public Types
+class QSE_EXPORT Mmged
 {
 public:
-	Mmged (Mmgr* mmgr): mmgr (mmgr) {}
+	Mmged (Mmgr* mmgr): mmgr(mmgr) {}
 
 	///
 	/// The getMmgr() function returns the memory manager associated.
 	///
-	Mmgr* getMmgr () const { return mmgr; }
+	Mmgr* getMmgr () const { return this->mmgr; }
+
+
+
 
 protected:
 	Mmgr* mmgr;
diff --git a/qse/include/qse/cmn/Mmgr.hpp b/qse/include/qse/cmn/Mmgr.hpp
index f703b9b2..c2599110 100644
--- a/qse/include/qse/cmn/Mmgr.hpp
+++ b/qse/include/qse/cmn/Mmgr.hpp
@@ -27,7 +27,8 @@
 #ifndef _QSE_CMN_MMGR_HPP_
 #define _QSE_CMN_MMGR_HPP_
 
-#include <qse/Types.hpp>
+#include <qse/types.h>
+#include <qse/macros.h>
 
 /////////////////////////////////
 QSE_BEGIN_NAMESPACE(QSE)
@@ -40,7 +41,7 @@ QSE_BEGIN_NAMESPACE(QSE)
 /// write code in more object-oriented fashion. An inheriting class should 
 /// implement three pure virtual functions.
 /// 
-class QSE_EXPORT Mmgr: public Types, public qse_mmgr_t
+class QSE_EXPORT Mmgr: public qse_mmgr_t
 {
 public:
 	/// defines an alias type to #qse_mmgr_t 
@@ -70,7 +71,7 @@ protected:
 	/// If it fails to allocate memory, it should return QSE_NULL.
 	///
 	virtual void* allocMem (
-		size_t n ///< size of memory chunk to allocate in bytes 
+		qse_size_t n ///< size of memory chunk to allocate in bytes 
 	) = 0;
 
 	///
@@ -81,7 +82,7 @@ protected:
 	///
 	virtual void* reallocMem (
 		void* ptr, ///< pointer to memory chunk to resize
-		size_t n   ///< new size in bytes
+		qse_size_t n   ///< new size in bytes
 	) = 0;
 
 	///
@@ -96,12 +97,12 @@ protected:
 	///
 	/// bridge function from the #qse_mmgr_t type the allocMem() function.
 	///
-	static void* alloc_mem (mmgr_t* mmgr, size_t n);
+	static void* alloc_mem (mmgr_t* mmgr, qse_size_t n);
 
 	///
 	/// bridge function from the #qse_mmgr_t type the reallocMem() function.
 	///
-	static void* realloc_mem (mmgr_t* mmgr, void* ptr, size_t n);
+	static void* realloc_mem (mmgr_t* mmgr, void* ptr, qse_size_t n);
 
 	///
 	/// bridge function from the #qse_mmgr_t type the freeMem() function.
diff --git a/qse/include/qse/cmn/Mpool.hpp b/qse/include/qse/cmn/Mpool.hpp
index b9de66c9..6f6aeefc 100644
--- a/qse/include/qse/cmn/Mpool.hpp
+++ b/qse/include/qse/cmn/Mpool.hpp
@@ -28,6 +28,7 @@
 #define _QSE_CMN_MPOOL_HPP_
 
 #include <qse/Uncopyable.hpp>
+#include <qse/cmn/ExcMmgr.hpp>
 
 /////////////////////////////////
 QSE_BEGIN_NAMESPACE(QSE)
@@ -37,7 +38,7 @@ QSE_BEGIN_NAMESPACE(QSE)
 // allocator for fixed-size data
 //
 
-class Mpool: public Uncopyable 
+class QSE_EXPORT Mpool: public Uncopyable, protected ExcMmgr
 {
 public:
 	enum 
@@ -63,14 +64,16 @@ public:
 		return this->datum_size <= 0 || this->block_size <= 0;
 	}
 
-	inline qse_size_t datumSize () const
+	inline qse_size_t getDatumSize () const
 	{
 		return this->datum_size;
 	}
-	inline qse_size_t blockSize () const
+
+	inline qse_size_t getBlockSize () const
 	{
 		return this->block_size;
 	}
+
 	inline void setBlockSize (qse_size_t blockSize) 
 	{
 		this->block_size = blockSize;
@@ -87,6 +90,7 @@ protected:
 		Block*  next;
 		//qse_uint8_t data[0];
 	};
+
 	struct Chain 
 	{
 		Chain* next;
@@ -97,7 +101,7 @@ protected:
 	qse_size_t datum_size;
 	qse_size_t block_size;
 
-	void add_block ();
+	Block* add_block ();
 };
 
 /////////////////////////////////
diff --git a/qse/include/qse/cmn/Mpoolable.hpp b/qse/include/qse/cmn/Mpoolable.hpp
index d3965db7..a221859b 100644
--- a/qse/include/qse/cmn/Mpoolable.hpp
+++ b/qse/include/qse/cmn/Mpoolable.hpp
@@ -29,15 +29,18 @@
 
 #include <qse/cmn/Mpool.hpp>
 
+// use size_t as some compilers complain about qse_size_t used in new().
+#include <stddef.h> 
+
 /////////////////////////////////
 QSE_BEGIN_NAMESPACE(QSE)
 /////////////////////////////////
 
-class Mpoolable
+class QSE_EXPORT Mpoolable
 {
 public:
-	typedef qse_size_t mp_size_t;
 
+/*
 	inline void* operator new (mp_size_t size)
 	{
 		return ::operator new (size);
@@ -47,21 +50,24 @@ public:
 	{
 		::operator delete (ptr);
 	}
+*/
 
-	inline void* operator new (mp_size_t /*size*/, Mpool* mp)
+	inline void* operator new (size_t size, Mpool* mp)
 	{
-		return mp->allocate ();
+		return mp->isEnabled()? mp->allocate (): ::operator new (size);
 	}
 
 #if defined(_MSC_VER)
 	void operator delete (void* ptr, Mpool* mp)
 	{
-		mp->dispose (ptr);
+		if (mp->isEnabled()) mp->dispose (ptr);
+		else ::operator delete (mp);
 	}
 #else
 	inline void dispose (void* ptr, Mpool* mp)
 	{
-		mp->dispose (ptr);
+		if (mp->isEnabled()) mp->dispose (ptr);
+		else ::operator delete (mp);
 	}
 #endif
 };
diff --git a/qse/include/qse/cmn/StdMmgr.hpp b/qse/include/qse/cmn/StdMmgr.hpp
index 2989e047..6ce7e1e3 100644
--- a/qse/include/qse/cmn/StdMmgr.hpp
+++ b/qse/include/qse/cmn/StdMmgr.hpp
@@ -33,12 +33,16 @@
 QSE_BEGIN_NAMESPACE(QSE)
 /////////////////////////////////
 
+/// The StdMmgr class implements the memory manager interface.
+/// It doesn't raise an exception upon failure. If you want an exception
+/// to be raised, use the ExcMmgr class instead.
+
 class QSE_EXPORT StdMmgr: public Mmgr
 {
 public:
-	void* allocMem (size_t n);
-	void* reallocMem (void* ptr, size_t n);
-	virtual void freeMem (void* ptr);
+	void* allocMem (qse_size_t n);
+	void* reallocMem (void* ptr, qse_size_t n);
+	void freeMem (void* ptr);
 
 	static StdMmgr* getDFL();
 };
diff --git a/qse/include/qse/sed/Sed.hpp b/qse/include/qse/sed/Sed.hpp
index 68c610ff..1779ae32 100644
--- a/qse/include/qse/sed/Sed.hpp
+++ b/qse/include/qse/sed/Sed.hpp
@@ -27,6 +27,7 @@
 #ifndef _QSE_SED_SED_HPP_
 #define _QSE_SED_SED_HPP_
 
+#include <qse/Types.hpp>
 #include <qse/cmn/Mmged.hpp>
 #include <qse/sed/sed.h>
 
@@ -45,7 +46,7 @@ QSE_BEGIN_NAMESPACE(QSE)
 ///
 /// The Sed class implements a stream editor by wrapping around #qse_sed_t.
 ///
-class QSE_EXPORT Sed: public Mmged
+class QSE_EXPORT Sed: public Types, public Mmged
 {
 public:
 	/// The sed_t type redefines a stream editor type
diff --git a/qse/lib/cmn/ExcMmgr.cpp b/qse/lib/cmn/ExcMmgr.cpp
new file mode 100644
index 00000000..a3349d41
--- /dev/null
+++ b/qse/lib/cmn/ExcMmgr.cpp
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ * 
+    Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <qse/cmn/ExcMmgr.hpp>
+#include <stdlib.h>
+#include <stdio.h>
+
+/////////////////////////////////
+QSE_BEGIN_NAMESPACE(QSE)
+/////////////////////////////////
+
+
+void* ExcMmgr::allocMem (qse_size_t n) 
+{
+	void* ptr = ::malloc (n);
+	if (!ptr) throw 1; // TODO: change 1 to a proper exception object
+	return ptr; 
+}
+
+void* ExcMmgr::reallocMem (void* ptr, qse_size_t n) 
+{ 
+	void* xptr = ::realloc (ptr, n); 
+	if (!xptr) throw 1;
+	return xptr;
+}
+
+void ExcMmgr::freeMem (void* ptr) 
+{ 
+	::free (ptr); 
+}
+
+ExcMmgr* ExcMmgr::getDFL ()
+{
+	static ExcMmgr DFL;
+	return &DFL;
+}
+
+/////////////////////////////////
+QSE_END_NAMESPACE(QSE)
+/////////////////////////////////
diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am
index 7ef4c314..c8d51c97 100644
--- a/qse/lib/cmn/Makefile.am
+++ b/qse/lib/cmn/Makefile.am
@@ -141,7 +141,7 @@ if ENABLE_CXX
 
 lib_LTLIBRARIES += libqsecmnxx.la
 libqsecmnxx_la_SOURCES = \
-	Mmgr.cpp StdMmgr.cpp Mpool.cpp
+	Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp Mpool.cpp
 libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined
 libqsecmnxx_la_LIBADD = 
 
diff --git a/qse/lib/cmn/Makefile.in b/qse/lib/cmn/Makefile.in
index 2ef65003..ea58a835 100644
--- a/qse/lib/cmn/Makefile.in
+++ b/qse/lib/cmn/Makefile.in
@@ -149,9 +149,10 @@ libqsecmn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@
 libqsecmnxx_la_DEPENDENCIES =
-am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp Mpool.cpp
+am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp \
+	Mpool.cpp
 @ENABLE_CXX_TRUE@am_libqsecmnxx_la_OBJECTS = Mmgr.lo StdMmgr.lo \
-@ENABLE_CXX_TRUE@	Mpool.lo
+@ENABLE_CXX_TRUE@	ExcMmgr.lo Mpool.lo
 libqsecmnxx_la_OBJECTS = $(am_libqsecmnxx_la_OBJECTS)
 libqsecmnxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -434,7 +435,7 @@ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \
 libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined
 libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
 @ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
-@ENABLE_CXX_TRUE@	Mmgr.cpp StdMmgr.cpp Mpool.cpp
+@ENABLE_CXX_TRUE@	Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp Mpool.cpp
 
 @ENABLE_CXX_TRUE@libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined
 @ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD = 
@@ -515,6 +516,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExcMmgr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mmgr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mpool.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdMmgr.Plo@am__quote@
diff --git a/qse/lib/cmn/Mmgr.cpp b/qse/lib/cmn/Mmgr.cpp
index c0ca7887..eebcd618 100644
--- a/qse/lib/cmn/Mmgr.cpp
+++ b/qse/lib/cmn/Mmgr.cpp
@@ -30,12 +30,12 @@
 QSE_BEGIN_NAMESPACE(QSE)
 /////////////////////////////////
 
-void* Mmgr::alloc_mem (mmgr_t* mmgr, size_t n) 
+void* Mmgr::alloc_mem (mmgr_t* mmgr, qse_size_t n) 
 {
 	return ((Mmgr*)mmgr->ctx)->allocMem (n);
 }
 
-void* Mmgr::realloc_mem (mmgr_t* mmgr, void* ptr, size_t n) 
+void* Mmgr::realloc_mem (mmgr_t* mmgr, void* ptr, qse_size_t n) 
 {
 	return ((Mmgr*)mmgr->ctx)->reallocMem (ptr, n);
 }
diff --git a/qse/lib/cmn/Mpool.cpp b/qse/lib/cmn/Mpool.cpp
index a91159cf..92630052 100644
--- a/qse/lib/cmn/Mpool.cpp
+++ b/qse/lib/cmn/Mpool.cpp
@@ -25,9 +25,7 @@
  */
 
 #include <qse/cmn/Mpool.hpp>
-
-
-// TODO: can i use QSE_MMGR_XXXXX instead of ::new and ::delete???
+#include <qse/cmn/mem.h>
 
 /////////////////////////////////
 QSE_BEGIN_NAMESPACE(QSE)
@@ -47,6 +45,7 @@ Mpool::Mpool (qse_size_t datum_size, qse_size_t block_size)
 	this->nalloc = 0;
 #endif
 }
+
 Mpool::~Mpool ()
 {
 	this->dispose ();
@@ -59,7 +58,9 @@ void* Mpool::allocate ()
 	void* ptr = this->free_list;
 	if (!ptr) 
 	{
-		this->add_block ();
+		// NOTE: 'return QSE_NULL' can't be reached if add_block()
+		//       raises an exception.
+		if (!this->add_block ()) return QSE_NULL; 
 		ptr = this->free_list;
 	}
 	this->free_list = this->free_list->next;
@@ -84,24 +85,30 @@ void Mpool::dispose ()
 	while (block) 
 	{
 		Block* next = block->next;
-		::delete[] block;
+
+		//::delete[] (qse_uint8_t*)block;
+		this->freeMem ((qse_uint8_t*)block);
+
 		block = next;
 	}
 
 	this->free_list = QSE_NULL;
 	this->mp_blocks = QSE_NULL;
+
 #if defined(QSE_DEBUG_MPOOL)
 	this->navail = 0;
 	this->nalloc = 0;
 #endif
 }
 
-void Mpool::add_block ()
+Mpool::Block* Mpool::add_block ()
 {
 	QSE_ASSERT (this->datum_size > 0 && this->block_size > 0);
 
-	Block* block = (Block*)::new qse_uint8_t[
-		QSE_SIZEOF(Block) + this->block_size * this->datum_size];
+	//Block* block = (Block*)::new qse_uint8_t[
+	//	QSE_SIZEOF(Block) + this->block_size * this->datum_size];
+	Block* block = (Block*)this->allocMem (QSE_SIZEOF(Block) + this->block_size * this->datum_size);
+	if (!block) return QSE_NULL; // this line may not be reached if the allocator raises an exception
 
 	//this->free_list = (Chain*)block->data;
 	this->free_list = (Chain*)(block + 1);
@@ -114,12 +121,15 @@ void Mpool::add_block ()
 	}
 	ptr->next = QSE_NULL;
 
-	block->next  = this->mp_blocks;
+	block->next = this->mp_blocks;
 	this->mp_blocks = block;
+
 #if defined(QSE_DEBUG_MPOOL)
 	this->navail += this->block_size;
 	this->nalloc += this->block_size;
 #endif
+
+	return block;
 }
 
 /////////////////////////////////
diff --git a/qse/lib/cmn/StdMmgr.cpp b/qse/lib/cmn/StdMmgr.cpp
index de53fea7..2fddf878 100644
--- a/qse/lib/cmn/StdMmgr.cpp
+++ b/qse/lib/cmn/StdMmgr.cpp
@@ -32,12 +32,12 @@ QSE_BEGIN_NAMESPACE(QSE)
 /////////////////////////////////
 
 
-void* StdMmgr::allocMem (size_t n) 
+void* StdMmgr::allocMem (qse_size_t n) 
 {
-	return ::malloc (n); 
+	return ::malloc (n);
 }
 
-void* StdMmgr::reallocMem (void* ptr, size_t n) 
+void* StdMmgr::reallocMem (void* ptr, qse_size_t n) 
 { 
 	return ::realloc (ptr, n); 
 }