diff --git a/lib/warn.js b/lib/warn.js
new file mode 100644
index 0000000..b9983f8
--- /dev/null
+++ b/lib/warn.js
@@ -0,0 +1,67 @@
+/**
+ * ease.js warning system
+ *
+ * Copyright (C) 2010 Mike Gerwitz
+ *
+ * This file is part of ease.js.
+ *
+ * ease.js is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ *
+ * @author Mike Gerwitz
+ * @package core
+ */
+
+
+/**
+ * Permits wrapping an exception as a warning
+ *
+ * Warnings are handled differently by the system, depending on the warning
+ * level that has been set.
+ *
+ * @param {Error} e exception (error) to wrap
+ *
+ * @return {Warning} new warning instance
+ */
+var Warning = exports.Warning = function( e )
+{
+ // allow instantiation without use of 'new' keyword
+ if ( !( this instanceof Warning ) )
+ {
+ return new Warning( e );
+ }
+
+ // ensure we're wrapping an exception
+ if ( !( e instanceof Error ) )
+ {
+ throw TypeError( "Must provide exception to wrap" );
+ }
+
+ // copy over the message for convenience
+ this.message = e.message;
+ this._error = e;
+};
+
+Warning.prototype = Error();
+
+
+/**
+ * Return the error wrapped by the warning
+ *
+ * @return {Error} wrapped error
+ */
+Warning.prototype.getError = function()
+{
+ return this._error;
+};
+
diff --git a/test/test-warn-exception.js b/test/test-warn-exception.js
new file mode 100644
index 0000000..72cac1a
--- /dev/null
+++ b/test/test-warn-exception.js
@@ -0,0 +1,101 @@
+/**
+ * Tests the Warning prototype
+ *
+ * Copyright (C) 2010 Mike Gerwitz
+ *
+ * This file is part of ease.js.
+ *
+ * ease.js is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ *
+ * @author Mike Gerwitz
+ * @package test
+ */
+
+var common = require( './common' ),
+ assert = require( 'assert' ),
+ Warning = common.require( 'warn' ).Warning
+;
+
+
+/**
+ * Warning's prototype should be Error to ensure instanceof() checks work
+ * properly
+ */
+( function testWarningIsAvailableAndHasErrorAsPrototype()
+{
+ assert.ok( ( Warning.prototype instanceof Error ),
+ "Warning should be an instance of Error"
+ );
+} )();
+
+
+/**
+ * Just as with the other Error classes, as well as all ease.js classes, the
+ * 'new' keyword should be optional when instantiating the class
+ */
+( function testNewKeywordIsNotRequiredForInstantiation()
+{
+ assert.ok( Warning( Error( '' ) ) instanceof Warning,
+ "'new' keyword should not be necessary to instantiate Warning"
+ );
+} )();
+
+
+/**
+ * Warning message should be taken from the exception passed to it
+ */
+( function testCanWarningMessageIsSetFromWrappedException()
+{
+ var err = Error( 'oshit' ),
+ warning = Warning( err );
+
+ assert.equal( warning.message, err.message,
+ "Warning message should be taken from wrapped exception"
+ );
+} )();
+
+
+/**
+ * The whole point of Warning is to wrap an exception. So, ensure that one is
+ * wrapped.
+ */
+( function testThrowsExceptionIfNoExceptionIsWrapped()
+{
+ assert.throws( function()
+ {
+ Warning( /* nothing provided to wrap */ );
+ }, TypeError, "Exception should be thrown if no exception is provided" );
+
+ assert.throws( function()
+ {
+ Warning( 'not an exception' );
+ }, TypeError, "Exception should be thrown if given value is not an Error" );
+} )();
+
+
+/**
+ * We must provide access to the wrapped exception so that it can be properly
+ * handled. Warning is only intended to provide additional information so that
+ * ease.js may handle it differently than other Error instances.
+ */
+( function testCanRetrieveWrappedException()
+{
+ var err = Error( 'foo' ),
+ warning = Warning( err );
+
+ assert.deepEqual( err, warning.getError(),
+ "Can retrieve wrapped exception"
+ );
+} )();
+
diff --git a/tools/combine b/tools/combine
index e968e5b..ed2bf6f 100755
--- a/tools/combine
+++ b/tools/combine
@@ -29,7 +29,7 @@ TPL_VAR='/**{CONTENT}**/'
RMTRAIL="$PATH_TOOLS/rmtrail"
# order matters
-CAT_MODULES="prop_parser util propobj member_builder class_builder"
+CAT_MODULES="warn prop_parser util propobj member_builder class_builder"
CAT_MODULES="$CAT_MODULES class class_final class_abstract interface"
##