diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ClassUtility.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ClassUtility.java
index 9ecb6c4..6ff109e 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ClassUtility.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ClassUtility.java
@@ -21,94 +21,116 @@
 /**
  * This class provides methods to process class name
  */
+public class ClassUtility
+{
+    /**
+     * This method capitalizes the first character in the provided string.
+     * @return resulted string
+     */
+    public static String capitalize(String name)
+    {
+        int len = name.length();
+        StringBuffer sb = new StringBuffer(len);
+        boolean setCap = true;
+        for (int i = 0; i < len; i++)
+        {
+            char c = name.charAt(i);
+            if (c == '-' || c == '_')
+            {
+                setCap = true;
+            }
+            else
+            {
+                if (setCap)
+                {
+                    sb.append(Character.toUpperCase(c));
+                    setCap = false;
+                }
+                else
+                {
+                    sb.append(c);
+                }
+            }
+        }
 
-public class ClassUtility {
+        return sb.toString();
+    }
 
-	/**
-	 * This method capitalizes the first character in the provided string.
-	 * @return resulted string
-	 */
-	public static String capitalize(String name) {
+    /**
+     * This method minusculizes all characters in the provided string.
+     * @return resulted string
+     */
+    public static String toLowerCase(String name)
+    {
+        int len = name.length();
+        StringBuffer sb = new StringBuffer(len);
+        for (int i = 0; i < len; i++)
+        {
+            char c = name.charAt(i);
+            sb.append(Character.toLowerCase(c));
+        }
+        return sb.toString();
+    }
 
-		int len=name.length();
-		StringBuffer sb=new StringBuffer(len);
-		boolean setCap=true;
-		for(int i=0; i<len; i++){
-			char c=name.charAt(i);
-			if(c=='-' || c=='_') {
-				setCap=true;			
-			} else {
-				if(setCap){
-					sb.append(Character.toUpperCase(c));
-					setCap=false;
-				} else {
-					sb.append(c);
-				}
-			}
-		} 
- 
-		return sb.toString();
-	}
+    /**
+     * This method capitalizes all characters in the provided string.
+     * @return resulted string
+     */
+    public static String finalstaticOf(String membername)
+    {
+        int len = membername.length();
+        StringBuffer sb = new StringBuffer(len + 2);
+        for (int i = 0; i < len; i++)
+        {
+            char c = membername.charAt(i);
+            if (Character.isLowerCase(c))
+            {
+                sb.append(Character.toUpperCase(c));
+            }
+            else if (Character.isUpperCase(c))
+            {
+                sb.append('_').append(c);
+            }
+            else
+            {
+                sb.append(c);
+            }
+        }
 
-	/**
-	 * This method minusculizes all characters in the provided string.
-	 * @return resulted string
-	 */
-	public static String toLowerCase(String name) {
-		int len=name.length();
-		StringBuffer sb=new StringBuffer(len);
-		for(int i=0; i<len; i++){
-			char c=name.charAt(i);
-			sb.append(Character.toLowerCase(c));
-		}  
-		return sb.toString();
-	}
+        return sb.toString();
+    }
 
+    /**
+     * This method returns the package name in a full class name
+     * @return resulted string
+     */
+    public static String packageOf(String fullclassname)
+    {
+        int index = fullclassname.lastIndexOf(".");
+        if (index > 0)
+        {
+            return fullclassname.substring(0, index);
+        }
+        else
+        {
+            return "";
+        }
+    }
 
-	/**
-	 * This method capitalizes all characters in the provided string.
-	 * @return resulted string
-	 */
-	public static String finalstaticOf(String membername) {
-		int len=membername.length();
-		StringBuffer sb=new StringBuffer(len+2);
-		for(int i=0; i<len; i++){
-			char c=membername.charAt(i);
-			if(Character.isLowerCase(c) ) {
-				sb.append(Character.toUpperCase(c));
-			} else if(Character.isUpperCase(c) ) {
-				sb.append('_').append(c);
-			} else {
-				sb.append(c);				
-			}
-		} 
- 
-		return sb.toString();
-	}
-	
-	/**
-	 * This method returns the package name in a full class name
-	 * @return resulted string
-	 */
-	public static String packageOf(String fullclassname) {
-		int index=fullclassname.lastIndexOf(".");
-		if(index>0) {
-			return fullclassname.substring(0,index);
-		} else {
-			return "";	
-		}
-	}
-
-	/**
-	 * This method returns the package name in a full class name
-	 * @return resulted string
-	 */
-	public static String classOf(String fullclassname) {
-		int index=fullclassname.lastIndexOf(".");
-		if(index>0) {
-			return fullclassname.substring(index+1);
-		} else {
-			return fullclassname;	
-		}
-	}
+    /**
+     * This method returns the package name in a full class name
+     * @return resulted string
+     */
+    public static String classOf(String fullclassname)
+    {
+        int index = fullclassname.lastIndexOf(".");
+        if (index > 0)
+        {
+            return fullclassname.substring(index + 1);
+        }
+        else
+        {
+            return fullclassname;
+        }
+    }
 }
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java
index b6e55eb..88a99cd 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java
@@ -27,19 +27,21 @@
  * handles the metadata in XML format
  * (use kXML (http://kxml.enhydra.org/) a open-source very light weight XML parser
  */
-public class KXml2MetadataHandler extends MetadataHandler {
-
-	public KXml2MetadataHandler(Logger logger) {
+public class KXml2MetadataHandler extends MetadataHandler
+{
+    public KXml2MetadataHandler(Logger logger)
+    {
         super(logger);
     }
 
-	/**
-	* Called to parse the InputStream and set bundle list and package hash map
-	*/
-	public void parse(InputStream is) throws Exception {
-		BufferedReader br = new BufferedReader(new InputStreamReader(is));
-		KXml2SAXParser parser;
-		parser = new KXml2SAXParser(br);
-		parser.parseXML(handler);
-	}
+    /**
+     * Called to parse the InputStream and set bundle list and package hash map
+     */
+    public void parse(InputStream is) throws Exception
+    {
+        BufferedReader br = new BufferedReader(new InputStreamReader(is));
+        KXml2SAXParser parser;
+        parser = new KXml2SAXParser(br);
+        parser.parseXML(m_handler);
+    }
 }
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java
index 81c2945..d3f52b2 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java
@@ -18,35 +18,40 @@
  */
 package org.apache.felix.bundlerepository.metadataparser;
 
-
 /**
  * this class adds type of elements to the parser
  */
-public class MappingProcessingInstructionHandler {
+public class MappingProcessingInstructionHandler
+{
+    private XmlCommonHandler m_handler;
+    private String m_name;
+    private String m_classname;
 
-	private XmlCommonHandler handler;
-	private String name;
-	private String classname;
+    public MappingProcessingInstructionHandler(XmlCommonHandler handler)
+    {
+        m_handler = handler;
+    }
 
-	public MappingProcessingInstructionHandler(XmlCommonHandler handler) {
-		this.handler = handler;
-	}
+    public void process() throws Exception
+    {
+        if (m_name == null)
+        {
+            throw new Exception("element is missing");
+        }
+        if (m_classname == null)
+        {
+            throw new Exception("class is missing");
+        }
+        m_handler.addType(m_name, getClass().getClassLoader().loadClass(m_classname), null, null);
+    }
 
-	public void process() throws Exception {
-		if(name==null) {
-			throw new Exception("element is missing");
-		}
-		if(classname==null) {
-			throw new Exception("class is missing");
-		}
-		handler.addType(name,this.getClass().getClassLoader().loadClass(classname),null,null);
-	}
+    public void setElement(String element)
+    {
+        m_name = element;
+    }
 
-	public void setElement(String element) {
-		this.name=element;
-	}
-
-	public void setClass(String classname) {
-		this.classname=classname;
-	}
+    public void setClass(String classname)
+    {
+        m_classname = classname;
+    }
 }
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java
index b0ea621..bd0cbfc 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java
@@ -23,116 +23,128 @@
 import java.io.InputStream;
 import java.lang.reflect.Method;
 
-public abstract class MetadataHandler {
+public abstract class MetadataHandler
+{
+    protected XmlCommonHandler m_handler;
 
-	protected XmlCommonHandler handler;
+    /**
+     * constructor 
+     *
+     */
+    public MetadataHandler(Logger logger)
+    {
+        m_handler = new XmlCommonHandler(logger);
+    }
 
-	/**
-	 * constructor 
-	 *
-	 */
-	public MetadataHandler(Logger logger) {
-		handler = new XmlCommonHandler(logger);
-	}
+    /**
+     * Called to parse the InputStream and set bundle list and package hash map
+     */
+    public abstract void parse(InputStream is) throws Exception;
 
-	/**
-	* Called to parse the InputStream and set bundle list and package hash map
-	*/
-	public abstract void parse(InputStream is) throws Exception;
+    /**
+     * return the metadata after the parsing
+     * @return a Object. Its class is the returned type of instanceFactory newInstance method for the root element of the XML document.
+     */
+    public final Object getMetadata()
+    {
+        return m_handler.getRoot();
+    }
 
-	/**
-	 * return the metadata after the parsing
-	 * @return a Object. Its class is the returned type of instanceFactory newInstance method for the root element of the XML document.
-	 */
-	public final Object getMetadata() {
-		return handler.getRoot();
-	}
-	/**
-	 * Add a type for a element
-	 * @param qname the name of the element to process
-	 * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
-	 * @throws Exception
-	 */
-	public final void addType(String qname, Object instanceFactory) throws Exception {
-		handler.addType(qname, instanceFactory, null, null);
-	}
+    /**
+     * Add a type for a element
+     * @param qname the name of the element to process
+     * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
+     * @throws Exception
+     */
+    public final void addType(String qname, Object instanceFactory) throws Exception
+    {
+        m_handler.addType(qname, instanceFactory, null, null);
+    }
 
-	/**
-	 * Add a type for a element
-	 * @param qname the name of the element to process
-	 * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
-	 * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
-	 * @throws Exception
-	 */
-	public final void addType(String qname, Object instanceFactory, Class castClass) throws Exception {
-		handler.addType(qname, instanceFactory, castClass, null);
-	}
+    /**
+     * Add a type for a element
+     * @param qname the name of the element to process
+     * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
+     * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
+     * @throws Exception
+     */
+    public final void addType(String qname, Object instanceFactory, Class castClass) throws Exception
+    {
+        m_handler.addType(qname, instanceFactory, castClass, null);
+    }
 
-	/**
-	 * Add a type for a element
-	 * @param qname the name of the element to process
-	 * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
-	 * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
-	 * @param defaultAddMethod the method used to add the sub-elements and attributes if no adder/setter is founded. could be omitted.
-	 * @throws Exception
-	 */
-	public final void addType(String qname, Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception {
-		handler.addType(qname, instanceFactory, castClass, defaultAddMethod);
-	}
-	
-	/**
-	 * Add a type for the default element
-	 * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
-	 * @throws Exception
-	 */
-	public final void setDefaultType(Object instanceFactory) throws Exception {
-		handler.setDefaultType(instanceFactory,null,null);
-	}
+    /**
+     * Add a type for a element
+     * @param qname the name of the element to process
+     * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
+     * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
+     * @param defaultAddMethod the method used to add the sub-elements and attributes if no adder/setter is founded. could be omitted.
+     * @throws Exception
+     */
+    public final void addType(String qname, Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception
+    {
+        m_handler.addType(qname, instanceFactory, castClass, defaultAddMethod);
+    }
 
-	/**
-	 * Add a type for the default element
-	 * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
-	 * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
-	 * @throws Exception
-	 */
-	public final void setDefaultType(Object instanceFactory, Class castClass) throws Exception {
-		handler.setDefaultType(instanceFactory, castClass,null);
-	}
+    /**
+     * Add a type for the default element
+     * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
+     * @throws Exception
+     */
+    public final void setDefaultType(Object instanceFactory) throws Exception
+    {
+        m_handler.setDefaultType(instanceFactory, null, null);
+    }
 
-	/**
-	 * Add a type for the default element
-	 * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
-	 * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
-	 * @param defaultAddMethod the method used to add the sub-elements and attributes if no adder/setter is founded. could be omitted.
-	 * @throws Exception
-	 */
-	public final void setDefaultType(Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception {
-		handler.setDefaultType(instanceFactory,castClass,defaultAddMethod);
-	}
+    /**
+     * Add a type for the default element
+     * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
+     * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
+     * @throws Exception
+     */
+    public final void setDefaultType(Object instanceFactory, Class castClass) throws Exception
+    {
+        m_handler.setDefaultType(instanceFactory, castClass, null);
+    }
 
-	/**
-	 * Add a type to process the processing instruction
-	 * @param piname
-	 * @param clazz
-	 */
-	public final void addPI(String piname, Class clazz) {
-		handler.addPI(piname, clazz);
-	}
+    /**
+     * Add a type for the default element
+     * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
+     * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
+     * @param defaultAddMethod the method used to add the sub-elements and attributes if no adder/setter is founded. could be omitted.
+     * @throws Exception
+     */
+    public final void setDefaultType(Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception
+    {
+        m_handler.setDefaultType(instanceFactory, castClass, defaultAddMethod);
+    }
 
-	/**
-	 * set the missing PI exception flag. If during parsing, the flag is true and the processing instruction is unknown, then the parser throws a exception  
-	 * @param flag
-	 */
-	public final void setMissingPIExceptionFlag(boolean flag) {
-		handler.setMissingPIExceptionFlag(flag);
-	}
+    /**
+     * Add a type to process the processing instruction
+     * @param piname
+     * @param clazz
+     */
+    public final void addPI(String piname, Class clazz)
+    {
+        m_handler.addPI(piname, clazz);
+    }
 
-	/**
-	 * 
-	 * @param trace
-	 * @since 0.9.1
-	 */
-	public final void setTrace(boolean trace) {
-		handler.setTrace(trace);
-	}
+    /**
+     * set the missing PI exception flag. If during parsing, the flag is true and the processing instruction is unknown, then the parser throws a exception  
+     * @param flag
+     */
+    public final void setMissingPIExceptionFlag(boolean flag)
+    {
+        m_handler.setMissingPIExceptionFlag(flag);
+    }
+
+    /**
+     * 
+     * @param trace
+     * @since 0.9.1
+     */
+    public final void setTrace(boolean trace)
+    {
+        m_handler.setTrace(trace);
+    }
 }
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ReplaceUtility.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ReplaceUtility.java
index 52e4662..f238ed4 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ReplaceUtility.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/ReplaceUtility.java
@@ -23,54 +23,60 @@
 /**
  * This class provides methods to replace ${var} substring by values stored in a map
  */
+public class ReplaceUtility
+{
+    /**
+     * This method replaces ${var} substring by values stored in a map.
+     * @return resulted string
+     */
+    public static String replace(String str, Map values)
+    {
+        int len = str.length();
+        StringBuffer sb = new StringBuffer(len);
 
-public class ReplaceUtility {
+        int prev = 0;
+        int start = str.indexOf("${");
+        int end = str.indexOf("}", start);
+        while (start != -1 && end != -1)
+        {
+            String key = str.substring(start + 2, end);
+            Object value = values.get(key);
+            if (value != null)
+            {
+                sb.append(str.substring(prev, start));
+                sb.append(value);
+            }
+            else
+            {
+                sb.append(str.substring(prev, end + 1));
+            }
+            prev = end + 1;
+            if (prev >= str.length())
+            {
+                break;
+            }
+            start = str.indexOf("${", prev);
+            if (start != -1)
+            {
+                end = str.indexOf("}", start);
+            }
+        }
 
-	/**
-	 * This method replaces ${var} substring by values stored in a map.
-	 * @return resulted string
-	 */
-	public static String replace(String str, Map values) {
+        sb.append(str.substring(prev));
 
-		int len = str.length();
-		StringBuffer sb = new StringBuffer(len);
+        return sb.toString();
+    }
 
-		int prev = 0;
-		int start = str.indexOf("${");
-		int end = str.indexOf("}", start);
-		while (start != -1 && end != -1) {
-			String key = str.substring(start + 2, end);
-			Object value = values.get(key);
-			if (value != null) {
-				sb.append(str.substring(prev, start));
-				sb.append(value);
-			} else {
-				sb.append(str.substring(prev, end + 1));
-			}
-			prev = end + 1;
-			if (prev >= str.length())
-				break;
-
-			start = str.indexOf("${", prev);
-			if (start != -1)
-				end = str.indexOf("}", start);
-		}
-
-		sb.append(str.substring(prev));
-
-		return sb.toString();
-	}
-
-	//	public static void main(String[] args){
-	//		Map map=new HashMap();
-	//		map.put("foo","FOO");
-	//		map.put("bar","BAR");
-	//		map.put("map",map);
-	//				
-	//		String str;
-	//		if(args.length==0) str=""; else str=args[0];
-	//		
-	//		System.out.println(replace(str,map));
-	//		
-	//	}
+    //	public static void main(String[] args){
+    //		Map map=new HashMap();
+    //		map.put("foo","FOO");
+    //		map.put("bar","BAR");
+    //		map.put("map",map);
+    //				
+    //		String str;
+    //		if(args.length==0) str=""; else str=args[0];
+    //		
+    //		System.out.println(replace(str,map));
+    //		
+    //	}
 }
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java
index 5257ee7..7a29b1d 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java
@@ -26,845 +26,996 @@
 import org.apache.felix.bundlerepository.Logger;
 import org.xml.sax.SAXException;
 
-
 /**
  * SAX handler for the XML file
  */
-public class XmlCommonHandler implements KXml2SAXHandler {
+public class XmlCommonHandler implements KXml2SAXHandler
+{
+    private static final String PI_MAPPING = "mapping";
+    public static final String METADATAPARSER_PIS = "METADATAPARSER_PIS";
+    public static final String METADATAPARSER_TYPES = "METADATAPARSER_TYPES";
+    private int m_columnNumber;
+    private int m_lineNumber;
+    private boolean m_traceFlag = false;
+    private static String VALUE = "value";
 
-	private static final String PI_MAPPING = "mapping";
-
-	public static final String METADATAPARSER_PIS = "METADATAPARSER_PIS";
-
-	public static final String METADATAPARSER_TYPES = "METADATAPARSER_TYPES";
-
-	private int columnNumber;
-
-	private int lineNumber;
-
-	private boolean traceFlag = false;
-
-	private static String VALUE = "value";
-
-	//
-	// Data
-	//
-
-	private XmlStackElement root;
-
-	private Stack elementStack;
-	
-	private Map pis;
-
-	private boolean missingPIExceptionFlag;
-
-	private Map types;
-
-	private TypeEntry defaultType;
-
-	private StringBuffer currentText;
-
-	private Map context;
+    //
+    // Data
+    //
+    private XmlStackElement m_root;
+    private Stack m_elementStack;
+    private Map m_pis;
+    private boolean m_missingPIExceptionFlag;
+    private Map m_types;
+    private TypeEntry m_defaultType;
+    private StringBuffer m_currentText;
+    private Map m_context;
     private final Logger m_logger;
 
-    private class XmlStackElement {
-		
-		public final String qname;
-		public Object object;
-		
-		public XmlStackElement(String qname, Object object) {
-			super();
-			this.qname = qname;
-			this.object = object;
-		};
-	}
+    private class XmlStackElement
+    {
+        public final String m_qname;
+        public Object m_object;
 
-	public class TypeEntry {
-		public final Object instanceFactory;
-		public final Class instanceClass;
-		public final Method newInstanceMethod;
-		public final Class castClass;
-		public final Method defaultAddMethod;
-		
-		public TypeEntry(Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception {
-			super();
-			this.instanceFactory = instanceFactory;
-						
-			try {
-				if (instanceFactory instanceof Class) {
-					newInstanceMethod = instanceFactory.getClass()
-						.getDeclaredMethod("newInstance", null);
-					if (castClass == null) {
-						this.castClass = (Class) instanceFactory;
-					} else {
-						if (!castClass.isAssignableFrom((Class) instanceFactory)) {
-							throw new Exception(
-											"instanceFactory "
-											+ instanceFactory.getClass().getName()
-											+ " could not instanciate objects assignable to "
-											+ castClass.getName());
-						}
-						this.castClass=castClass;
-					}
-					instanceClass = (Class) instanceFactory;
-				} else {
-					newInstanceMethod = instanceFactory.getClass()
-						.getDeclaredMethod("newInstance", null);
-					Class returnType = newInstanceMethod.getReturnType();
-					if (castClass == null) {
-						this.castClass = returnType;
-					} else if (!castClass.isAssignableFrom(returnType)) {
-						throw new Exception(
-								"instanceFactory "
-								+ instanceFactory.getClass().getName()
-								+ " could not instanciate objects assignable to "
-								+ castClass.getName());
-					} else 
-						this.castClass=castClass;
-					instanceClass = returnType;
-				}
-			} catch (NoSuchMethodException e) {
-				throw new Exception(
-						"instanceFactory " + instanceFactory.getClass().getName()
-						+ " should have a newInstance method");
-			}
-			
-			// TODO check method
-			this.defaultAddMethod = defaultAddMethod;
-            if (this.defaultAddMethod != null)
+        public XmlStackElement(String qname, Object object)
+        {
+            super();
+            m_qname = qname;
+            m_object = object;
+        }
+    }
+
+    public class TypeEntry
+    {
+        public final Object m_instanceFactory;
+        public final Class m_instanceClass;
+        public final Method m_newInstanceMethod;
+        public final Class m_castClass;
+        public final Method m_defaultAddMethod;
+
+        public TypeEntry(Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception
+        {
+            super();
+            m_instanceFactory = instanceFactory;
+
+            try
             {
-                this.defaultAddMethod.setAccessible(true);
+                if (instanceFactory instanceof Class)
+                {
+                    m_newInstanceMethod = instanceFactory.getClass().getDeclaredMethod("newInstance", null);
+                    if (castClass == null)
+                    {
+                        m_castClass = (Class) instanceFactory;
+                    }
+                    else
+                    {
+                        if (!castClass.isAssignableFrom((Class) instanceFactory))
+                        {
+                            throw new Exception(
+                                "instanceFactory " + instanceFactory.getClass().getName() + " could not instanciate objects assignable to " + castClass.getName());
+                        }
+                        m_castClass = castClass;
+                    }
+                    m_instanceClass = (Class) instanceFactory;
+                }
+                else
+                {
+                    m_newInstanceMethod = instanceFactory.getClass().getDeclaredMethod("newInstance", null);
+                    Class returnType = m_newInstanceMethod.getReturnType();
+                    if (castClass == null)
+                    {
+                        m_castClass = returnType;
+                    }
+                    else if (!castClass.isAssignableFrom(returnType))
+                    {
+                        throw new Exception(
+                            "instanceFactory " + instanceFactory.getClass().getName() + " could not instanciate objects assignable to " + castClass.getName());
+                    }
+                    else
+                    {
+                        m_castClass = castClass;
+                    }
+                    m_instanceClass = returnType;
+                }
             }
-		}
-		
-		public String toString(){
-			StringBuffer sb=new StringBuffer();
-			sb.append("[");
-			if(instanceFactory instanceof Class)
-				sb.append("instanceFactory=").append(((Class)instanceFactory).getName());
-			else
-				sb.append("instanceFactory=").append(instanceFactory.getClass().getName());
-			sb.append(",instanceClass=").append(instanceClass.getName());
-			sb.append(",castClass=").append(castClass.getName());
-			sb.append(",defaultAddMethod=");
-			if(defaultAddMethod==null) sb.append(""); else sb.append(defaultAddMethod.getName());
-			sb.append("]");
-			return sb.toString();
-		}
-	}
-	
-	public XmlCommonHandler(Logger logger) {
+            catch (NoSuchMethodException e)
+            {
+                throw new Exception(
+                    "instanceFactory " + instanceFactory.getClass().getName() + " should have a newInstance method");
+            }
+
+            // TODO check method
+            m_defaultAddMethod = defaultAddMethod;
+            if (m_defaultAddMethod != null)
+            {
+                m_defaultAddMethod.setAccessible(true);
+            }
+        }
+
+        public String toString()
+        {
+            StringBuffer sb = new StringBuffer();
+            sb.append("[");
+            if (m_instanceFactory instanceof Class)
+            {
+                sb.append("instanceFactory=").append(((Class) m_instanceFactory).getName());
+            }
+            else
+            {
+                sb.append("instanceFactory=").append(m_instanceFactory.getClass().getName());
+            }
+            sb.append(",instanceClass=").append(m_instanceClass.getName());
+            sb.append(",castClass=").append(m_castClass.getName());
+            sb.append(",defaultAddMethod=");
+            if (m_defaultAddMethod == null)
+            {
+                sb.append("");
+            }
+            else
+            {
+                sb.append(m_defaultAddMethod.getName());
+            }
+            sb.append("]");
+            return sb.toString();
+        }
+    }
+
+    public XmlCommonHandler(Logger logger)
+    {
         m_logger = logger;
-        elementStack = new Stack();
-		pis = new HashMap();
-		missingPIExceptionFlag = false;
-		types = new HashMap();
-		context = new HashMap();
-		context.put(METADATAPARSER_PIS, pis);
-		context.put(METADATAPARSER_TYPES, types);
-	}
+        m_elementStack = new Stack();
+        m_pis = new HashMap();
+        m_missingPIExceptionFlag = false;
+        m_types = new HashMap();
+        m_context = new HashMap();
+        m_context.put(METADATAPARSER_PIS, m_pis);
+        m_context.put(METADATAPARSER_TYPES, m_types);
+    }
 
-	public void addPI(String piname, Class clazz) {
-		pis.put(piname, clazz);
-	}
+    public void addPI(String piname, Class clazz)
+    {
+        m_pis.put(piname, clazz);
+    }
 
-	/**
-	 * set the missing PI exception flag. If during parsing, the flag is true
-	 * and the processing instruction is unknown, then the parser throws a
-	 * exception
-	 * 
-	 * @param flag
-	 */
-	public void setMissingPIExceptionFlag(boolean flag) {
-		missingPIExceptionFlag = flag;
-	}
-	
-	public void addType(String qname, Object instanceFactory, Class castClass, Method defaultAddMethod)
-	throws Exception {
+    /**
+     * set the missing PI exception flag. If during parsing, the flag is true
+     * and the processing instruction is unknown, then the parser throws a
+     * exception
+     * 
+     * @param flag
+     */
+    public void setMissingPIExceptionFlag(boolean flag)
+    {
+        m_missingPIExceptionFlag = flag;
+    }
 
-		TypeEntry typeEntry;
-		try {
-			typeEntry = new TypeEntry(
-					instanceFactory,
-					castClass,
-					defaultAddMethod
-				);
-		} catch (Exception e) {
-			throw new Exception(lineNumber + "," + columnNumber + ":" + qname + " : " + e.getMessage());
-		}
-		types.put(qname,typeEntry);		
-		trace("element "
-				+ qname
-				+ " : " + typeEntry.toString());
-	}
-		
-	public void setDefaultType(Object instanceFactory, Class castClass, Method defaultAddMethod)
-			throws Exception {
-		TypeEntry typeEntry;
-		try {
-			typeEntry = new TypeEntry(
-					instanceFactory,
-					castClass,
-					defaultAddMethod
-				);
-		} catch (Exception e) {
-			throw new Exception(lineNumber + "," + columnNumber + ": default element : " + e.getMessage());
-		}
-		defaultType=typeEntry;		
-		trace("default element "
-				+ " : " + typeEntry.toString());
-	}
+    public void addType(String qname, Object instanceFactory, Class castClass, Method defaultAddMethod)
+        throws Exception
+    {
 
-	public void setContext(Map context) {
-		this.context = context;
-	}
+        TypeEntry typeEntry;
+        try
+        {
+            typeEntry = new TypeEntry(
+                instanceFactory,
+                castClass,
+                defaultAddMethod);
+        }
+        catch (Exception e)
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + qname + " : " + e.getMessage());
+        }
+        m_types.put(qname, typeEntry);
+        trace("element " + qname + " : " + typeEntry.toString());
+    }
 
-	public Map getContext() {
-		return context;
-	}
+    public void setDefaultType(Object instanceFactory, Class castClass, Method defaultAddMethod)
+        throws Exception
+    {
+        TypeEntry typeEntry;
+        try
+        {
+            typeEntry = new TypeEntry(
+                instanceFactory,
+                castClass,
+                defaultAddMethod);
+        }
+        catch (Exception e)
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ": default element : " + e.getMessage());
+        }
+        m_defaultType = typeEntry;
+        trace("default element " + " : " + typeEntry.toString());
+    }
 
-	public Object getRoot() {
-		return root.object;
-	}
+    public void setContext(Map context)
+    {
+        m_context = context;
+    }
 
-	/* for PCDATA */
-	public void characters(char[] ch, int offset, int length) throws Exception {
-		if (currentText != null)
-			currentText.append(ch, offset, length);
-	}
+    public Map getContext()
+    {
+        return m_context;
+    }
 
-	private String adderOf(Class clazz) {
-		return "add"
-				+ ClassUtility
-						.capitalize(ClassUtility.classOf(clazz.getName()));
-	}
+    public Object getRoot()
+    {
+        return m_root.m_object;
+    }
 
-	private String adderOf(String key) {
-		return "add" + ClassUtility.capitalize(key);
-	}
+    /* for PCDATA */
+    public void characters(char[] ch, int offset, int length) throws Exception
+    {
+        if (m_currentText != null)
+        {
+            m_currentText.append(ch, offset, length);
+        }
+    }
 
-	private String setterOf(Class clazz) {
-		return "set"
-				+ ClassUtility
-						.capitalize(ClassUtility.classOf(clazz.getName()));
-	}
+    private String adderOf(Class clazz)
+    {
+        return "add" + ClassUtility.capitalize(ClassUtility.classOf(clazz.getName()));
+    }
 
-	private String setterOf(String key) {
-		return "set" + ClassUtility.capitalize(key);
-	}
+    private String adderOf(String key)
+    {
+        return "add" + ClassUtility.capitalize(key);
+    }
 
-	/**
-	 * set the parser context in a object
-	 */
-	private void setObjectContext(Object object)
-			throws IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		Method method = null;
-		try {
-			// TODO setContext from castClass or object.getClass() ?
-			method = object.getClass().getDeclaredMethod("setContext",
-					new Class[] { Map.class });
-		} catch (NoSuchMethodException e) {
-			// do nothing
-		}
-		if (method != null) {
-			trace(method.getName());
-			try {
-				method.invoke(object, new Object[] { context });
-			} catch (InvocationTargetException e) {
+    private String setterOf(Class clazz)
+    {
+        return "set" + ClassUtility.capitalize(ClassUtility.classOf(clazz.getName()));
+    }
+
+    private String setterOf(String key)
+    {
+        return "set" + ClassUtility.capitalize(key);
+    }
+
+    /**
+     * set the parser context in a object
+     */
+    private void setObjectContext(Object object)
+        throws IllegalArgumentException, IllegalAccessException,
+        InvocationTargetException
+    {
+        Method method = null;
+        try
+        {
+            // TODO setContext from castClass or object.getClass() ?
+            method = object.getClass().getDeclaredMethod("setContext",
+                new Class[]
+                {
+                    Map.class
+                });
+        }
+        catch (NoSuchMethodException e)
+        {
+            // do nothing
+        }
+        if (method != null)
+        {
+            trace(method.getName());
+            try
+            {
+                method.invoke(object, new Object[]
+                    {
+                        m_context
+                    });
+            }
+            catch (InvocationTargetException e)
+            {
                 m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-				throw e;
-			}
-		}
-	}
+                throw e;
+            }
+        }
+    }
 
-	/**
-	 * set the parser context in a object
-	 * 
-	 * @throws Throwable
-	 */
-	private void invokeProcess(Object object) throws Throwable {
-		Method method = null;
-		try {
-			// TODO process from castClass or object.getClass() ?
-			method = object.getClass().getDeclaredMethod("process", null);
-		} catch (NoSuchMethodException e) {
-			// do nothing
-		}
-		if (method != null) {
-			trace(method.getName());
-			try {
-				method.invoke(object, null);
-			} catch (InvocationTargetException e) {
-				// m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-				throw e.getTargetException();
-			}
+    /**
+     * set the parser context in a object
+     * 
+     * @throws Throwable
+     */
+    private void invokeProcess(Object object) throws Throwable
+    {
+        Method method = null;
+        try
+        {
+            // TODO process from castClass or object.getClass() ?
+            method = object.getClass().getDeclaredMethod("process", null);
+        }
+        catch (NoSuchMethodException e)
+        {
+            // do nothing
+        }
+        if (method != null)
+        {
+            trace(method.getName());
+            try
+            {
+                method.invoke(object, null);
+            }
+            catch (InvocationTargetException e)
+            {
+                // m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
+                throw e.getTargetException();
+            }
+        }
+    }
 
-		}
-	}
+    /**
+     * set the parent in a object
+     */
+    private void setObjectParent(Object object, Object parent)
+        throws InvocationTargetException, IllegalArgumentException,
+        IllegalAccessException
+    {
+        Method method = null;
+        try
+        {
+            // TODO setParent from castClass or object.getClass() ?
+            method = object.getClass().getDeclaredMethod("setParent",
+                new Class[]
+                {
+                    parent.getClass()
+                });
+        }
+        catch (NoSuchMethodException e)
+        {
+            // do nothing
+        }
+        if (method != null)
+        {
+            trace(method.getName());
+            try
+            {
+                method.invoke(object, new Object[]
+                    {
+                        parent
+                    });
+            }
+            catch (InvocationTargetException e)
+            {
+                m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
+                throw e;
+            }
+        }
+    }
 
-	/**
-	 * set the parent in a object
-	 */
-	private void setObjectParent(Object object, Object parent)
-			throws InvocationTargetException, IllegalArgumentException,
-			IllegalAccessException {
-		Method method = null;
-		try {
-			// TODO setParent from castClass or object.getClass() ?
-			method = object.getClass().getDeclaredMethod("setParent",
-					new Class[] { parent.getClass() });
-		} catch (NoSuchMethodException e) {
-			// do nothing
-		}
-		if (method != null) {
-			trace(method.getName());
-			try {
-				method.invoke(object, new Object[] { parent });
-			} catch (InvocationTargetException e) {
-				m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-				throw e;
-			}
-		}
-	}
+    /**
+     * Method called when a tag opens
+     * 
+     * @param uri
+     * @param localName
+     * @param qName
+     * @param attrib
+     * @exception SAXException
+     */
+    public void startElement(String uri, String localName, String qName,
+        Properties attrib) throws Exception
+    {
 
-	/**
-	 * Method called when a tag opens
-	 * 
-	 * @param uri
-	 * @param localName
-	 * @param qName
-	 * @param attrib
-	 * @exception SAXException
-	 */
-	public void startElement(String uri, String localName, String qName,
-			Properties attrib) throws Exception {
+        trace("START (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
 
-		trace("START (" + lineNumber + "," + columnNumber + "):" + uri + ":"
-				+ qName);
+        // TODO: should add uri in the qname in the future
+        TypeEntry type = (TypeEntry) m_types.get(qName);
+        if (type == null)
+        {
+            type = m_defaultType;
+        }
 
-		// TODO: should add uri in the qname in the future
-		TypeEntry type=(TypeEntry) types.get(qName);
-		if(type==null) {
-			type=defaultType;
-		}
+        Object obj = null;
+        if (type != null)
+        {
 
-		Object obj = null;
-		if (type != null) {
+            try
+            {
+                // enables to access to "unmuttable" method
+                type.m_newInstanceMethod.setAccessible(true);
+                obj = type.m_newInstanceMethod.invoke(type.m_instanceFactory, null);
+            }
+            catch (InvocationTargetException e)
+            {
+                m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
+            }
 
-			try {
-				// enables to access to "unmuttable" method
-				type.newInstanceMethod.setAccessible(true);
-                obj = type.newInstanceMethod.invoke(type.instanceFactory, null);
-			} catch (InvocationTargetException e) {
-				m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-			}
+            // set parent
+            if (!m_elementStack.isEmpty())
+            {
+                XmlStackElement parent = (XmlStackElement) m_elementStack.peek();
+                setObjectParent(obj, parent.m_object);
+            }
 
-			// set parent
-			if (!elementStack.isEmpty()) {
-				XmlStackElement parent = (XmlStackElement) elementStack.peek();
-				setObjectParent(obj, parent.object);
-			}
+            // set the parser context
+            setObjectContext(obj);
 
-			// set the parser context
-			setObjectContext(obj);
+            // set the attributes
+            Set keyset = attrib.keySet();
+            Iterator iter = keyset.iterator();
+            while (iter.hasNext())
+            {
+                String key = (String) iter.next();
 
-			// set the attributes
-			Set keyset = attrib.keySet();
-			Iterator iter = keyset.iterator();
-			while (iter.hasNext()) {
-				String key = (String) iter.next();
+                // substitute ${property} sbustrings by context' properties
+                // values
+                String value = ReplaceUtility.replace((String) attrib.get(key),
+                    m_context);
 
-				// substitute ${property} sbustrings by context' properties
-				// values
-				String value = ReplaceUtility.replace((String) attrib.get(key),
-						context);
+                // Firstly, test if the getter or the adder exists
 
-				// Firstly, test if the getter or the adder exists
+                Method method = null;
+                if (!(obj instanceof String))
+                {
+                    try
+                    {
+                        // method = castClass.getDeclaredMethod(setterOf(key),new
+                        // Class[] { String.class });
+                        method = type.m_instanceClass.getDeclaredMethod(setterOf(key),
+                            new Class[]
+                            {
+                                String.class
+                            });
+                    }
+                    catch (NoSuchMethodException e)
+                    {
+                        // do nothing
+                    }
+                    if (method == null)
+                    {
+                        try
+                        {
+                            method = type.m_instanceClass.getDeclaredMethod(adderOf(key),
+                                new Class[]
+                                {
+                                    String.class
+                                });
 
-				Method method = null;
-				if (!(obj instanceof String)) {
-					try {
-						// method = castClass.getDeclaredMethod(setterOf(key),new
-						// Class[] { String.class });
-						method = type.instanceClass.getDeclaredMethod(setterOf(key),
-								new Class[] { String.class });
-					} catch (NoSuchMethodException e) {
-						// do nothing
-					}
-					if (method == null)
-						try {
-							method = type.instanceClass.getDeclaredMethod(adderOf(key),
-									new Class[] { String.class });
+                        }
+                        catch (NoSuchMethodException e)
+                        {
+                            /*
+                             * throw new Exception(lineNumber + "," +
+                             * columnNumber + ":" + "element " + qName + " does
+                             * not support the attribute " + key);
+                             */
+                        }
+                    }
+                }
 
-						} catch (NoSuchMethodException e) {
-							/*
-							 * throw new Exception(lineNumber + "," +
-							 * columnNumber + ":" + "element " + qName + " does
-							 * not support the attribute " + key);
-							 */
-						}
+                if (method != null)
+                {
+                    trace(method.getName());
+                    try
+                    {
+                        method.invoke(obj, new String[]
+                            {
+                                value
+                            });
+                    }
+                    catch (InvocationTargetException e)
+                    {
+                        m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
+                        throw e;
+                    }
+                }
+                else
+                {
 
-				}
-				
-				if (method != null) {
-					trace(method.getName());
-					try {
-						method.invoke(obj, new String[] { value });
-					} catch (InvocationTargetException e) {
-						m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-						throw e;
-					}
-				} else {
-					
-					if (obj instanceof String) {
-						if (key.equals(VALUE)) {
-							obj = value;
-						} else {
-							throw new Exception(lineNumber + "," + columnNumber
-									+ ":" + "String element " + qName
-									+ " cannot have other attribute than value");
-						}
-					} else {
-						if (type.defaultAddMethod != null) {
-							Class[] parameterTypes=type.defaultAddMethod.getParameterTypes();
-							if(parameterTypes.length==2
-								&& parameterTypes[0].isAssignableFrom(String.class)
-								&& parameterTypes[1].isAssignableFrom(String.class)
-							){
-								type.defaultAddMethod.invoke(obj,new String[]{key, value});
-							} else if(parameterTypes.length==1
-										&& parameterTypes[0].isAssignableFrom(String.class)
-									){
-										type.defaultAddMethod.invoke(obj,new String[]{value});
-							} else 
-								throw new Exception(lineNumber + "," + columnNumber
-										+ ":" + "class "
-										+ type.instanceFactory.getClass().getName()
-										+ " for element " + qName
-										+ " does not support the attribute " + key
-										);							
-						} else {
-							throw new Exception(lineNumber + "," + columnNumber
-								+ ":" + "class "
-								+ type.instanceFactory.getClass().getName()
-								+ " for element " + qName
-								+ " does not support the attribute " + key
-								);
-						}
+                    if (obj instanceof String)
+                    {
+                        if (key.equals(VALUE))
+                        {
+                            obj = value;
+                        }
+                        else
+                        {
+                            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "String element " + qName + " cannot have other attribute than value");
+                        }
+                    }
+                    else
+                    {
+                        if (type.m_defaultAddMethod != null)
+                        {
+                            Class[] parameterTypes = type.m_defaultAddMethod.getParameterTypes();
+                            if (parameterTypes.length == 2 && parameterTypes[0].isAssignableFrom(String.class) && parameterTypes[1].isAssignableFrom(String.class))
+                            {
+                                type.m_defaultAddMethod.invoke(obj, new String[]
+                                    {
+                                        key, value
+                                    });
+                            }
+                            else if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(String.class))
+                            {
+                                type.m_defaultAddMethod.invoke(obj, new String[]
+                                    {
+                                        value
+                                    });
+                            }
+                            else
+                            {
+                                throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "class " + type.m_instanceFactory.getClass().getName() + " for element " + qName + " does not support the attribute " + key);
+                            }
+                        }
+                        else
+                        {
+                            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "class " + type.m_instanceFactory.getClass().getName() + " for element " + qName + " does not support the attribute " + key);
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "this element " + qName + " has not corresponding class");
+        }
+        XmlStackElement element = new XmlStackElement(qName, obj);
+        if (m_root == null)
+        {
+            m_root = element;
+        }
+        m_elementStack.push(element);
+        m_currentText = new StringBuffer();
 
-					}
-				}
+        trace("START/ (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
+    }
 
-			}
+    /**
+     * Method called when a tag closes
+     * 
+     * @param uri
+     * @param localName
+     * @param qName
+     * @exception SAXException
+     */
+    public void endElement(java.lang.String uri, java.lang.String localName,
+        java.lang.String qName) throws Exception
+    {
 
-		} else {
-			throw new Exception(lineNumber + "," + columnNumber + ":"
-					+ "this element " + qName + " has not corresponding class");
-		}
-		XmlStackElement element=new XmlStackElement(qName,obj);
-		if (root == null)
-			root = element;
-		elementStack.push(element);
-		currentText = new StringBuffer();
+        trace("END (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
 
-		trace("START/ (" + lineNumber + "," + columnNumber + "):" + uri + ":"
-				+ qName);
-	}
+        XmlStackElement element = (XmlStackElement) m_elementStack.pop();
+        TypeEntry elementType = (TypeEntry) m_types.get(element.m_qname);
+        if (elementType == null)
+        {
+            elementType = m_defaultType;
+        }
 
-	/**
-	 * Method called when a tag closes
-	 * 
-	 * @param uri
-	 * @param localName
-	 * @param qName
-	 * @exception SAXException
-	 */
-	public void endElement(java.lang.String uri, java.lang.String localName,
-			java.lang.String qName) throws Exception {
+        if (m_currentText != null && m_currentText.length() != 0)
+        {
 
-		trace("END (" + lineNumber + "," + columnNumber + "):" + uri + ":"
-				+ qName);
+            String currentStr = ReplaceUtility.replace(m_currentText.toString(),
+                m_context).trim();
+            // TODO: trim may be not the right choice
+            trace("current text:" + currentStr);
 
-		XmlStackElement element = (XmlStackElement) elementStack.pop();
-		TypeEntry elementType=(TypeEntry) types.get(element.qname);
-		if(elementType==null) {
-			elementType=defaultType;
-		}		
-		
-		if (currentText != null && currentText.length() != 0) {
+            Method method = null;
+            try
+            {
+                method = elementType.m_castClass.getDeclaredMethod("addText",
+                    new Class[]
+                    {
+                        String.class
+                    });
+            }
+            catch (NoSuchMethodException e)
+            {
+                try
+                {
+                    method = elementType.m_castClass.getDeclaredMethod("setText",
+                        new Class[]
+                        {
+                            String.class
+                        });
+                }
+                catch (NoSuchMethodException e2)
+                {
+                    // do nothing
+                }
+            }
+            if (method != null)
+            {
+                trace(method.getName());
+                try
+                {
+                    method.invoke(element.m_object, new String[]
+                        {
+                            currentStr
+                        });
+                }
+                catch (InvocationTargetException e)
+                {
+                    m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
+                    throw e;
+                }
+            }
+            else
+            {
+                if (String.class.isAssignableFrom(elementType.m_castClass))
+                {
+                    String str = (String) element.m_object;
+                    if (str.length() != 0)
+                    {
+                        throw new Exception(
+                            m_lineNumber + "," + m_columnNumber + ":" + "String element " + qName + " cannot have both PCDATA and an attribute value");
+                    }
+                    else
+                    {
+                        element.m_object = currentStr;
+                    }
+                }
+            }
+        }
 
-			String currentStr = ReplaceUtility.replace(currentText.toString(),
-					context).trim();
-			// TODO: trim may be not the right choice
-			trace("current text:" + currentStr);
+        m_currentText = null;
 
-			Method method = null;
-			try {
-				method = elementType.castClass.getDeclaredMethod("addText",
-						new Class[] { String.class });
-			} catch (NoSuchMethodException e) {
-				try {
-					method = elementType.castClass.getDeclaredMethod("setText",
-							new Class[] { String.class });
-				} catch (NoSuchMethodException e2) {
-					// do nothing
-				}
-			}
-			if (method != null) {
-				trace(method.getName());
-				try {
-					method.invoke(element.object, new String[] { currentStr });
-				} catch (InvocationTargetException e) {
-					m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-					throw e;
-				}
-			} else {
-				if (String.class.isAssignableFrom(elementType.castClass)) {
-					String str = (String) element.object;
-					if (str.length() != 0) {
-						throw new Exception(
-								lineNumber
-										+ ","
-										+ columnNumber
-										+ ":"
-										+ "String element "
-										+ qName
-										+ " cannot have both PCDATA and an attribute value");
-					} else {
-						element.object = currentStr;
-					}
-				}
-			}
+        if (!m_elementStack.isEmpty())
+        {
 
-		}
+            XmlStackElement parent = (XmlStackElement) m_elementStack.peek();
+            TypeEntry parentType = (TypeEntry) m_types.get(parent.m_qname);
+            if (parentType == null)
+            {
+                parentType = m_defaultType;
+            }
 
-		currentText = null;
-
-		if (!elementStack.isEmpty()) {
-
-			XmlStackElement parent = (XmlStackElement) elementStack.peek();
-			TypeEntry parentType = (TypeEntry) types.get(parent.qname);
-			if(parentType==null) {
-				parentType=defaultType;
-			}		
-
-			String capqName=ClassUtility.capitalize(qName);
-			Method method = null;
-			try {
+            String capqName = ClassUtility.capitalize(qName);
+            Method method = null;
+            try
+            {
 // TODO: OBR PARSER: We should also check for instance class as a parameter.
-				method = parentType.instanceClass.getDeclaredMethod(
-						adderOf(capqName),
-						new Class[] { elementType.castClass });  // instanceClass
-			} catch (NoSuchMethodException e) {
-				trace("NoSuchMethodException: "
-						+ adderOf(capqName) + "("+elementType.castClass.getName()+")");
-				// do nothing
-			}
-			if (method == null)
-                try {
-					method = parentType.instanceClass.getDeclaredMethod(
-						setterOf(capqName),
-						new Class[] { elementType.castClass });
-				} catch (NoSuchMethodException e) {
-					trace("NoSuchMethodException: "
-							+ setterOf(capqName) + "("+elementType.castClass.getName()+")");
-					// do nothing
-				}
-			/*if (method == null)
-				try {
-					method = parentType.castClass.getDeclaredMethod(
-							adderOf(type.castClass),
-							new Class[] { type.castClass });
-				} catch (NoSuchMethodException e) {
-					trace("NoSuchMethodException: " + adderOf(type.castClass)+ "("+type.castClass.getName()+")");
-					// do nothing
-				}
-			if (method == null)
-				try {
-					method = parentType.castClass.getDeclaredMethod(
-							setterOf(type.castClass),
-							new Class[] { type.castClass });
-				} catch (NoSuchMethodException e) {
-					trace("NoSuchMethodException: " + setterOf(type.castClass)+ "("+type.castClass.getName()+")");
-					// do nothing
-				}
-				*/
-			if (method != null) {
-				trace(method.getName());
-				try {
+                method = parentType.m_instanceClass.getDeclaredMethod(
+                    adderOf(capqName),
+                    new Class[]
+                    {
+                        elementType.m_castClass
+                    
+                    });  // instanceClass
+            }
+            catch (NoSuchMethodException e)
+            {
+                trace("NoSuchMethodException: " + adderOf(capqName) + "(" + elementType.m_castClass.getName() + ")");
+            // do nothing
+            }
+            if (method == null)
+            {
+                try
+                {
+                    method = parentType.m_instanceClass.getDeclaredMethod(
+                        setterOf(capqName),
+                        new Class[]
+                        {
+                            elementType.m_castClass
+                        
+                        });
+                }
+                catch (NoSuchMethodException e)
+                {
+                    trace("NoSuchMethodException: " + setterOf(capqName) + "(" + elementType.m_castClass.getName() + ")");
+                // do nothing
+                }
+            /*if (method == null)
+            try {
+            method = parentType.castClass.getDeclaredMethod(
+            adderOf(type.castClass),
+            new Class[] { type.castClass });
+            } catch (NoSuchMethodException e) {
+            trace("NoSuchMethodException: " + adderOf(type.castClass)+ "("+type.castClass.getName()+")");
+            // do nothing
+            }
+            if (method == null)
+            try {
+            method = parentType.castClass.getDeclaredMethod(
+            setterOf(type.castClass),
+            new Class[] { type.castClass });
+            } catch (NoSuchMethodException e) {
+            trace("NoSuchMethodException: " + setterOf(type.castClass)+ "("+type.castClass.getName()+")");
+            // do nothing
+            }
+             */
+            }
+            if (method != null)
+            {
+                trace(method.getName());
+                try
+                {
                     method.setAccessible(true);
-					method.invoke(parent.object, new Object[] { element.object });
-				} catch (InvocationTargetException e) {
-					m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-					throw e;
-				}
-			} else {
-				if (parentType.defaultAddMethod != null) {
-					Class[] parameterTypes=parentType.defaultAddMethod.getParameterTypes();
-					if(parameterTypes.length==2
-						&& parameterTypes[0].isAssignableFrom(String.class)
-						&& parameterTypes[1].isAssignableFrom(elementType.castClass)
-					){
-						parentType.defaultAddMethod.invoke(parent.object,new Object[]{qName, element.object});
-					} else 	if(parameterTypes.length==1
-							&& parameterTypes[0].isAssignableFrom(elementType.castClass)
-						){
-							parentType.defaultAddMethod.invoke(parent.object,new Object[]{element.object});
-					} else {
-						throw new Exception(lineNumber + "," + columnNumber + ":"
-								+ " element " + parent.qname
-								+ " cannot have an attribute " + qName
-								+ " of type " + elementType.castClass);						
-					}
-				} else {
-					throw new Exception(lineNumber + "," + columnNumber + ":"
-							+ " element " + parent.qname
-							+ " cannot have an attribute " + qName
-							+ " of type " + elementType.castClass);
-				}
-			}
+                    method.invoke(parent.m_object, new Object[]
+                        {
+                            element.m_object
+                        
+                        });
+                }
+                catch (InvocationTargetException e)
+                {
+                    m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
+                    throw e;
+                }
+            }
+            else
+            {
+                if (parentType.m_defaultAddMethod != null)
+                {
+                    Class[] parameterTypes = parentType.m_defaultAddMethod.getParameterTypes();
+                    if (parameterTypes.length == 2 && parameterTypes[0].isAssignableFrom(String.class) && parameterTypes[1].isAssignableFrom(elementType.m_castClass))
+                    {
+                        parentType.m_defaultAddMethod.invoke(parent.m_object, new Object[]
+                            {
+                                qName, element.m_object
+                            
+                            });
+                    }
+                    else if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(elementType.m_castClass))
+                    {
+                        parentType.m_defaultAddMethod.invoke(parent.m_object, new Object[]
+                            {
+                                element.m_object
+                            
+                            });
+                    }
+                    else
+                    {
+                        throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " element " + parent.m_qname + " cannot have an attribute " + qName + " of type " + elementType.m_castClass);
+                    }
+                }
+                else
+                {
+                    throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " element " + parent.m_qname + " cannot have an attribute " + qName + " of type " + elementType.m_castClass);
+                }
+            }
 
-		}
+        }
 
-		// invoke the process method
-		try {
-			invokeProcess(element);
-		} catch (Throwable e) {
-			m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e);
-			throw new Exception(e);
-		}
+        // invoke the process method
+        try
+        {
+            invokeProcess(element);
+        }
+        catch (Throwable e)
+        {
+            m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e);
+            throw new Exception(e);
+        }
 
-		trace("END/ (" + lineNumber + "," + columnNumber + "):" + uri + ":"
-				+ qName);
+        trace("END/ (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
+    }
 
-	}
+    public void setTrace(boolean trace)
+    {
+        m_traceFlag = trace;
+    }
 
-	public void setTrace(boolean trace) {
-		this.traceFlag = trace;
-	}
+    private void trace(String msg)
+    {
+        if (m_traceFlag)
+        {
+            m_logger.log(Logger.LOG_DEBUG, msg);
+        }
+    }
 
-	private void trace(String msg) {
-		if (traceFlag)
-			m_logger.log(Logger.LOG_DEBUG, msg);
-	}
+    /**
+     * @see kxml.sax.KXmlSAXHandler#setLineNumber(int)
+     */
+    public void setLineNumber(int lineNumber)
+    {
+        m_lineNumber = lineNumber;
+    }
 
-	/**
-	 * @see kxml.sax.KXmlSAXHandler#setLineNumber(int)
-	 */
-	public void setLineNumber(int lineNumber) {
-		this.lineNumber = lineNumber;
-	}
+    /**
+     * @see kxml.sax.KXmlSAXHandler#setColumnNumber(int)
+     */
+    public void setColumnNumber(int columnNumber)
+    {
+        m_columnNumber = columnNumber;
+    }
 
-	/**
-	 * @see kxml.sax.KXmlSAXHandler#setColumnNumber(int)
-	 */
-	public void setColumnNumber(int columnNumber) {
-		this.columnNumber = columnNumber;
+    /**
+     * @see kxml.sax.KXmlSAXHandler#processingInstruction(java.lang.String,
+     *      java.lang.String)
+     */
+    public void processingInstruction(String target, String data)
+        throws Exception
+    {
+        trace("PI:" + target + ";" + data);
+        trace("ignore PI : " + data);
+    /*		// reuse the kXML parser methods to parser the PI data
+    Reader reader = new StringReader(data);
+    XmlParser parser = new XmlParser(reader);
+    parser.parsePIData();
+    
+    target = parser.getTarget();
+    Map attributes = parser.getAttributes();
+    
+    // get the class
+    Class clazz = (Class) pis.get(target);
+    if (clazz == null) {
+    if (missingPIExceptionFlag)
+    throw new Exception(lineNumber + "," + columnNumber + ":"
+    + "Unknown processing instruction");
+    else {
+    trace(lineNumber + "," + columnNumber + ":"
+    + "No class for PI " + target);
+    return;
+    }
+    }
+    
+    // instanciate a object
+    Object object;
+    Constructor ctor = null;
+    try {
+    ctor = clazz.getConstructor(new Class[] { XmlCommonHandler.class });
+    } catch (NoSuchMethodException e) {
+    // do nothing
+    trace("no constructor with XmlCommonHandler parameter");
+    }
+    try {
+    if (ctor == null) {
+    object = clazz.newInstance();
+    } else {
+    object = ctor.newInstance(new Object[] { this });
+    }
+    } catch (InstantiationException e) {
+    throw new Exception(
+    lineNumber
+    + ","
+    + columnNumber
+    + ":"
+    + "class "
+    + clazz.getName()
+    + " for PI "
+    + target
+    + " should have an empty constructor or a constructor with XmlCommonHandler parameter");
+    } catch (IllegalAccessException e) {
+    throw new Exception(lineNumber + "," + columnNumber + ":"
+    + "illegal access on the constructor " + clazz.getName()
+    + " for PI " + target);
+    }
+    
+    // set the context
+    setObjectContext(object);
+    
+    // TODO: set the parent
+    
+    // invoke setter
+    Iterator iter = attributes.keySet().iterator();
+    while (iter.hasNext()) {
+    String key = (String) iter.next();
+    String value = ReplaceUtility.replace((String) attributes.get(key),
+    context);
+    Method method = null;
+    try {
+    method = clazz.getDeclaredMethod(setterOf(key),
+    new Class[] { String.class });
+    } catch (NoSuchMethodException e) {
+    // do nothing
+    }
+    if (method != null) {
+    trace(method.getName());
+    try {
+    method.invoke(object, new String[] { value });
+    } catch (InvocationTargetException e) {
+    m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
+    throw e;
+    }
+    }
+    
+    }
+    
+    // invoke process
+    try {
+    invokeProcess(object);
+    } catch (Throwable e) {
+    m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e);
+    throw new Exception(e);
+    }
+     */    }
 
-	}
+    public void processingInstructionForMapping(String target, String data)
+        throws Exception
+    {
+        if (target == null)
+        { // TODO kXML
+            if (!data.startsWith(PI_MAPPING))
+            {
+                return;
+            }
+        }
+        else if (!target.equals(PI_MAPPING))
+        {
+            return;        // defaultclass attribute
+        }
+        String datt = "defaultclass=\"";
+        int dstart = data.indexOf(datt);
+        if (dstart != -1)
+        {
+            int dend = data.indexOf("\"", dstart + datt.length());
+            if (dend == -1)
+            {
+                throw new Exception(
+                    m_lineNumber + "," + m_columnNumber + ":" + " \"defaultclass\" attribute in \"mapping\" PI is not quoted");
+            }
+            String classname = data.substring(dstart + datt.length(), dend);
+            Class clazz = null;
+            try
+            {
+                clazz = getClass().getClassLoader().loadClass(classname);
+            }
+            catch (ClassNotFoundException e)
+            {
+                throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " cannot found class " + classname + " for \"mapping\" PI");
+            }
 
-	/**
-	 * @see kxml.sax.KXmlSAXHandler#processingInstruction(java.lang.String,
-	 *      java.lang.String)
-	 */
+            //			 TODO Add method
+            Method defaultdefaultAddMethod = null;
+            setDefaultType(clazz, null, defaultdefaultAddMethod);
+            return;
+        }
 
-	public void processingInstruction(String target, String data)
-			throws Exception {
-		trace("PI:" + target + ";" + data);
-		trace("ignore PI : "+data);
-/*		// reuse the kXML parser methods to parser the PI data
-		Reader reader = new StringReader(data);
-		XmlParser parser = new XmlParser(reader);
-		parser.parsePIData();
+        // element attribute
+        String eatt = "element=\"";
+        int estart = data.indexOf(eatt);
+        if (estart == -1)
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " missing \"element\" attribute in \"mapping\" PI");
+        }
+        int eend = data.indexOf("\"", estart + eatt.length());
+        if (eend == -1)
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " \"element\" attribute in \"mapping\" PI is not quoted");
+        }
+        String element = data.substring(estart + eatt.length(), eend);
 
-		target = parser.getTarget();
-		Map attributes = parser.getAttributes();
+        // element class
+        String catt = "class=\"";
+        int cstart = data.indexOf(catt);
+        if (cstart == -1)
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " missing \"class\" attribute in \"mapping\" PI");
+        }
+        int cend = data.indexOf("\"", cstart + catt.length());
+        if (cend == -1)
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " \"class\" attribute in \"mapping\" PI is not quoted");
+        }
+        String classname = data.substring(cstart + catt.length(), cend);
 
-		// get the class
-		Class clazz = (Class) pis.get(target);
-		if (clazz == null) {
-			if (missingPIExceptionFlag)
-				throw new Exception(lineNumber + "," + columnNumber + ":"
-						+ "Unknown processing instruction");
-			else {
-				trace(lineNumber + "," + columnNumber + ":"
-						+ "No class for PI " + target);
-				return;
-			}
-		}
+        // element cast (optional)
+        String castname = null;
+        String castatt = "cast=\"";
+        int caststart = data.indexOf(castatt);
+        if (caststart != -1)
+        {
+            int castend = data.indexOf("\"", cstart + castatt.length());
+            if (castend == -1)
+            {
+                throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " \"cast\" attribute in \"mapping\" PI is not quoted");
+            }
+            castname = data.substring(caststart + castatt.length(), castend);
+        }
 
-		// instanciate a object
-		Object object;
-		Constructor ctor = null;
-		try {
-			ctor = clazz.getConstructor(new Class[] { XmlCommonHandler.class });
-		} catch (NoSuchMethodException e) {
-			// do nothing
-			trace("no constructor with XmlCommonHandler parameter");
-		}
-		try {
-			if (ctor == null) {
-				object = clazz.newInstance();
-			} else {
-				object = ctor.newInstance(new Object[] { this });
-			}
-		} catch (InstantiationException e) {
-			throw new Exception(
-					lineNumber
-							+ ","
-							+ columnNumber
-							+ ":"
-							+ "class "
-							+ clazz.getName()
-							+ " for PI "
-							+ target
-							+ " should have an empty constructor or a constructor with XmlCommonHandler parameter");
-		} catch (IllegalAccessException e) {
-			throw new Exception(lineNumber + "," + columnNumber + ":"
-					+ "illegal access on the constructor " + clazz.getName()
-					+ " for PI " + target);
-		}
+        Class clazz = null;
+        try
+        {
+            clazz = getClass().getClassLoader().loadClass(classname);
+        }
+        catch (ClassNotFoundException e)
+        {
+            throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " cannot found class " + classname + " for \"mapping\" PI");
+        }
 
-		// set the context
-		setObjectContext(object);
+        Class castClazz = null;
+        if (castname != null)
+        {
+            try
+            {
+                clazz = getClass().getClassLoader().loadClass(castname);
+            }
+            catch (ClassNotFoundException e)
+            {
+                throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " cannot found cast class " + classname + " for \"mapping\" PI");
+            }        // TODO Add method
+        }
+        Method defaultAddMethod = null;
 
-		// TODO: set the parent
-
-		// invoke setter
-		Iterator iter = attributes.keySet().iterator();
-		while (iter.hasNext()) {
-			String key = (String) iter.next();
-			String value = ReplaceUtility.replace((String) attributes.get(key),
-					context);
-			Method method = null;
-			try {
-				method = clazz.getDeclaredMethod(setterOf(key),
-						new Class[] { String.class });
-			} catch (NoSuchMethodException e) {
-				// do nothing
-			}
-			if (method != null) {
-				trace(method.getName());
-				try {
-					method.invoke(object, new String[] { value });
-				} catch (InvocationTargetException e) {
-					m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
-					throw e;
-				}
-			}
-
-		}
-
-		// invoke process
-		try {
-			invokeProcess(object);
-		} catch (Throwable e) {
-			m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e);
-			throw new Exception(e);
-		}
-*/	}
-
-	public void processingInstructionForMapping(String target, String data)
-			throws Exception {
-		
-		
-		if (target == null) { // TODO kXML
-			if (!data.startsWith(PI_MAPPING))
-				return;
-		} else if (!target.equals(PI_MAPPING))
-			return;
-
-		// defaultclass attribute
-		String datt = "defaultclass=\"";
-		int dstart = data.indexOf(datt);
-		if (dstart != -1) {
-			int dend = data.indexOf("\"", dstart + datt.length());
-			if (dend == -1)
-				throw new Exception(
-						lineNumber
-								+ ","
-								+ columnNumber
-								+ ":"
-								+ " \"defaultclass\" attribute in \"mapping\" PI is not quoted");
-
-			String classname = data.substring(dstart + datt.length(), dend);
-			Class clazz = null;
-			try {
-				clazz = getClass().getClassLoader().loadClass(classname);
-			} catch (ClassNotFoundException e) {
-				throw new Exception(lineNumber + "," + columnNumber + ":"
-						+ " cannot found class " + classname
-						+ " for \"mapping\" PI");
-			}
-
-			//			 TODO Add method
-			Method defaultdefaultAddMethod=null;
-			setDefaultType(clazz, null,defaultdefaultAddMethod);
-			return;
-		}
-
-		// element attribute
-		String eatt = "element=\"";
-		int estart = data.indexOf(eatt);
-		if (estart == -1)
-			throw new Exception(lineNumber + "," + columnNumber + ":"
-					+ " missing \"element\" attribute in \"mapping\" PI");
-		int eend = data.indexOf("\"", estart + eatt.length());
-		if (eend == -1)
-			throw new Exception(lineNumber + "," + columnNumber + ":"
-					+ " \"element\" attribute in \"mapping\" PI is not quoted");
-
-		String element = data.substring(estart + eatt.length(), eend);
-
-		// element class
-		String catt = "class=\"";
-		int cstart = data.indexOf(catt);
-		if (cstart == -1)
-			throw new Exception(lineNumber + "," + columnNumber + ":"
-					+ " missing \"class\" attribute in \"mapping\" PI");
-		int cend = data.indexOf("\"", cstart + catt.length());
-		if (cend == -1)
-			throw new Exception(lineNumber + "," + columnNumber + ":"
-					+ " \"class\" attribute in \"mapping\" PI is not quoted");
-
-		String classname = data.substring(cstart + catt.length(), cend);
-
-		// element cast (optional)
-		String castname = null;
-		String castatt = "cast=\"";
-		int caststart = data.indexOf(castatt);
-		if (caststart != -1) {
-			int castend = data.indexOf("\"", cstart + castatt.length());
-			if (castend == -1)
-				throw new Exception(lineNumber + "," + columnNumber + ":"
-						+ " \"cast\" attribute in \"mapping\" PI is not quoted");
-
-			castname = data.substring(caststart + castatt.length(), castend);
-		}
-
-		Class clazz = null;
-		try {
-			clazz = getClass().getClassLoader().loadClass(classname);
-		} catch (ClassNotFoundException e) {
-			throw new Exception(lineNumber + "," + columnNumber + ":"
-					+ " cannot found class " + classname
-					+ " for \"mapping\" PI");
-		}
-
-		Class castClazz = null;
-		if (castname != null)
-			try {
-				clazz = getClass().getClassLoader().loadClass(castname);
-			} catch (ClassNotFoundException e) {
-				throw new Exception(lineNumber + "," + columnNumber + ":"
-						+ " cannot found cast class " + classname
-						+ " for \"mapping\" PI");
-			}
-
-		// TODO Add method
-		Method defaultAddMethod=null;
-			
-		addType(element, clazz, castClazz, defaultAddMethod);
-	}
+        addType(element, clazz, castClazz, defaultAddMethod);
+    }
 }
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java
index 6cc5531..f452fab 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java
@@ -29,30 +29,32 @@
 /**
  * handles the metadata in XML format
  */
-public class XmlMetadataHandler extends MetadataHandler {
-
-	public XmlMetadataHandler(Logger logger) {
+public class XmlMetadataHandler extends MetadataHandler
+{
+    public XmlMetadataHandler(Logger logger)
+    {
         super(logger);
     }
-	
-	/**
-	* Called to parse the InputStream and set bundle list and package hash map
-	*/
-	public void parse(InputStream istream) throws ParserConfigurationException, IOException, SAXException {
-     // Parse the Meta-Data
 
-	 	ContentHandler contenthandler = (ContentHandler) handler;
+    /**
+     * Called to parse the InputStream and set bundle list and package hash map
+     */
+    public void parse(InputStream istream) throws ParserConfigurationException, IOException, SAXException
+    {
+        // Parse the Meta-Data
 
-		InputSource is = new InputSource(istream);
+        ContentHandler contenthandler = (ContentHandler) m_handler;
+
+        InputSource is = new InputSource(istream);
 
         SAXParserFactory spf = SAXParserFactory.newInstance();
         spf.setValidating(false);
 
         SAXParser saxParser = spf.newSAXParser();
-		
+
         XMLReader xmlReader = null;
         xmlReader = saxParser.getXMLReader();
         xmlReader.setContentHandler(contenthandler);
         xmlReader.parse(is);
     }
-}
+}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java
index e5b6c4f..4997df6 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java
@@ -23,52 +23,53 @@
 /**
  * Interface for SAX handler with kXML
  */
-public interface KXml2SAXHandler {
+public interface KXml2SAXHandler
+{
+    /**
+     * Method called when parsing text
+     *
+     * @param   ch
+     * @param   offset
+     * @param   length
+     * @exception   SAXException
+     */
+    public void characters(char[] ch, int offset, int length) throws Exception;
 
-	/**
-	* Method called when parsing text
-	*
-	* @param   ch
-	* @param   offset
-	* @param   length
-	* @exception   SAXException
-	*/
-	public void characters(char[] ch, int offset, int length) throws Exception;
+    /**
+     * Method called when a tag opens
+     *
+     * @param   uri
+     * @param   localName
+     * @param   qName
+     * @param   attrib
+     * @exception   SAXException
+     **/
+    public void startElement(
+        String uri,
+        String localName,
+        String qName,
+        Properties attrib)
+        throws Exception;
 
-	/**
-	* Method called when a tag opens
-	*
-	* @param   uri
-	* @param   localName
-	* @param   qName
-	* @param   attrib
-	* @exception   SAXException
-	**/
-	public void startElement(
-		String uri,
-		String localName,
-		String qName,
-		Properties attrib)
-		throws Exception;
-	/**
-	* Method called when a tag closes
-	*
-	* @param   uri
-	* @param   localName
-	* @param   qName
-	* @exception   SAXException
-	*/
-	public void endElement(
-		java.lang.String uri,
-		java.lang.String localName,
-		java.lang.String qName)
-		throws Exception;
+    /**
+     * Method called when a tag closes
+     *
+     * @param   uri
+     * @param   localName
+     * @param   qName
+     * @exception   SAXException
+     */
+    public void endElement(
+        java.lang.String uri,
+        java.lang.String localName,
+        java.lang.String qName)
+        throws Exception;
 
-	public void processingInstruction(String target,
-									  String data)
-							   throws Exception;
-		
-	public void setLineNumber(int lineNumber);
+    public void processingInstruction(String target,
+        String data)
+        throws Exception;
 
-	public void setColumnNumber(int columnNumber);
+    public void setLineNumber(int lineNumber);
+
+    public void setColumnNumber(int columnNumber);
 }
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java
index 089fb73..04dd8d1 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java
@@ -28,54 +28,66 @@
 /**
  * The KXml2SAXParser extends the XmlParser from kxml2 (which  does not take into account the DTD).
  */
-public class KXml2SAXParser extends KXmlParser {
-	
-	public String uri="uri";
+public class KXml2SAXParser extends KXmlParser
+{
+    public String m_uri = "uri";
 
-	/**
-	* The constructor for a parser, it receives a java.io.Reader.
-	*
-	* @param   reader  The reader
-	* @throws XmlPullParserException 
-	*/
-	public KXml2SAXParser(Reader reader) throws XmlPullParserException {
-		super();
-	    setInput(reader);
-	}
-	
-	/**
-	* parse from the reader provided in the constructor, and call
-	* the startElement and endElement in the handler
-	*
-	* @param   handler  The handler
-	* @exception   Exception thrown by the superclass
-	*/
-	public void parseXML(KXml2SAXHandler handler) throws Exception {
+    /**
+     * The constructor for a parser, it receives a java.io.Reader.
+     *
+     * @param   reader  The reader
+     * @throws XmlPullParserException 
+     */
+    public KXml2SAXParser(Reader reader) throws XmlPullParserException
+    {
+        super();
+        setInput(reader);
+    }
 
-		while (next() != XmlPullParser.END_DOCUMENT) {
-			handler.setLineNumber(getLineNumber());
-			handler.setColumnNumber(getColumnNumber());
-			if (getEventType() == XmlPullParser.START_TAG) {
-				Properties props = new Properties();
-				for (int i = 0; i < getAttributeCount(); i++) {
-					props.put(getAttributeName(i), getAttributeValue(i));
-				}
-				handler.startElement(
-					getNamespace(),
-					getName(),
-					getName(),
-					props);
-			} else if (getEventType() == XmlPullParser.END_TAG) {
-				handler.endElement(getNamespace(), getName(), getName());
-			} else if (getEventType() == XmlPullParser.TEXT) {
-				String text = getText();
-				handler.characters(text.toCharArray(),0,text.length());
-			} else if (getEventType() == XmlPullParser.PROCESSING_INSTRUCTION) {
-				// TODO extract the target from the evt.getText()
-				handler.processingInstruction(null,getText()); 
-			} else {
-				// do nothing
-			}
-		}
-	}	
-}
+    /**
+     * parse from the reader provided in the constructor, and call
+     * the startElement and endElement in the handler
+     *
+     * @param   handler  The handler
+     * @exception   Exception thrown by the superclass
+     */
+    public void parseXML(KXml2SAXHandler handler) throws Exception
+    {
+        while (next() != XmlPullParser.END_DOCUMENT)
+        {
+            handler.setLineNumber(getLineNumber());
+            handler.setColumnNumber(getColumnNumber());
+            if (getEventType() == XmlPullParser.START_TAG)
+            {
+                Properties props = new Properties();
+                for (int i = 0; i < getAttributeCount(); i++)
+                {
+                    props.put(getAttributeName(i), getAttributeValue(i));
+                }
+                handler.startElement(
+                    getNamespace(),
+                    getName(),
+                    getName(),
+                    props);
+            }
+            else if (getEventType() == XmlPullParser.END_TAG)
+            {
+                handler.endElement(getNamespace(), getName(), getName());
+            }
+            else if (getEventType() == XmlPullParser.TEXT)
+            {
+                String text = getText();
+                handler.characters(text.toCharArray(), 0, text.length());
+            }
+            else if (getEventType() == XmlPullParser.PROCESSING_INSTRUCTION)
+            {
+                // TODO extract the target from the evt.getText()
+                handler.processingInstruction(null, getText());
+            }
+            else
+            {
+                // do nothing
+            }
+        }
+    }
+}
\ No newline at end of file
