Add possibility to define a custom Class Loader
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d072212..bebbed4 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -7,6 +7,9 @@
 	</properties>

 	<body>

 		<release version="1.5" date="in Mercurial" description="development: improve performance">

+            <action dev="py4fun" type="add">

+                Add possibility to define a custom Class Loader. (2009-09-01)

+            </action>

             <action dev="py4fun" type="fix">

                 Fixed an obscure scanner error not reported when there is no line break at the end 

                 of the stream. The fix is imported from PyYAML 3.09 {ticket 118} (2009-08-31)

diff --git a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
index 750460f..1e0b8f7 100644
--- a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
+++ b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
@@ -526,7 +526,7 @@
             String name = node.getTag().substring(Tags.PREFIX.length());
             Class<?> cl;
             try {
-                cl = Class.forName(name);
+                cl = getClassForName(name);
             } catch (ClassNotFoundException e) {
                 throw new YAMLException("Class not found: " + name);
             }
@@ -536,4 +536,8 @@
             return classForTag;
         }
     }
+
+    protected Class<?> getClassForName(String name) throws ClassNotFoundException {
+        return Class.forName(name);
+    }
 }
diff --git a/src/main/java/org/yaml/snakeyaml/constructor/CustomClassLoaderConstructor.java b/src/main/java/org/yaml/snakeyaml/constructor/CustomClassLoaderConstructor.java
new file mode 100644
index 0000000..7b29280
--- /dev/null
+++ b/src/main/java/org/yaml/snakeyaml/constructor/CustomClassLoaderConstructor.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2008-2009 Andrey Somov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.yaml.snakeyaml.constructor;
+
+/**
+ * Construct instances with a custom Class Loader.
+ */
+public class CustomClassLoaderConstructor extends Constructor {
+    private ClassLoader loader = CustomClassLoaderConstructor.class.getClassLoader();
+
+    public CustomClassLoaderConstructor(ClassLoader cLoader) {
+        this(Object.class, cLoader);
+    }
+
+    public CustomClassLoaderConstructor(Class<? extends Object> theRoot, ClassLoader theLoader) {
+        super(theRoot);
+        if (theLoader == null) {
+            throw new NullPointerException("Loader must be provided.");
+        }
+        this.loader = theLoader;
+    }
+
+    @Override
+    protected Class<?> getClassForName(String name) throws ClassNotFoundException {
+        return Class.forName(name, true, loader);
+    }
+}
diff --git a/src/test/java/org/yaml/snakeyaml/constructor/CustomClassLoaderConstructorTest.java b/src/test/java/org/yaml/snakeyaml/constructor/CustomClassLoaderConstructorTest.java
new file mode 100644
index 0000000..5978ac1
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/constructor/CustomClassLoaderConstructorTest.java
@@ -0,0 +1,84 @@
+/**

+ * Copyright (c) 2008-2009 Andrey Somov

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+package org.yaml.snakeyaml.constructor;

+

+import junit.framework.TestCase;

+

+import org.yaml.snakeyaml.Loader;

+import org.yaml.snakeyaml.Yaml;

+

+public class CustomClassLoaderConstructorTest extends TestCase {

+

+    public void testGetClassForNameNull() {

+        try {

+            new CustomClassLoaderConstructor(null);

+            fail();

+        } catch (Exception e) {

+            assertEquals("Loader must be provided.", e.getMessage());

+        }

+    }

+

+    public void testGetClassForName() {

+        CustomClassLoaderConstructor constr = new CustomClassLoaderConstructor(

+                CustomClassLoaderConstructorTest.class.getClassLoader());

+        Yaml yaml = new Yaml(new Loader(constr));

+        String s = (String) yaml.load("abc");

+        assertEquals("abc", s);

+    }

+

+    public void testGetClassForNameWithRoot() throws ClassNotFoundException {

+        Class<?> clazz = Class.forName(

+                "org.yaml.snakeyaml.constructor.CustomClassLoaderConstructorTest$LoaderBean", true,

+                CustomClassLoaderConstructorTest.class.getClassLoader());

+        CustomClassLoaderConstructor constr = new CustomClassLoaderConstructor(clazz,

+                CustomClassLoaderConstructorTest.class.getClassLoader());

+        Yaml yaml = new Yaml(new Loader(constr));

+        LoaderBean bean = (LoaderBean) yaml.load("{name: Andrey, number: 555}");

+        assertEquals("Andrey", bean.getName());

+        assertEquals(555, bean.getNumber());

+    }

+

+    public void testGetClassForNameBean() {

+        CustomClassLoaderConstructor constr = new CustomClassLoaderConstructor(

+                CustomClassLoaderConstructorTest.class.getClassLoader());

+        Yaml yaml = new Yaml(new Loader(constr));

+        LoaderBean bean = (LoaderBean) yaml

+                .load("!!org.yaml.snakeyaml.constructor.CustomClassLoaderConstructorTest$LoaderBean {name: Andrey, number: 555}");

+        assertEquals("Andrey", bean.getName());

+        assertEquals(555, bean.getNumber());

+    }

+

+    public static class LoaderBean {

+        private String name;

+        private int number;

+

+        public String getName() {

+            return name;

+        }

+

+        public void setName(String name) {

+            this.name = name;

+        }

+

+        public int getNumber() {

+            return number;

+        }

+

+        public void setNumber(int number) {

+            this.number = number;

+        }

+    }

+}