diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Capability.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Capability.java
index e8d4bee..ead50ab 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Capability.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Capability.java
@@ -1,123 +1,123 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-
-/**
- * This class describe and store capability node.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class Capability
-{
-
-    /**
-     * m_name: name of the capability.
-     */
-    private String m_name;
-
-    /**
-     * m_p: List of PElement.
-     */
-    private List m_p = new ArrayList();
-
-
-    /**
-     * get the name attribute.
-     * 
-     * @return name attribute
-     */
-    public String getName()
-    {
-        return m_name;
-    }
-
-
-    /**
-     * set the name attribute.
-     * 
-     * @param name new name value
-     *            
-     */
-    public void setName( String name )
-    {
-        this.m_name = name;
-    }
-
-
-    /**
-     * return the capabilities.
-     * 
-     * @return List of PElement
-     */
-    public List getP()
-    {
-        return m_p;
-    }
-
-
-    /**
-     * set the capabilities.
-     * 
-     * @param mp List of PElement
-     *            
-     */
-    public void setP( List mp )
-    {
-        this.m_p = mp;
-    }
-
-
-    /**
-     * add one element in List.
-     * 
-     * @param pelement PElement
-     *            
-     */
-    public void addP( PElement pelement )
-    {
-        m_p.add( pelement );
-    }
-
-
-    /**
-     * transform this object to Node.
-     * 
-     * @param father father document for create Node
-     * @return node
-     */
-    public Node getNode( Document father )
-    {
-        Element capability = father.createElement( "capability" );
-        capability.setAttribute( "name", this.getName() );
-        for ( int i = 0; i < this.getP().size(); i++ )
-        {
-            capability.appendChild( ( ( PElement ) ( this.getP().get( i ) ) ).getNode( father ) );
-        }
-        return capability;
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * This class describe and store capability node.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Capability
+{
+
+    /**
+     * m_name: name of the capability.
+     */
+    private String m_name;
+
+    /**
+     * m_p: List of PElement.
+     */
+    private List m_p = new ArrayList();
+
+
+    /**
+     * get the name attribute.
+     * 
+     * @return name attribute
+     */
+    public String getName()
+    {
+        return m_name;
+    }
+
+
+    /**
+     * set the name attribute.
+     * 
+     * @param name new name value
+     *            
+     */
+    public void setName( String name )
+    {
+        this.m_name = name;
+    }
+
+
+    /**
+     * return the capabilities.
+     * 
+     * @return List of PElement
+     */
+    public List getP()
+    {
+        return m_p;
+    }
+
+
+    /**
+     * set the capabilities.
+     * 
+     * @param mp List of PElement
+     *            
+     */
+    public void setP( List mp )
+    {
+        this.m_p = mp;
+    }
+
+
+    /**
+     * add one element in List.
+     * 
+     * @param pelement PElement
+     *            
+     */
+    public void addP( PElement pelement )
+    {
+        m_p.add( pelement );
+    }
+
+
+    /**
+     * transform this object to Node.
+     * 
+     * @param father father document for create Node
+     * @return node
+     */
+    public Node getNode( Document father )
+    {
+        Element capability = father.createElement( "capability" );
+        capability.setAttribute( "name", this.getName() );
+        for ( int i = 0; i < this.getP().size(); i++ )
+        {
+            capability.appendChild( ( ( PElement ) ( this.getP().get( i ) ) ).getNode( father ) );
+        }
+        return capability;
+    }
+
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Category.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Category.java
index 990256b..c50e4b9 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Category.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Category.java
@@ -1,73 +1,73 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-
-/**
- * describe and store category node.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-
-public class Category
-{
-    /**
-     * id of the category.
-     */
-    private String m_id;
-
-
-    /**
-     * get the id attribute.
-     * 
-     * @return id
-     */
-    public String getId()
-    {
-        return m_id;
-    }
-
-
-    /**
-     * set the id attribute.
-     * @param id new id value
-     */
-    public void setId( String id )
-    {
-        this.m_id = id;
-    }
-
-
-    /**
-     * transform this object to node.
-     * @param father father document for create Node
-     * @return node
-     */
-    public Node getNode( Document father )
-    {
-        Element category = father.createElement( "category" );
-        category.setAttribute( "id", this.getId() );
-        return category;
-    }
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * describe and store category node.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+
+public class Category
+{
+    /**
+     * id of the category.
+     */
+    private String m_id;
+
+
+    /**
+     * get the id attribute.
+     * 
+     * @return id
+     */
+    public String getId()
+    {
+        return m_id;
+    }
+
+
+    /**
+     * set the id attribute.
+     * @param id new id value
+     */
+    public void setId( String id )
+    {
+        this.m_id = id;
+    }
+
+
+    /**
+     * transform this object to node.
+     * @param father father document for create Node
+     * @return node
+     */
+    public Node getNode( Document father )
+    {
+        Element category = father.createElement( "category" );
+        category.setAttribute( "id", this.getId() );
+        return category;
+    }
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Config.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Config.java
index 16cbe92..54952be 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Config.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Config.java
@@ -1,91 +1,91 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-/**
- * this class is used to store some user information about configuration of the plugin.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- *
- */
-public class Config
-{
-
-    /**
-     * use relative path or not.
-     */
-    private boolean m_pathRelative; // use relative or absolute path in repository.xml
-
-    /**
-     * deploy file or not.
-     */
-    private boolean m_fileRemote; // deploy file on remote server
-
-
-    /**
-     * constructor: set default configuration: use relative path and don't upload file.
-     *
-     */
-    public Config()
-    {
-        // default configuration
-        m_pathRelative = true;
-        m_fileRemote = false;
-    }
-
-
-    /**
-     * set relativePath attribute.
-     * @param value new value of attribute
-     */
-    public void setPathRelative( boolean value )
-    {
-        m_pathRelative = value;
-    }
-
-
-    /**
-     * set fileRemote attribute.
-     * @param value new value of attribute
-     */
-    public void setRemotely( boolean value )
-    {
-        m_fileRemote = value;
-    }
-
-
-    /**
-     * get use path relative.
-     * @return true if plugin use relative path, else false
-     */
-    public boolean isPathRelative()
-    {
-        return m_pathRelative;
-    }
-
-
-    /**
-     * get if use upload file.
-     * @return true if the file will be uploaded, else false
-     */
-    public boolean isRemotely()
-    {
-        return m_fileRemote;
-    }
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+/**
+ * this class is used to store some user information about configuration of the plugin.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class Config
+{
+
+    /**
+     * use relative path or not.
+     */
+    private boolean m_pathRelative; // use relative or absolute path in repository.xml
+
+    /**
+     * deploy file or not.
+     */
+    private boolean m_fileRemote; // deploy file on remote server
+
+
+    /**
+     * constructor: set default configuration: use relative path and don't upload file.
+     *
+     */
+    public Config()
+    {
+        // default configuration
+        m_pathRelative = true;
+        m_fileRemote = false;
+    }
+
+
+    /**
+     * set relativePath attribute.
+     * @param value new value of attribute
+     */
+    public void setPathRelative( boolean value )
+    {
+        m_pathRelative = value;
+    }
+
+
+    /**
+     * set fileRemote attribute.
+     * @param value new value of attribute
+     */
+    public void setRemotely( boolean value )
+    {
+        m_fileRemote = value;
+    }
+
+
+    /**
+     * get use path relative.
+     * @return true if plugin use relative path, else false
+     */
+    public boolean isPathRelative()
+    {
+        return m_pathRelative;
+    }
+
+
+    /**
+     * get if use upload file.
+     * @return true if the file will be uploaded, else false
+     */
+    public boolean isRemotely()
+    {
+        return m_fileRemote;
+    }
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ExtractBindexInfo.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ExtractBindexInfo.java
index b416e32..679dcc0 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ExtractBindexInfo.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ExtractBindexInfo.java
@@ -1,322 +1,322 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.plugin.MojoExecutionException;
-import org.osgi.impl.bundle.obr.resource.BundleInfo;
-import org.osgi.impl.bundle.obr.resource.CapabilityImpl;
-import org.osgi.impl.bundle.obr.resource.RepositoryImpl;
-import org.osgi.impl.bundle.obr.resource.RequirementImpl;
-import org.osgi.impl.bundle.obr.resource.ResourceImpl;
-import org.osgi.impl.bundle.obr.resource.VersionRange;
-
-
-/**
- * this class is used to configure bindex and get information built by bindex about targeted bundle.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ExtractBindexInfo
-{
-
-    /**
-     * attribute get from bindex which describe targeted resource.
-     */
-    private ResourceImpl m_resource;
-
-
-    /**
-     * configure bindex and build information.
-     * @param repoFilename URI on OBR descriptor file
-     * @param outFile path on targeted jar-file
-     * @throws MojoExecutionException occurs if bindex configuration failed
-     */
-    public ExtractBindexInfo( URI repoFilename, String outFile ) throws MojoExecutionException
-    {
-
-        this.m_resource = null;
-        RepositoryImpl repository = null;
-        try
-        {
-            repository = new RepositoryImpl( new File( repoFilename ).getAbsoluteFile().toURL() );
-        }
-        catch ( MalformedURLException e )
-        {
-            e.printStackTrace();
-            throw new MojoExecutionException( "MalformedURLException" );
-        }
-        BundleInfo info = null;
-        try
-        {
-            info = new BundleInfo( repository, new File( outFile ) );
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-            throw new MojoExecutionException( "Exception" );
-        }
-
-        try
-        {
-            m_resource = info.build();
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-            throw new MojoExecutionException( "Exception" );
-        }
-    }
-
-
-    /**
-     * transform logical operator in xml syntax.
-     * @param filter string which contains logical operator
-     * @return string in correct xml syntax
-     */
-    private String parseFilter( String filter )
-    {
-        filter.replaceAll( "&", "&amp" );
-        filter.replaceAll( ">=", "&gt" );
-
-        return filter;
-    }
-
-
-    /**
-     * extract capabilities from bindex information.
-     * @return bundle capabilities List
-     */
-    public List getCapabilities()
-    {
-        List list = new ArrayList();
-        Collection res = m_resource.getCapabilityList();
-        Iterator it = res.iterator();
-        while ( it.hasNext() )
-        {
-            Capability capability = new Capability();
-            CapabilityImpl ci = ( CapabilityImpl ) it.next();
-            capability.setName( ci.getName() );
-            // System.out.println(ci.getName()) ;
-            if ( !( ci.getName().compareTo( "bundle" ) == 0 ) )
-            {
-                Map properties = ci.getProperties();
-                for ( Iterator k = properties.keySet().iterator(); k.hasNext(); )
-                {
-                    PElement p = new PElement();
-                    String key = ( String ) k.next();
-                    List values = ( List ) properties.get( key );
-                    for ( Iterator v = values.iterator(); v.hasNext(); )
-                    {
-                        Object value = v.next();
-                        p.setN( key );
-                        if ( value != null )
-                        {
-                            p.setV( value.toString() );
-                        }
-                        else
-                        {
-                            System.out.println( "Missing value " + key );
-                        }
-                        String type = null;
-                        if ( value instanceof Number )
-                        {
-                            type = "number";
-                        }
-                        else
-                        {
-                            if ( value.getClass() == VersionRange.class )
-                            {
-                                type = "version";
-                            }
-                        }
-                        if ( type != null )
-                        {
-                            p.setT( type );
-                        }
-                    }
-                    capability.addP( p );
-                }
-
-                list.add( capability );
-            }
-        }
-        return list;
-    }
-
-
-    /**
-     * extract requirement from bindex information.
-     * @return bundle requirement List
-     */
-    public List getRequirement()
-    {
-        List list = new ArrayList();
-        Collection res = m_resource.getRequirementList();
-        Iterator it = res.iterator();
-        while ( it.hasNext() )
-        {
-            RequirementImpl ci = ( RequirementImpl ) it.next();
-            Require require = new Require();
-
-            require.setExtend( String.valueOf( ci.isExtend() ) );
-            require.setMultiple( String.valueOf( ci.isMultiple() ) );
-            require.setOptional( String.valueOf( ci.isOptional() ) );
-            require.setName( ci.getName() );
-            require.setFilter( this.parseFilter( ci.getFilter() ) );
-            require.setValue( ci.getComment() );
-            list.add( require );
-        }
-        return list;
-    }
-
-
-    /**
-     * extract symbolic name from bindex information.
-     * @return bundle symbolic name
-     */
-    public String getSymbolicName()
-    {
-        return m_resource.getSymbolicName();
-    }
-
-
-    /**
-     * extract version from bindex information.
-     * @return bundle version
-     */
-    public String getVersion()
-    {
-        if ( m_resource.getVersion() != null )
-        {
-            return m_resource.getVersion().toString();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * extract presentation name from bindex information.
-     * @return bundle presentation name
-     */
-    public String getPresentationName()
-    {
-        return m_resource.getPresentationName();
-    }
-
-
-    /**
-     * extract copyright from bindex information.
-     * @return bundle copyright
-     */
-    public String getCopyright()
-    {
-        return m_resource.getCopyright();
-    }
-
-
-    /**
-     * extract description from bindex information.
-     * @return bundle description
-     */
-    public String getDescription()
-    {
-        return m_resource.getDescription();
-    }
-
-
-    /**
-     * extract documentation from bindex information.
-     * @return bundle documentation
-     */
-    public String getDocumentation()
-    {
-        if ( m_resource.getDocumentation() != null )
-        {
-            return m_resource.getDocumentation().toString();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * extract license from bindex information.
-     * @return bundle license
-     */
-    public String getLicense()
-    {
-        if ( m_resource.getLicense() != null )
-        {
-            return m_resource.getLicense().toString();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * extract source from bindex information.
-     * @return bundle source
-     */
-    public String getSource()
-    {
-        if ( m_resource.getSource() != null )
-        {
-            return m_resource.getSource().toString();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * extract source from bindex information.
-     * @return bundle source
-     */
-    public String getId()
-    {
-        if ( m_resource.getId() != null )
-        {
-            return m_resource.getId();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.osgi.impl.bundle.obr.resource.BundleInfo;
+import org.osgi.impl.bundle.obr.resource.CapabilityImpl;
+import org.osgi.impl.bundle.obr.resource.RepositoryImpl;
+import org.osgi.impl.bundle.obr.resource.RequirementImpl;
+import org.osgi.impl.bundle.obr.resource.ResourceImpl;
+import org.osgi.impl.bundle.obr.resource.VersionRange;
+
+
+/**
+ * this class is used to configure bindex and get information built by bindex about targeted bundle.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ExtractBindexInfo
+{
+
+    /**
+     * attribute get from bindex which describe targeted resource.
+     */
+    private ResourceImpl m_resource;
+
+
+    /**
+     * configure bindex and build information.
+     * @param repoFilename URI on OBR descriptor file
+     * @param outFile path on targeted jar-file
+     * @throws MojoExecutionException occurs if bindex configuration failed
+     */
+    public ExtractBindexInfo( URI repoFilename, String outFile ) throws MojoExecutionException
+    {
+
+        this.m_resource = null;
+        RepositoryImpl repository = null;
+        try
+        {
+            repository = new RepositoryImpl( new File( repoFilename ).getAbsoluteFile().toURL() );
+        }
+        catch ( MalformedURLException e )
+        {
+            e.printStackTrace();
+            throw new MojoExecutionException( "MalformedURLException" );
+        }
+        BundleInfo info = null;
+        try
+        {
+            info = new BundleInfo( repository, new File( outFile ) );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+            throw new MojoExecutionException( "Exception" );
+        }
+
+        try
+        {
+            m_resource = info.build();
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+            throw new MojoExecutionException( "Exception" );
+        }
+    }
+
+
+    /**
+     * transform logical operator in xml syntax.
+     * @param filter string which contains logical operator
+     * @return string in correct xml syntax
+     */
+    private String parseFilter( String filter )
+    {
+        filter.replaceAll( "&", "&amp" );
+        filter.replaceAll( ">=", "&gt" );
+
+        return filter;
+    }
+
+
+    /**
+     * extract capabilities from bindex information.
+     * @return bundle capabilities List
+     */
+    public List getCapabilities()
+    {
+        List list = new ArrayList();
+        Collection res = m_resource.getCapabilityList();
+        Iterator it = res.iterator();
+        while ( it.hasNext() )
+        {
+            Capability capability = new Capability();
+            CapabilityImpl ci = ( CapabilityImpl ) it.next();
+            capability.setName( ci.getName() );
+            // System.out.println(ci.getName()) ;
+            if ( !( ci.getName().compareTo( "bundle" ) == 0 ) )
+            {
+                Map properties = ci.getProperties();
+                for ( Iterator k = properties.keySet().iterator(); k.hasNext(); )
+                {
+                    PElement p = new PElement();
+                    String key = ( String ) k.next();
+                    List values = ( List ) properties.get( key );
+                    for ( Iterator v = values.iterator(); v.hasNext(); )
+                    {
+                        Object value = v.next();
+                        p.setN( key );
+                        if ( value != null )
+                        {
+                            p.setV( value.toString() );
+                        }
+                        else
+                        {
+                            System.out.println( "Missing value " + key );
+                        }
+                        String type = null;
+                        if ( value instanceof Number )
+                        {
+                            type = "number";
+                        }
+                        else
+                        {
+                            if ( value.getClass() == VersionRange.class )
+                            {
+                                type = "version";
+                            }
+                        }
+                        if ( type != null )
+                        {
+                            p.setT( type );
+                        }
+                    }
+                    capability.addP( p );
+                }
+
+                list.add( capability );
+            }
+        }
+        return list;
+    }
+
+
+    /**
+     * extract requirement from bindex information.
+     * @return bundle requirement List
+     */
+    public List getRequirement()
+    {
+        List list = new ArrayList();
+        Collection res = m_resource.getRequirementList();
+        Iterator it = res.iterator();
+        while ( it.hasNext() )
+        {
+            RequirementImpl ci = ( RequirementImpl ) it.next();
+            Require require = new Require();
+
+            require.setExtend( String.valueOf( ci.isExtend() ) );
+            require.setMultiple( String.valueOf( ci.isMultiple() ) );
+            require.setOptional( String.valueOf( ci.isOptional() ) );
+            require.setName( ci.getName() );
+            require.setFilter( this.parseFilter( ci.getFilter() ) );
+            require.setValue( ci.getComment() );
+            list.add( require );
+        }
+        return list;
+    }
+
+
+    /**
+     * extract symbolic name from bindex information.
+     * @return bundle symbolic name
+     */
+    public String getSymbolicName()
+    {
+        return m_resource.getSymbolicName();
+    }
+
+
+    /**
+     * extract version from bindex information.
+     * @return bundle version
+     */
+    public String getVersion()
+    {
+        if ( m_resource.getVersion() != null )
+        {
+            return m_resource.getVersion().toString();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * extract presentation name from bindex information.
+     * @return bundle presentation name
+     */
+    public String getPresentationName()
+    {
+        return m_resource.getPresentationName();
+    }
+
+
+    /**
+     * extract copyright from bindex information.
+     * @return bundle copyright
+     */
+    public String getCopyright()
+    {
+        return m_resource.getCopyright();
+    }
+
+
+    /**
+     * extract description from bindex information.
+     * @return bundle description
+     */
+    public String getDescription()
+    {
+        return m_resource.getDescription();
+    }
+
+
+    /**
+     * extract documentation from bindex information.
+     * @return bundle documentation
+     */
+    public String getDocumentation()
+    {
+        if ( m_resource.getDocumentation() != null )
+        {
+            return m_resource.getDocumentation().toString();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * extract license from bindex information.
+     * @return bundle license
+     */
+    public String getLicense()
+    {
+        if ( m_resource.getLicense() != null )
+        {
+            return m_resource.getLicense().toString();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * extract source from bindex information.
+     * @return bundle source
+     */
+    public String getSource()
+    {
+        if ( m_resource.getSource() != null )
+        {
+            return m_resource.getSource().toString();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * extract source from bindex information.
+     * @return bundle source
+     */
+    public String getId()
+    {
+        if ( m_resource.getId() != null )
+        {
+            return m_resource.getId();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrCleanRepo.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrCleanRepo.java
index d61a839..178b817 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrCleanRepo.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrCleanRepo.java
@@ -1,331 +1,331 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Properties;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-
-/**
- * Clean an OBR repository by finding and removing missing resources. 
- * @goal clean
- * @phase install
- * @requiresDependencyResolution compile
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ObrCleanRepo extends AbstractMojo
-{
-
-    /**
-     * OBR Repository.
-     * 
-     * @parameter expression="${obrRepository}"
-     */
-    private String obrRepository;
-
-    /**
-     * Local Repository.
-     * 
-     * @parameter expression="${localRepository}"
-     * @required
-     * @readonly
-     */
-    private ArtifactRepository localRepository;
-
-
-    public void execute() throws MojoExecutionException
-    {
-        // If no OBR repository, return
-        if ( "NONE".equalsIgnoreCase( obrRepository ) )
-        {
-            return;
-        }
-
-        try
-        {
-            // Compute local repository location
-            String localRepoPath = localRepository.getBasedir();
-            PathFile repositoryXml = normalizeRepositoryPath( obrRepository, localRepoPath );
-
-            // Check if the file exist
-            if ( !repositoryXml.isExists() )
-            {
-                getLog().error( "The repository file " + repositoryXml.getAbsoluteFilename() + " does not exist" );
-                return;
-            }
-
-            Document doc = parseFile( repositoryXml.getFile(), initConstructor() );
-            Node finalDocument = cleanDocument( doc.getDocumentElement() ); //Analyze existing repository.
-
-            if ( finalDocument == null )
-            {
-                getLog().info( "Nothing to clean in " + repositoryXml.getAbsoluteFilename() );
-            }
-            else
-            {
-                getLog().info( "Cleaning..." );
-                writeToFile( repositoryXml.getUri(), finalDocument ); // Write the new file
-                getLog().info( "Repository " + repositoryXml.getAbsoluteFilename() + " updated" );
-            }
-        }
-        catch ( Exception e )
-        {
-            getLog().error( "Exception while cleaning the OBR repository file : " + e.getLocalizedMessage(), e );
-        }
-    }
-
-
-    /**
-     * Analyze the given XML tree (DOM of the repository file) and remove missing resources.
-     * @param elem : the input XML tree
-     * @return the cleaned XML tree
-     */
-    private Element cleanDocument( Element elem )
-    {
-        NodeList nodes = elem.getElementsByTagName( "resource" );
-        List toRemove = new ArrayList();
-
-        // First, look for missing resources
-        for ( int i = 0; i < nodes.getLength(); i++ )
-        {
-            Element n = ( Element ) nodes.item( i );
-            String value = n.getAttribute( "uri" );
-
-            String localRepoPath = localRepository.getBasedir();
-            File file = new File( localRepoPath, value );
-
-            if ( !file.exists() )
-            {
-                getLog().info(
-                    "The bundle " + n.getAttribute( "presentationname" ) + " - " + n.getAttribute( "version" )
-                        + " will be removed" );
-                toRemove.add( n );
-            }
-        }
-
-        if ( toRemove.size() > 0 )
-        {
-            // Then remove missing resources.
-            for ( int i = 0; i < toRemove.size(); i++ )
-            {
-                elem.removeChild( ( Node ) toRemove.get( i ) );
-            }
-
-            // If we have to remove resources, we need to update  'lastmodified' attribute
-            SimpleDateFormat format = new SimpleDateFormat( "yyyyMMddHHmmss.SSS" );
-            Date d = new Date();
-            d.setTime( System.currentTimeMillis() );
-            elem.setAttribute( "lastmodified", format.format( d ) );
-            return elem;
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * Initialize the document builder from Xerces.
-     * @return DocumentBuilder ready to create new document
-     * @throws MojoExecutionException : occurs when the instantiation of the document builder fails
-     */
-    private DocumentBuilder initConstructor() throws MojoExecutionException
-    {
-        DocumentBuilder constructor = null;
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        try
-        {
-            constructor = factory.newDocumentBuilder();
-        }
-        catch ( ParserConfigurationException e )
-        {
-            getLog().error( "Unable to create a new xml document" );
-            throw new MojoExecutionException( "Cannot create the Document Builder : " + e.getMessage() );
-        }
-        return constructor;
-    }
-
-
-    /**
-     * Open an XML file.
-     * @param filename : XML file path
-     * @param constructor DocumentBuilder get from xerces
-     * @return Document which describes this file
-     * @throws MojoExecutionException occurs when the given file cannot be opened or is a valid XML file.
-     */
-    private Document parseFile( File file, DocumentBuilder constructor ) throws MojoExecutionException
-    {
-        if ( constructor == null )
-        {
-            return null;
-        }
-        // The document is the root of the DOM tree.
-        getLog().info( "Parsing " + file.getAbsolutePath() );
-        Document doc = null;
-        try
-        {
-            doc = constructor.parse( file );
-        }
-        catch ( SAXException e )
-        {
-            getLog().error( "Cannot parse " + file.getAbsolutePath() + " : " + e.getMessage() );
-            throw new MojoExecutionException( "Cannot parse " + file.getAbsolutePath() + " : " + e.getMessage() );
-        }
-        catch ( IOException e )
-        {
-            getLog().error( "Cannot open " + file.getAbsolutePath() + " : " + e.getMessage() );
-            throw new MojoExecutionException( "Cannot open " + file.getAbsolutePath() + " : " + e.getMessage() );
-        }
-        return doc;
-    }
-
-
-    /**
-     * write a Node in a xml file.
-     * @param outputFilename URI to the output file
-     * @param treeToBeWrite Node root of the tree to be write in file
-     * @throws MojoExecutionException if the plugin failed
-     */
-    private void writeToFile( URI outputFilename, Node treeToBeWrite ) throws MojoExecutionException
-    {
-        // init the transformer
-        Transformer transformer = null;
-        TransformerFactory tfabrique = TransformerFactory.newInstance();
-        try
-        {
-            transformer = tfabrique.newTransformer();
-        }
-        catch ( TransformerConfigurationException e )
-        {
-            getLog().error( "Unable to write to file: " + outputFilename.toString() );
-            throw new MojoExecutionException( "Unable to write to file: " + outputFilename.toString() + " : "
-                + e.getMessage() );
-        }
-        Properties proprietes = new Properties();
-        proprietes.put( "method", "xml" );
-        proprietes.put( "version", "1.0" );
-        proprietes.put( "encoding", "ISO-8859-1" );
-        proprietes.put( "standalone", "yes" );
-        proprietes.put( "indent", "yes" );
-        proprietes.put( "omit-xml-declaration", "no" );
-        transformer.setOutputProperties( proprietes );
-
-        DOMSource input = new DOMSource( treeToBeWrite );
-
-        File fichier = new File( outputFilename );
-        FileOutputStream flux = null;
-        try
-        {
-            flux = new FileOutputStream( fichier );
-        }
-        catch ( FileNotFoundException e )
-        {
-            getLog().error( "Unable to write to file: " + fichier.getName() );
-            throw new MojoExecutionException( "Unable to write to file: " + fichier.getName() + " : " + e.getMessage() );
-        }
-        Result output = new StreamResult( flux );
-        try
-        {
-            transformer.transform( input, output );
-        }
-        catch ( TransformerException e )
-        {
-            throw new MojoExecutionException( "Unable to write to file: " + outputFilename.toString() + " : "
-                + e.getMessage() );
-        }
-
-        try
-        {
-            flux.flush();
-            flux.close();
-        }
-        catch ( IOException e )
-        {
-            throw new MojoExecutionException( "IOException when closing file : " + e.getMessage() );
-        }
-
-    }
-
-
-    private static PathFile normalizeRepositoryPath( String obrPath, String mavenPath )
-    {
-        if ( null == obrPath || obrPath.length() == 0 )
-        {
-            obrPath = mavenPath + File.separatorChar + "repository.xml";
-        }
-        else if ( !obrPath.endsWith( ".xml" ) )
-        {
-            obrPath = obrPath + File.separatorChar + "repository.xml";
-        }
-
-        URI uri;
-        try
-        {
-            uri = new URI( obrPath );
-        }
-        catch ( URISyntaxException e )
-        {
-            uri = null;
-        }
-
-        if ( null == uri || !uri.isAbsolute() )
-        {
-            File file = new File( obrPath );
-            if ( !file.isAbsolute() )
-            {
-                file = new File( mavenPath, obrPath );
-            }
-
-            uri = file.toURI();
-        }
-
-        return new PathFile( uri.toASCIIString() );
-    }
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Clean an OBR repository by finding and removing missing resources. 
+ * @goal clean
+ * @phase install
+ * @requiresDependencyResolution compile
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ObrCleanRepo extends AbstractMojo
+{
+
+    /**
+     * OBR Repository.
+     * 
+     * @parameter expression="${obrRepository}"
+     */
+    private String obrRepository;
+
+    /**
+     * Local Repository.
+     * 
+     * @parameter expression="${localRepository}"
+     * @required
+     * @readonly
+     */
+    private ArtifactRepository localRepository;
+
+
+    public void execute() throws MojoExecutionException
+    {
+        // If no OBR repository, return
+        if ( "NONE".equalsIgnoreCase( obrRepository ) )
+        {
+            return;
+        }
+
+        try
+        {
+            // Compute local repository location
+            String localRepoPath = localRepository.getBasedir();
+            PathFile repositoryXml = normalizeRepositoryPath( obrRepository, localRepoPath );
+
+            // Check if the file exist
+            if ( !repositoryXml.isExists() )
+            {
+                getLog().error( "The repository file " + repositoryXml.getAbsoluteFilename() + " does not exist" );
+                return;
+            }
+
+            Document doc = parseFile( repositoryXml.getFile(), initConstructor() );
+            Node finalDocument = cleanDocument( doc.getDocumentElement() ); //Analyze existing repository.
+
+            if ( finalDocument == null )
+            {
+                getLog().info( "Nothing to clean in " + repositoryXml.getAbsoluteFilename() );
+            }
+            else
+            {
+                getLog().info( "Cleaning..." );
+                writeToFile( repositoryXml.getUri(), finalDocument ); // Write the new file
+                getLog().info( "Repository " + repositoryXml.getAbsoluteFilename() + " updated" );
+            }
+        }
+        catch ( Exception e )
+        {
+            getLog().error( "Exception while cleaning the OBR repository file : " + e.getLocalizedMessage(), e );
+        }
+    }
+
+
+    /**
+     * Analyze the given XML tree (DOM of the repository file) and remove missing resources.
+     * @param elem : the input XML tree
+     * @return the cleaned XML tree
+     */
+    private Element cleanDocument( Element elem )
+    {
+        NodeList nodes = elem.getElementsByTagName( "resource" );
+        List toRemove = new ArrayList();
+
+        // First, look for missing resources
+        for ( int i = 0; i < nodes.getLength(); i++ )
+        {
+            Element n = ( Element ) nodes.item( i );
+            String value = n.getAttribute( "uri" );
+
+            String localRepoPath = localRepository.getBasedir();
+            File file = new File( localRepoPath, value );
+
+            if ( !file.exists() )
+            {
+                getLog().info(
+                    "The bundle " + n.getAttribute( "presentationname" ) + " - " + n.getAttribute( "version" )
+                        + " will be removed" );
+                toRemove.add( n );
+            }
+        }
+
+        if ( toRemove.size() > 0 )
+        {
+            // Then remove missing resources.
+            for ( int i = 0; i < toRemove.size(); i++ )
+            {
+                elem.removeChild( ( Node ) toRemove.get( i ) );
+            }
+
+            // If we have to remove resources, we need to update  'lastmodified' attribute
+            SimpleDateFormat format = new SimpleDateFormat( "yyyyMMddHHmmss.SSS" );
+            Date d = new Date();
+            d.setTime( System.currentTimeMillis() );
+            elem.setAttribute( "lastmodified", format.format( d ) );
+            return elem;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * Initialize the document builder from Xerces.
+     * @return DocumentBuilder ready to create new document
+     * @throws MojoExecutionException : occurs when the instantiation of the document builder fails
+     */
+    private DocumentBuilder initConstructor() throws MojoExecutionException
+    {
+        DocumentBuilder constructor = null;
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        try
+        {
+            constructor = factory.newDocumentBuilder();
+        }
+        catch ( ParserConfigurationException e )
+        {
+            getLog().error( "Unable to create a new xml document" );
+            throw new MojoExecutionException( "Cannot create the Document Builder : " + e.getMessage() );
+        }
+        return constructor;
+    }
+
+
+    /**
+     * Open an XML file.
+     * @param filename : XML file path
+     * @param constructor DocumentBuilder get from xerces
+     * @return Document which describes this file
+     * @throws MojoExecutionException occurs when the given file cannot be opened or is a valid XML file.
+     */
+    private Document parseFile( File file, DocumentBuilder constructor ) throws MojoExecutionException
+    {
+        if ( constructor == null )
+        {
+            return null;
+        }
+        // The document is the root of the DOM tree.
+        getLog().info( "Parsing " + file.getAbsolutePath() );
+        Document doc = null;
+        try
+        {
+            doc = constructor.parse( file );
+        }
+        catch ( SAXException e )
+        {
+            getLog().error( "Cannot parse " + file.getAbsolutePath() + " : " + e.getMessage() );
+            throw new MojoExecutionException( "Cannot parse " + file.getAbsolutePath() + " : " + e.getMessage() );
+        }
+        catch ( IOException e )
+        {
+            getLog().error( "Cannot open " + file.getAbsolutePath() + " : " + e.getMessage() );
+            throw new MojoExecutionException( "Cannot open " + file.getAbsolutePath() + " : " + e.getMessage() );
+        }
+        return doc;
+    }
+
+
+    /**
+     * write a Node in a xml file.
+     * @param outputFilename URI to the output file
+     * @param treeToBeWrite Node root of the tree to be write in file
+     * @throws MojoExecutionException if the plugin failed
+     */
+    private void writeToFile( URI outputFilename, Node treeToBeWrite ) throws MojoExecutionException
+    {
+        // init the transformer
+        Transformer transformer = null;
+        TransformerFactory tfabrique = TransformerFactory.newInstance();
+        try
+        {
+            transformer = tfabrique.newTransformer();
+        }
+        catch ( TransformerConfigurationException e )
+        {
+            getLog().error( "Unable to write to file: " + outputFilename.toString() );
+            throw new MojoExecutionException( "Unable to write to file: " + outputFilename.toString() + " : "
+                + e.getMessage() );
+        }
+        Properties proprietes = new Properties();
+        proprietes.put( "method", "xml" );
+        proprietes.put( "version", "1.0" );
+        proprietes.put( "encoding", "ISO-8859-1" );
+        proprietes.put( "standalone", "yes" );
+        proprietes.put( "indent", "yes" );
+        proprietes.put( "omit-xml-declaration", "no" );
+        transformer.setOutputProperties( proprietes );
+
+        DOMSource input = new DOMSource( treeToBeWrite );
+
+        File fichier = new File( outputFilename );
+        FileOutputStream flux = null;
+        try
+        {
+            flux = new FileOutputStream( fichier );
+        }
+        catch ( FileNotFoundException e )
+        {
+            getLog().error( "Unable to write to file: " + fichier.getName() );
+            throw new MojoExecutionException( "Unable to write to file: " + fichier.getName() + " : " + e.getMessage() );
+        }
+        Result output = new StreamResult( flux );
+        try
+        {
+            transformer.transform( input, output );
+        }
+        catch ( TransformerException e )
+        {
+            throw new MojoExecutionException( "Unable to write to file: " + outputFilename.toString() + " : "
+                + e.getMessage() );
+        }
+
+        try
+        {
+            flux.flush();
+            flux.close();
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "IOException when closing file : " + e.getMessage() );
+        }
+
+    }
+
+
+    private static PathFile normalizeRepositoryPath( String obrPath, String mavenPath )
+    {
+        if ( null == obrPath || obrPath.length() == 0 )
+        {
+            obrPath = mavenPath + File.separatorChar + "repository.xml";
+        }
+        else if ( !obrPath.endsWith( ".xml" ) )
+        {
+            obrPath = obrPath + File.separatorChar + "repository.xml";
+        }
+
+        URI uri;
+        try
+        {
+            uri = new URI( obrPath );
+        }
+        catch ( URISyntaxException e )
+        {
+            uri = null;
+        }
+
+        if ( null == uri || !uri.isAbsolute() )
+        {
+            File file = new File( obrPath );
+            if ( !file.isAbsolute() )
+            {
+                file = new File( mavenPath, obrPath );
+            }
+
+            uri = file.toURI();
+        }
+
+        return new PathFile( uri.toASCIIString() );
+    }
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java
index 5eea1a3..83a847d 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeploy.java
@@ -1,374 +1,374 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.List;
-
-import org.apache.maven.artifact.manager.WagonManager;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.model.Resource;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.settings.Settings;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.TransferFailedException;
-import org.apache.maven.wagon.authorization.AuthorizationException;
-
-
-/**
- * deploy the bundle to a remote site.
- * this goal is used when you compile a project with a pom file
- * @goal deployment
- * @phase deploy
- * @requiresDependencyResolution compile
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-
-public class ObrDeploy extends AbstractMojo
-{
-
-    /**
-     * setting of maven.
-     * 
-     * @parameter expression="${settings}"
-     * @require
-     */
-    private Settings m_settings;
-
-    /**
-     * name of the repository xml descriptor file.
-     * 
-     * @parameter expression="${repository-name}" default-value="repository.xml"
-     */
-    private String m_repositoryName;
-
-    /**
-     * The local Maven repository.
-     * 
-     * @parameter expression="${localRepository}"
-     * @required
-     */
-    private ArtifactRepository m_localRepo;
-
-    /**
-     * Project in use.
-     * 
-     * @parameter expression="${project}"
-     * @require
-     */
-    private MavenProject m_project;
-
-    /**
-     * Wagon Manager.
-     * @component
-     */
-    private WagonManager m_wagonManager;
-
-    /**
-     * obr file define by the user.
-     * 
-     * @parameter expression="${ignore-lock}"
-     * 
-     */
-    private boolean m_ignoreLock;
-
-    /**
-     * used to store pathfile in local repo.
-     */
-    private String m_fileInLocalRepo;
-
-    /**
-     * Enable/Disable this goal
-     * @description If true evrything the goal do nothing, the goal just skip over 
-     * @parameter expression="${maven.obr.installToRemoteOBR}" default-value="false"
-     */
-    private boolean installToRemoteOBR;
-
-
-    /**
-     * main method for this goal.
-     * @implements org.apache.maven.plugin.Mojo.execute 
-     * @throws MojoExecutionException if the plugin failed
-     * @throws MojoFailureException if the plugin failed
-     */
-    public void execute() throws MojoExecutionException, MojoFailureException
-    {
-        getLog().info( "Obr-deploy start:" );
-        if ( !installToRemoteOBR )
-        {
-            getLog().info( "maven-obr-plugin:deploy goal is disable due to one of the following reason:" );
-            getLog().info( " - 'installToRemoteOBR' configuration set to false" );
-            getLog().info( " - JVM property maven.obr.installToRemoteOBR set to false" );
-            return;
-        }
-        ArtifactRepository ar = m_project.getDistributionManagementArtifactRepository();
-
-        // locate the obr.xml file
-        String obrXmlFile = null;
-        List l = m_project.getResources();
-        for ( int i = 0; i < l.size(); i++ )
-        {
-            File f = new File( ( ( Resource ) l.get( i ) ).getDirectory() + File.separator + "obr.xml" );
-            if ( f.exists() )
-            {
-                obrXmlFile = ( ( Resource ) l.get( i ) ).getDirectory() + File.separator + "obr.xml";
-                break;
-            }
-        }
-
-        // the obr.xml file is not present
-        if ( obrXmlFile == null )
-        {
-            getLog().warn( "obr.xml is not present, use default" );
-        }
-
-        File repoDescriptorFile = null;
-
-        // init the wagon connection
-        RemoteFileManager remoteFile = new RemoteFileManager( ar, m_wagonManager, m_settings, getLog() );
-        remoteFile.connect();
-
-        // create a non-empty file used to lock the repository descriptor file
-        File lockFile = null;
-        Writer output = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-            output = new BufferedWriter( new FileWriter( lockFile ) );
-            output.write( "locked" );
-            output.close();
-        }
-        catch ( IOException e )
-        {
-            getLog().error( "Unable to create temporary file" );
-            throw new MojoFailureException( "IOException" );
-        }
-
-        if ( m_ignoreLock )
-        {
-            try
-            {
-                remoteFile.put( lockFile, m_repositoryName + ".lock" );
-            }
-            catch ( TransferFailedException e )
-            {
-                getLog().error( "Transfer failed" );
-                e.printStackTrace();
-                throw new MojoFailureException( "TransferFailedException" );
-
-            }
-            catch ( ResourceDoesNotExistException e )
-            {
-                throw new MojoFailureException( "ResourceDoesNotExistException" );
-            }
-            catch ( AuthorizationException e )
-            {
-                getLog().error( "Authorization failed" );
-                e.printStackTrace();
-                throw new MojoFailureException( "AuthorizationException" );
-            }
-
-        }
-        else
-        {
-            int countError = 0;
-            while ( remoteFile.isLockedFile( remoteFile, m_repositoryName ) && countError < 2 )
-            {
-                countError++;
-                getLog().warn( "File is locked, retry in 10s" );
-                try
-                {
-                    Thread.sleep( 10000 );
-                }
-                catch ( InterruptedException e )
-                {
-                    getLog().warn( "Sleep interupted" );
-                }
-            }
-
-            if ( countError == 2 )
-            {
-                getLog().error(
-                    "File: " + m_repositoryName + " is locked. Try -Dignore-lock=true if you want force uploading" );
-                throw new MojoFailureException( "fileLocked" );
-            }
-        }
-
-        // file is not locked, so we lock it now
-        try
-        {
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-
-        try
-        {
-            repoDescriptorFile = remoteFile.get( m_repositoryName );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            // file doesn't exist! create a new one
-            getLog().warn( "file specified does not exist: " + m_repositoryName );
-            getLog().warn( "Create a new repository descriptor file " + m_repositoryName );
-            try
-            {
-                File f = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-                repoDescriptorFile = new File( f.getParent() + File.separator
-                    + String.valueOf( System.currentTimeMillis() ) + ".xml" );
-            }
-            catch ( IOException e1 )
-            {
-                getLog().error( "canno't create temporary file" );
-                e1.printStackTrace();
-                return;
-            }
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
-
-        Config userConfig = new Config();
-        userConfig.setPathRelative( true );
-        userConfig.setRemotely( true );
-
-        PathFile file = null;
-
-        // get the path to local maven repository
-        file = new PathFile( PathFile.uniformSeparator( m_settings.getLocalRepository() ) + File.separator
-            + PathFile.uniformSeparator( m_localRepo.pathOf( m_project.getArtifact() ) ) );
-        if ( file.isExists() )
-        {
-            m_fileInLocalRepo = file.getOnlyAbsoluteFilename();
-        }
-        else
-        {
-            getLog().error(
-                "file not found in local repository: " + m_settings.getLocalRepository() + File.separator
-                    + m_localRepo.pathOf( m_project.getArtifact() ) );
-            return;
-        }
-
-        file = new PathFile( "file:/" + repoDescriptorFile.getAbsolutePath() );
-
-        ObrUpdate obrUpdate = new ObrUpdate( file, obrXmlFile, m_project, m_fileInLocalRepo, PathFile
-            .uniformSeparator( m_settings.getLocalRepository() ), userConfig, getLog() );
-
-        obrUpdate.updateRepository();
-
-        // the reposiroty descriptor file is modified, we upload it on the remote repository
-        try
-        {
-            remoteFile.put( repoDescriptorFile, m_repositoryName );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            getLog().error( "Resource does not exist:" + repoDescriptorFile.getName() );
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        repoDescriptorFile.delete();
-
-        // we remove lockFile activation
-        lockFile = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
-        try
-        {
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-
-        remoteFile.disconnect();
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import org.apache.maven.artifact.manager.WagonManager;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+
+
+/**
+ * deploy the bundle to a remote site.
+ * this goal is used when you compile a project with a pom file
+ * @goal deployment
+ * @phase deploy
+ * @requiresDependencyResolution compile
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+
+public class ObrDeploy extends AbstractMojo
+{
+
+    /**
+     * setting of maven.
+     * 
+     * @parameter expression="${settings}"
+     * @require
+     */
+    private Settings m_settings;
+
+    /**
+     * name of the repository xml descriptor file.
+     * 
+     * @parameter expression="${repository-name}" default-value="repository.xml"
+     */
+    private String m_repositoryName;
+
+    /**
+     * The local Maven repository.
+     * 
+     * @parameter expression="${localRepository}"
+     * @required
+     */
+    private ArtifactRepository m_localRepo;
+
+    /**
+     * Project in use.
+     * 
+     * @parameter expression="${project}"
+     * @require
+     */
+    private MavenProject m_project;
+
+    /**
+     * Wagon Manager.
+     * @component
+     */
+    private WagonManager m_wagonManager;
+
+    /**
+     * obr file define by the user.
+     * 
+     * @parameter expression="${ignore-lock}"
+     * 
+     */
+    private boolean m_ignoreLock;
+
+    /**
+     * used to store pathfile in local repo.
+     */
+    private String m_fileInLocalRepo;
+
+    /**
+     * Enable/Disable this goal
+     * @description If true evrything the goal do nothing, the goal just skip over 
+     * @parameter expression="${maven.obr.installToRemoteOBR}" default-value="false"
+     */
+    private boolean installToRemoteOBR;
+
+
+    /**
+     * main method for this goal.
+     * @implements org.apache.maven.plugin.Mojo.execute 
+     * @throws MojoExecutionException if the plugin failed
+     * @throws MojoFailureException if the plugin failed
+     */
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        getLog().info( "Obr-deploy start:" );
+        if ( !installToRemoteOBR )
+        {
+            getLog().info( "maven-obr-plugin:deploy goal is disable due to one of the following reason:" );
+            getLog().info( " - 'installToRemoteOBR' configuration set to false" );
+            getLog().info( " - JVM property maven.obr.installToRemoteOBR set to false" );
+            return;
+        }
+        ArtifactRepository ar = m_project.getDistributionManagementArtifactRepository();
+
+        // locate the obr.xml file
+        String obrXmlFile = null;
+        List l = m_project.getResources();
+        for ( int i = 0; i < l.size(); i++ )
+        {
+            File f = new File( ( ( Resource ) l.get( i ) ).getDirectory() + File.separator + "obr.xml" );
+            if ( f.exists() )
+            {
+                obrXmlFile = ( ( Resource ) l.get( i ) ).getDirectory() + File.separator + "obr.xml";
+                break;
+            }
+        }
+
+        // the obr.xml file is not present
+        if ( obrXmlFile == null )
+        {
+            getLog().warn( "obr.xml is not present, use default" );
+        }
+
+        File repoDescriptorFile = null;
+
+        // init the wagon connection
+        RemoteFileManager remoteFile = new RemoteFileManager( ar, m_wagonManager, m_settings, getLog() );
+        remoteFile.connect();
+
+        // create a non-empty file used to lock the repository descriptor file
+        File lockFile = null;
+        Writer output = null;
+        try
+        {
+            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
+            output = new BufferedWriter( new FileWriter( lockFile ) );
+            output.write( "locked" );
+            output.close();
+        }
+        catch ( IOException e )
+        {
+            getLog().error( "Unable to create temporary file" );
+            throw new MojoFailureException( "IOException" );
+        }
+
+        if ( m_ignoreLock )
+        {
+            try
+            {
+                remoteFile.put( lockFile, m_repositoryName + ".lock" );
+            }
+            catch ( TransferFailedException e )
+            {
+                getLog().error( "Transfer failed" );
+                e.printStackTrace();
+                throw new MojoFailureException( "TransferFailedException" );
+
+            }
+            catch ( ResourceDoesNotExistException e )
+            {
+                throw new MojoFailureException( "ResourceDoesNotExistException" );
+            }
+            catch ( AuthorizationException e )
+            {
+                getLog().error( "Authorization failed" );
+                e.printStackTrace();
+                throw new MojoFailureException( "AuthorizationException" );
+            }
+
+        }
+        else
+        {
+            int countError = 0;
+            while ( remoteFile.isLockedFile( remoteFile, m_repositoryName ) && countError < 2 )
+            {
+                countError++;
+                getLog().warn( "File is locked, retry in 10s" );
+                try
+                {
+                    Thread.sleep( 10000 );
+                }
+                catch ( InterruptedException e )
+                {
+                    getLog().warn( "Sleep interupted" );
+                }
+            }
+
+            if ( countError == 2 )
+            {
+                getLog().error(
+                    "File: " + m_repositoryName + " is locked. Try -Dignore-lock=true if you want force uploading" );
+                throw new MojoFailureException( "fileLocked" );
+            }
+        }
+
+        // file is not locked, so we lock it now
+        try
+        {
+            remoteFile.put( lockFile, m_repositoryName + ".lock" );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            throw new MojoFailureException( "ResourceDoesNotExistException" );
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+
+        try
+        {
+            repoDescriptorFile = remoteFile.get( m_repositoryName );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            // file doesn't exist! create a new one
+            getLog().warn( "file specified does not exist: " + m_repositoryName );
+            getLog().warn( "Create a new repository descriptor file " + m_repositoryName );
+            try
+            {
+                File f = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
+                repoDescriptorFile = new File( f.getParent() + File.separator
+                    + String.valueOf( System.currentTimeMillis() ) + ".xml" );
+            }
+            catch ( IOException e1 )
+            {
+                getLog().error( "canno't create temporary file" );
+                e1.printStackTrace();
+                return;
+            }
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "IOException" );
+        }
+
+        Config userConfig = new Config();
+        userConfig.setPathRelative( true );
+        userConfig.setRemotely( true );
+
+        PathFile file = null;
+
+        // get the path to local maven repository
+        file = new PathFile( PathFile.uniformSeparator( m_settings.getLocalRepository() ) + File.separator
+            + PathFile.uniformSeparator( m_localRepo.pathOf( m_project.getArtifact() ) ) );
+        if ( file.isExists() )
+        {
+            m_fileInLocalRepo = file.getOnlyAbsoluteFilename();
+        }
+        else
+        {
+            getLog().error(
+                "file not found in local repository: " + m_settings.getLocalRepository() + File.separator
+                    + m_localRepo.pathOf( m_project.getArtifact() ) );
+            return;
+        }
+
+        file = new PathFile( "file:/" + repoDescriptorFile.getAbsolutePath() );
+
+        ObrUpdate obrUpdate = new ObrUpdate( file, obrXmlFile, m_project, m_fileInLocalRepo, PathFile
+            .uniformSeparator( m_settings.getLocalRepository() ), userConfig, getLog() );
+
+        obrUpdate.updateRepository();
+
+        // the reposiroty descriptor file is modified, we upload it on the remote repository
+        try
+        {
+            remoteFile.put( repoDescriptorFile, m_repositoryName );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            getLog().error( "Resource does not exist:" + repoDescriptorFile.getName() );
+            e.printStackTrace();
+            throw new MojoFailureException( "ResourceDoesNotExistException" );
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+        repoDescriptorFile.delete();
+
+        // we remove lockFile activation
+        lockFile = null;
+        try
+        {
+            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "IOException" );
+        }
+        try
+        {
+            remoteFile.put( lockFile, m_repositoryName + ".lock" );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "ResourceDoesNotExistException" );
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+
+        remoteFile.disconnect();
+    }
+
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java
index 4eb126e..2f7f6b5 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrDeployFile.java
@@ -1,352 +1,352 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.maven.artifact.manager.WagonManager;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.settings.Settings;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.TransferFailedException;
-import org.apache.maven.wagon.authorization.AuthorizationException;
-
-
-/**
- * deploy the bundle to a ftp site.
- * this goal is used when you upload a jar file (in command line)
- * @goal deploy-file
- * @phase deploy
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ObrDeployFile extends AbstractMojo
-{
-
-    /**
-     * setting of maven.
-     * 
-     * @parameter expression="${settings}"
-     * @require
-     */
-
-    private Settings m_settings;
-
-    /**
-     * name of the repository xml descriptor file.
-     * 
-     * @parameter expression="${repository-name}" default-value="repository.xml"
-     */
-    private String m_repositoryName;
-
-    /**
-     * The local Maven repository.
-     * 
-     * @parameter expression="${localRepository}"
-     * @required
-     */
-    private ArtifactRepository m_localRepo;
-
-    /**
-     * Project in use.
-     * 
-     * @parameter expression="${project}"
-     * @require
-     */
-    private MavenProject m_project;
-
-    /**
-     * Wagon Manager.
-     * @component
-     */
-    private WagonManager m_wagonManager;
-
-    /**
-     * obr file define by the user.
-     * 
-     * @parameter expression="${obr-file}"
-     * 
-     */
-    private String m_obrFile;
-
-    /**
-     * obr file define by the user.
-     * 
-     * @parameter expression="${ignore-lock}"
-     * 
-     */
-    private boolean m_ignoreLock;
-
-    /**
-     * used to store pathfile in local repo.
-     */
-    private String m_fileInLocalRepo;
-
-
-    /**
-     * main method for this goal.
-     * @implements org.apache.maven.plugin.Mojo.execute 
-     * @throws MojoExecutionException if the plugin failed
-     * @throws MojoFailureException if the plugin failed
-     */
-    public void execute() throws MojoExecutionException, MojoFailureException
-    {
-        getLog().info( "Obr-deploy-file start:" );
-
-        ArtifactRepository ar = m_project.getDistributionManagementArtifactRepository();
-
-        // locate the obr.xml file
-        PathFile fileObrXml = new PathFile( m_obrFile );
-        if ( !fileObrXml.isExists() )
-        {
-            getLog().warn( "obr.xml file not found, use default" );
-        }
-
-        File repoDescriptorFile = null;
-
-        RemoteFileManager remoteFile = new RemoteFileManager( ar, m_wagonManager, m_settings, getLog() );
-
-        remoteFile.connect();
-
-        // create a non-empty file used to lock the repository descriptor file
-        File lockFile = null;
-        Writer output = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-            output = new BufferedWriter( new FileWriter( lockFile ) );
-            output.write( "locked" );
-            output.close();
-        }
-        catch ( IOException e )
-        {
-            getLog().error( "Unable to create temporary file" );
-            throw new MojoFailureException( "IOException" );
-        }
-
-        if ( m_ignoreLock )
-        {
-            try
-            {
-                remoteFile.put( lockFile, m_repositoryName + ".lock" );
-            }
-            catch ( TransferFailedException e )
-            {
-                getLog().error( "Transfer failed" );
-                e.printStackTrace();
-                throw new MojoFailureException( "TransferFailedException" );
-
-            }
-            catch ( ResourceDoesNotExistException e )
-            {
-                throw new MojoFailureException( "ResourceDoesNotExistException" );
-            }
-            catch ( AuthorizationException e )
-            {
-                getLog().error( "Authorization failed" );
-                e.printStackTrace();
-                throw new MojoFailureException( "AuthorizationException" );
-            }
-
-        }
-        else
-        {
-            int countError = 0;
-            while ( remoteFile.isLockedFile( remoteFile, m_repositoryName ) && countError < 2 )
-            {
-                countError++;
-                getLog().warn( "File is locked, retry in 10s" );
-                try
-                {
-                    Thread.sleep( 10000 );
-                }
-                catch ( InterruptedException e )
-                {
-                    getLog().warn( "Sleep Interupted" );
-                }
-            }
-
-            if ( countError == 2 )
-            {
-                getLog().error(
-                    "File: " + m_repositoryName + " is locked. Try -Dignore-lock=true if you want to force uploading" );
-                throw new MojoFailureException( "fileLocked" );
-            }
-        }
-
-        // file is not locked, so we lock it now
-        try
-        {
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-
-        try
-        {
-            repoDescriptorFile = remoteFile.get( m_repositoryName );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            // file doesn't exist! create a new one
-            getLog().warn( "file specified does not exist: " + m_repositoryName );
-            getLog().warn( "Create a new repository descriptor file " + m_repositoryName );
-            try
-            {
-                File f = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-                repoDescriptorFile = new File( f.getParent() + File.separator
-                    + String.valueOf( System.currentTimeMillis() ) + ".xml" );
-            }
-            catch ( IOException e1 )
-            {
-                getLog().error( "canno't create temporary file" );
-                e1.printStackTrace();
-                return;
-            }
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
-
-        Config userConfig = new Config();
-        userConfig.setPathRelative( true );
-        userConfig.setRemotely( true );
-
-        PathFile file = null;
-
-        // get the path to local maven repository
-        file = new PathFile( PathFile.uniformSeparator( m_settings.getLocalRepository() ) + File.separator
-            + PathFile.uniformSeparator( m_localRepo.pathOf( m_project.getArtifact() ) ) );
-        if ( file.isExists() )
-        {
-            m_fileInLocalRepo = file.getOnlyAbsoluteFilename();
-        }
-        else
-        {
-            getLog().error(
-                "file not found in local repository: " + m_settings.getLocalRepository() + File.separator
-                    + m_localRepo.pathOf( m_project.getArtifact() ) );
-            return;
-        }
-
-        file = new PathFile( "file:/" + repoDescriptorFile.getAbsolutePath() );
-
-        ObrUpdate obrUpdate = new ObrUpdate( file, fileObrXml.getOnlyAbsoluteFilename(), m_project, m_fileInLocalRepo,
-            PathFile.uniformSeparator( m_settings.getLocalRepository() ), userConfig, getLog() );
-
-        obrUpdate.updateRepository();
-
-        // the reposiroty descriptor file is modified, we upload it on the remote repository
-        try
-        {
-            remoteFile.put( repoDescriptorFile, m_repositoryName );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            getLog().error( "Resource does not exist:" + repoDescriptorFile.getName() );
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        repoDescriptorFile.delete();
-
-        // we remove lockFile activation
-        lockFile = null;
-        try
-        {
-            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
-        try
-        {
-            remoteFile.put( lockFile, m_repositoryName + ".lock" );
-        }
-        catch ( TransferFailedException e )
-        {
-            getLog().error( "Transfer failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "ResourceDoesNotExistException" );
-        }
-        catch ( AuthorizationException e )
-        {
-            getLog().error( "Authorization failed" );
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        remoteFile.disconnect();
-    }
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.maven.artifact.manager.WagonManager;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+
+
+/**
+ * deploy the bundle to a ftp site.
+ * this goal is used when you upload a jar file (in command line)
+ * @goal deploy-file
+ * @phase deploy
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ObrDeployFile extends AbstractMojo
+{
+
+    /**
+     * setting of maven.
+     * 
+     * @parameter expression="${settings}"
+     * @require
+     */
+
+    private Settings m_settings;
+
+    /**
+     * name of the repository xml descriptor file.
+     * 
+     * @parameter expression="${repository-name}" default-value="repository.xml"
+     */
+    private String m_repositoryName;
+
+    /**
+     * The local Maven repository.
+     * 
+     * @parameter expression="${localRepository}"
+     * @required
+     */
+    private ArtifactRepository m_localRepo;
+
+    /**
+     * Project in use.
+     * 
+     * @parameter expression="${project}"
+     * @require
+     */
+    private MavenProject m_project;
+
+    /**
+     * Wagon Manager.
+     * @component
+     */
+    private WagonManager m_wagonManager;
+
+    /**
+     * obr file define by the user.
+     * 
+     * @parameter expression="${obr-file}"
+     * 
+     */
+    private String m_obrFile;
+
+    /**
+     * obr file define by the user.
+     * 
+     * @parameter expression="${ignore-lock}"
+     * 
+     */
+    private boolean m_ignoreLock;
+
+    /**
+     * used to store pathfile in local repo.
+     */
+    private String m_fileInLocalRepo;
+
+
+    /**
+     * main method for this goal.
+     * @implements org.apache.maven.plugin.Mojo.execute 
+     * @throws MojoExecutionException if the plugin failed
+     * @throws MojoFailureException if the plugin failed
+     */
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        getLog().info( "Obr-deploy-file start:" );
+
+        ArtifactRepository ar = m_project.getDistributionManagementArtifactRepository();
+
+        // locate the obr.xml file
+        PathFile fileObrXml = new PathFile( m_obrFile );
+        if ( !fileObrXml.isExists() )
+        {
+            getLog().warn( "obr.xml file not found, use default" );
+        }
+
+        File repoDescriptorFile = null;
+
+        RemoteFileManager remoteFile = new RemoteFileManager( ar, m_wagonManager, m_settings, getLog() );
+
+        remoteFile.connect();
+
+        // create a non-empty file used to lock the repository descriptor file
+        File lockFile = null;
+        Writer output = null;
+        try
+        {
+            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
+            output = new BufferedWriter( new FileWriter( lockFile ) );
+            output.write( "locked" );
+            output.close();
+        }
+        catch ( IOException e )
+        {
+            getLog().error( "Unable to create temporary file" );
+            throw new MojoFailureException( "IOException" );
+        }
+
+        if ( m_ignoreLock )
+        {
+            try
+            {
+                remoteFile.put( lockFile, m_repositoryName + ".lock" );
+            }
+            catch ( TransferFailedException e )
+            {
+                getLog().error( "Transfer failed" );
+                e.printStackTrace();
+                throw new MojoFailureException( "TransferFailedException" );
+
+            }
+            catch ( ResourceDoesNotExistException e )
+            {
+                throw new MojoFailureException( "ResourceDoesNotExistException" );
+            }
+            catch ( AuthorizationException e )
+            {
+                getLog().error( "Authorization failed" );
+                e.printStackTrace();
+                throw new MojoFailureException( "AuthorizationException" );
+            }
+
+        }
+        else
+        {
+            int countError = 0;
+            while ( remoteFile.isLockedFile( remoteFile, m_repositoryName ) && countError < 2 )
+            {
+                countError++;
+                getLog().warn( "File is locked, retry in 10s" );
+                try
+                {
+                    Thread.sleep( 10000 );
+                }
+                catch ( InterruptedException e )
+                {
+                    getLog().warn( "Sleep Interupted" );
+                }
+            }
+
+            if ( countError == 2 )
+            {
+                getLog().error(
+                    "File: " + m_repositoryName + " is locked. Try -Dignore-lock=true if you want to force uploading" );
+                throw new MojoFailureException( "fileLocked" );
+            }
+        }
+
+        // file is not locked, so we lock it now
+        try
+        {
+            remoteFile.put( lockFile, m_repositoryName + ".lock" );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            throw new MojoFailureException( "ResourceDoesNotExistException" );
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+
+        try
+        {
+            repoDescriptorFile = remoteFile.get( m_repositoryName );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            // file doesn't exist! create a new one
+            getLog().warn( "file specified does not exist: " + m_repositoryName );
+            getLog().warn( "Create a new repository descriptor file " + m_repositoryName );
+            try
+            {
+                File f = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
+                repoDescriptorFile = new File( f.getParent() + File.separator
+                    + String.valueOf( System.currentTimeMillis() ) + ".xml" );
+            }
+            catch ( IOException e1 )
+            {
+                getLog().error( "canno't create temporary file" );
+                e1.printStackTrace();
+                return;
+            }
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "IOException" );
+        }
+
+        Config userConfig = new Config();
+        userConfig.setPathRelative( true );
+        userConfig.setRemotely( true );
+
+        PathFile file = null;
+
+        // get the path to local maven repository
+        file = new PathFile( PathFile.uniformSeparator( m_settings.getLocalRepository() ) + File.separator
+            + PathFile.uniformSeparator( m_localRepo.pathOf( m_project.getArtifact() ) ) );
+        if ( file.isExists() )
+        {
+            m_fileInLocalRepo = file.getOnlyAbsoluteFilename();
+        }
+        else
+        {
+            getLog().error(
+                "file not found in local repository: " + m_settings.getLocalRepository() + File.separator
+                    + m_localRepo.pathOf( m_project.getArtifact() ) );
+            return;
+        }
+
+        file = new PathFile( "file:/" + repoDescriptorFile.getAbsolutePath() );
+
+        ObrUpdate obrUpdate = new ObrUpdate( file, fileObrXml.getOnlyAbsoluteFilename(), m_project, m_fileInLocalRepo,
+            PathFile.uniformSeparator( m_settings.getLocalRepository() ), userConfig, getLog() );
+
+        obrUpdate.updateRepository();
+
+        // the reposiroty descriptor file is modified, we upload it on the remote repository
+        try
+        {
+            remoteFile.put( repoDescriptorFile, m_repositoryName );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            getLog().error( "Resource does not exist:" + repoDescriptorFile.getName() );
+            e.printStackTrace();
+            throw new MojoFailureException( "ResourceDoesNotExistException" );
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+        repoDescriptorFile.delete();
+
+        // we remove lockFile activation
+        lockFile = null;
+        try
+        {
+            lockFile = File.createTempFile( String.valueOf( System.currentTimeMillis() ), null );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "IOException" );
+        }
+        try
+        {
+            remoteFile.put( lockFile, m_repositoryName + ".lock" );
+        }
+        catch ( TransferFailedException e )
+        {
+            getLog().error( "Transfer failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "ResourceDoesNotExistException" );
+        }
+        catch ( AuthorizationException e )
+        {
+            getLog().error( "Authorization failed" );
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+        remoteFile.disconnect();
+    }
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrInstallFile.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrInstallFile.java
index 03b9e8b..1ef7a78 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrInstallFile.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrInstallFile.java
@@ -1,198 +1,198 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.File;
-
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.settings.Settings;
-
-
-/**
- * construct the repository.xml from a compiled bundle.
- * @description construct the repository.xml from a compiled bundle.
- * @goal install-file
- * @requiresProject false
- * @phase install
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ObrInstallFile extends AbstractMojo
-{
-    /**
-     * The local Maven repository.
-     * 
-     * @parameter expression="${localRepository}"
-     * @required
-     */
-    private ArtifactRepository m_localRepo;
-
-    /**
-     * path to the repository.xml.
-     * 
-     * @parameter expression="${repository-path}"
-     * @require
-     */
-    private String m_repositoryPath;
-
-    /**
-     * setting of maven.
-     * 
-     * @parameter expression="${settings}"
-     * @require
-     */
-    private Settings m_settings;
-
-    /**
-     * Artifact Id.
-     * @description symbolic name define by the user
-     * @parameter expression="${artifactId}"
-     */
-    private String m_artifactId;
-
-    /**
-     * Group Id.
-     * @description groupId define by the user
-     * @parameter expression="${groupId}"
-     */
-    private String m_groupId;
-
-    /**
-     * Version.
-     * @description version define by the user
-     * @parameter expression="${version}"
-     */
-    private String m_version;
-
-    /**
-     * Packaging.
-     * @description packaging define by the user
-     * @parameter expression="${packaging}"
-     */
-    private String m_packaging;
-
-    /**
-     * OBR File.
-     * @description obr file define by the user
-     * @parameter expression="${obr-file}"
-     */
-    private String m_obrFile;
-
-    /**
-     * store user information in a project.
-     */
-    private MavenProject m_project;
-
-
-    /**
-     * main method for this goal.
-     * @implements org.apache.maven.plugin.Mojo.execute 
-     * @throws MojoExecutionException if the plugin failed
-     * @throws MojoFailureException if the plugin failed
-     */
-    public void execute() throws MojoExecutionException, MojoFailureException
-    {
-        getLog().info( "Install-File Obr starts:" );
-
-        m_project = new MavenProject();
-        m_project.setArtifactId( m_artifactId );
-        m_project.setGroupId( m_groupId );
-        m_project.setVersion( m_version );
-        m_project.setPackaging( m_packaging );
-
-        PathFile fileOut;
-
-        if ( m_groupId == null )
-        {
-            getLog().error( "-DgroupId=VALUE is required" );
-            return;
-        }
-        if ( m_artifactId == null )
-        {
-            getLog().error( "-Dartifactid=VALUE is required" );
-            return;
-        }
-        if ( m_version == null )
-        {
-            getLog().error( "-Dversion=VALUE is required" );
-            return;
-        }
-        if ( m_packaging == null )
-        {
-            getLog().error( "-Dpackaging=VALUE is required" );
-            return;
-        }
-
-        // copy the file to the local repository
-        PathFile repoLocal = new PathFile( m_localRepo.getBasedir() );
-
-        // get the target file in mvn repo
-        fileOut = new PathFile( PathFile.uniformSeparator( m_settings.getLocalRepository() ) + File.separator
-            + m_groupId.replace( '.', File.separatorChar ) + File.separator + m_artifactId + File.separator + m_version
-            + File.separator + m_artifactId + "-" + m_version + "." + m_packaging );
-
-        if ( !fileOut.isExists() )
-        {
-            getLog().error( "file doesn't exist: " + fileOut.getAbsoluteFilename() );
-            return;
-        }
-        else
-        {
-            getLog().info( "Target file: " + fileOut.getAbsoluteFilename() );
-        }
-
-        if ( m_repositoryPath == null )
-        {
-            m_repositoryPath = "file:" + repoLocal.getOnlyAbsoluteFilename() + "repository.xml";
-            getLog().warn( "-DpathRepo is not define, use default repository: " + m_repositoryPath );
-        }
-
-        PathFile fileRepo = new PathFile( m_repositoryPath );
-        if ( fileRepo.isRelative() )
-        {
-            fileRepo.setBaseDir( m_settings.getLocalRepository() );
-        }
-
-        // create the folder to the repository
-        PathFile repoExist = new PathFile( fileRepo.getAbsolutePath() );
-        if ( !repoExist.isExists() )
-        {
-            fileRepo.createPath();
-        }
-
-        PathFile fileObrXml = new PathFile( m_obrFile );
-        if ( !fileObrXml.isExists() )
-        {
-            getLog().warn( "obr.xml file not found, use default" );
-        }
-
-        // build the user config
-        Config userConfig = new Config();
-
-        ObrUpdate obrUpdate = new ObrUpdate( fileRepo, fileObrXml.getOnlyAbsoluteFilename(), m_project, fileOut
-            .getOnlyAbsoluteFilename(), m_localRepo.getBasedir(), userConfig, getLog() );
-        obrUpdate.updateRepository();
-
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.File;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Settings;
+
+
+/**
+ * construct the repository.xml from a compiled bundle.
+ * @description construct the repository.xml from a compiled bundle.
+ * @goal install-file
+ * @requiresProject false
+ * @phase install
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ObrInstallFile extends AbstractMojo
+{
+    /**
+     * The local Maven repository.
+     * 
+     * @parameter expression="${localRepository}"
+     * @required
+     */
+    private ArtifactRepository m_localRepo;
+
+    /**
+     * path to the repository.xml.
+     * 
+     * @parameter expression="${repository-path}"
+     * @require
+     */
+    private String m_repositoryPath;
+
+    /**
+     * setting of maven.
+     * 
+     * @parameter expression="${settings}"
+     * @require
+     */
+    private Settings m_settings;
+
+    /**
+     * Artifact Id.
+     * @description symbolic name define by the user
+     * @parameter expression="${artifactId}"
+     */
+    private String m_artifactId;
+
+    /**
+     * Group Id.
+     * @description groupId define by the user
+     * @parameter expression="${groupId}"
+     */
+    private String m_groupId;
+
+    /**
+     * Version.
+     * @description version define by the user
+     * @parameter expression="${version}"
+     */
+    private String m_version;
+
+    /**
+     * Packaging.
+     * @description packaging define by the user
+     * @parameter expression="${packaging}"
+     */
+    private String m_packaging;
+
+    /**
+     * OBR File.
+     * @description obr file define by the user
+     * @parameter expression="${obr-file}"
+     */
+    private String m_obrFile;
+
+    /**
+     * store user information in a project.
+     */
+    private MavenProject m_project;
+
+
+    /**
+     * main method for this goal.
+     * @implements org.apache.maven.plugin.Mojo.execute 
+     * @throws MojoExecutionException if the plugin failed
+     * @throws MojoFailureException if the plugin failed
+     */
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        getLog().info( "Install-File Obr starts:" );
+
+        m_project = new MavenProject();
+        m_project.setArtifactId( m_artifactId );
+        m_project.setGroupId( m_groupId );
+        m_project.setVersion( m_version );
+        m_project.setPackaging( m_packaging );
+
+        PathFile fileOut;
+
+        if ( m_groupId == null )
+        {
+            getLog().error( "-DgroupId=VALUE is required" );
+            return;
+        }
+        if ( m_artifactId == null )
+        {
+            getLog().error( "-Dartifactid=VALUE is required" );
+            return;
+        }
+        if ( m_version == null )
+        {
+            getLog().error( "-Dversion=VALUE is required" );
+            return;
+        }
+        if ( m_packaging == null )
+        {
+            getLog().error( "-Dpackaging=VALUE is required" );
+            return;
+        }
+
+        // copy the file to the local repository
+        PathFile repoLocal = new PathFile( m_localRepo.getBasedir() );
+
+        // get the target file in mvn repo
+        fileOut = new PathFile( PathFile.uniformSeparator( m_settings.getLocalRepository() ) + File.separator
+            + m_groupId.replace( '.', File.separatorChar ) + File.separator + m_artifactId + File.separator + m_version
+            + File.separator + m_artifactId + "-" + m_version + "." + m_packaging );
+
+        if ( !fileOut.isExists() )
+        {
+            getLog().error( "file doesn't exist: " + fileOut.getAbsoluteFilename() );
+            return;
+        }
+        else
+        {
+            getLog().info( "Target file: " + fileOut.getAbsoluteFilename() );
+        }
+
+        if ( m_repositoryPath == null )
+        {
+            m_repositoryPath = "file:" + repoLocal.getOnlyAbsoluteFilename() + "repository.xml";
+            getLog().warn( "-DpathRepo is not define, use default repository: " + m_repositoryPath );
+        }
+
+        PathFile fileRepo = new PathFile( m_repositoryPath );
+        if ( fileRepo.isRelative() )
+        {
+            fileRepo.setBaseDir( m_settings.getLocalRepository() );
+        }
+
+        // create the folder to the repository
+        PathFile repoExist = new PathFile( fileRepo.getAbsolutePath() );
+        if ( !repoExist.isExists() )
+        {
+            fileRepo.createPath();
+        }
+
+        PathFile fileObrXml = new PathFile( m_obrFile );
+        if ( !fileObrXml.isExists() )
+        {
+            getLog().warn( "obr.xml file not found, use default" );
+        }
+
+        // build the user config
+        Config userConfig = new Config();
+
+        ObrUpdate obrUpdate = new ObrUpdate( fileRepo, fileObrXml.getOnlyAbsoluteFilename(), m_project, fileOut
+            .getOnlyAbsoluteFilename(), m_localRepo.getBasedir(), userConfig, getLog() );
+        obrUpdate.updateRepository();
+
+    }
+
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrUpdate.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrUpdate.java
index 75d307b..c112cec 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrUpdate.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ObrUpdate.java
@@ -1,602 +1,602 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Properties;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-
-/**
- * this class parse the old repository.xml file build the bundle resource description and update the repository.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-
-public class ObrUpdate
-{
-    /**
-     * generate the date format to insert it in repository descriptor file.
-     */
-    static SimpleDateFormat m_format = new SimpleDateFormat( "yyyyMMddHHmmss.SSS" );
-
-    /**
-     * logger for this plugin.
-     */
-    private Log m_logger;
-
-    /**
-     * name and path to the repository descriptor file.
-     */
-    private URI m_repoFilename;
-
-    /**
-     * name and path to the obr.xml file.
-     */
-    private String m_obrXml;
-
-    /**
-     * name and path to the bundle jar file.
-     */
-    private String m_outputFile;
-
-    /**
-     * maven project description.
-     */
-    private MavenProject m_project;
-
-    /**
-     * user configuration information.
-     */
-    private Config m_userConfig;
-
-    /**
-     * used to build another xml document.
-     */
-    private DocumentBuilder m_constructor;
-
-    /**
-     * root on parent document.
-     */
-    private Document m_repoDoc;
-
-    /**
-     * first Node on repository descriptor tree.
-     */
-    private Node m_root;
-
-    /**
-     * used to extract bindex bundle information.
-     */
-    private ExtractBindexInfo m_ebi;
-
-    /**
-     * used to store bundle information.
-     */
-    private ResourcesBundle m_resourceBundle;
-
-    /**
-     * pathfile to the repository descriptor file.
-     */
-    private PathFile m_repo;
-
-
-    /**
-     * initialize information.
-     * @param repoFilename path to the repository descriptor file
-     * @param obrXml path and filename to the obr.xml file
-     * @param project maven project description
-     * @param outputFile path to the bundle jar file
-     * @param localRepo only path to the local repository
-     * @param userConfig user information
-     * @param log plugin logger
-     */
-    public ObrUpdate( PathFile repoFilename, String obrXml, MavenProject project, String outputFile, String localRepo,
-        Config userConfig, Log log )
-    {
-        // this.m_localRepo = localRepo;
-        this.m_outputFile = outputFile;
-        this.m_repoFilename = repoFilename.getUri();
-        this.m_obrXml = obrXml;
-        this.m_project = project;
-        this.m_logger = log;
-
-        this.m_userConfig = userConfig;
-
-        m_resourceBundle = new ResourcesBundle( log );
-
-        if ( userConfig.isRemotely() )
-        {
-            this.m_repo = new PathFile( localRepo );
-        }
-        else
-        {
-            this.m_repo = repoFilename;
-        }
-    }
-
-
-    /**
-     * update the repository descriptor file. parse the old repository descriptor file, get the old reference of the bundle or determine the id for a new bundle, extract information from bindex set the new information in descriptor file and save it.
-     * @throws MojoExecutionException if the plugin failed
-     */
-    public void updateRepository() throws MojoExecutionException
-    {
-
-        m_logger.debug( " (f) m_obrXml = " + m_obrXml );
-        m_logger.debug( " (f) m_outputFile = " + m_outputFile );
-        m_logger.debug( " (f) m_repoFilename = " + m_repoFilename );
-
-        m_constructor = initConstructor();
-
-        if ( m_constructor == null )
-        {
-            return;
-        }
-
-        // get the file size
-        PathFile pf = new PathFile( m_outputFile );
-        File fout = pf.getFile();
-        pf.setBaseDir( m_repo.getOnlyAbsolutePath() );
-        if ( fout.exists() )
-        {
-            m_resourceBundle.setSize( String.valueOf( fout.length() ) );
-            if ( m_userConfig.isPathRelative() )
-            {
-                m_resourceBundle.setUri( pf.getOnlyRelativeFilename().replace( '\\', '/' ) );
-            }
-            else
-            {
-                m_resourceBundle.setUri( "file:" + m_outputFile );
-            }
-        }
-        else
-        {
-            m_logger.error( "file doesn't exist: " + m_outputFile );
-            return;
-        }
-
-        // parse repository
-        if ( parseRepositoryXml() == -1 )
-        {
-            return;
-        }
-
-        // parse the obr.xml file
-        if ( m_obrXml != null )
-        {
-            // URL url = getClass().getResource("/SchemaObr.xsd");
-            // TODO validate obr.xml file
-
-            Document obrXmlDoc = parseFile( m_obrXml, m_constructor );
-            if ( obrXmlDoc == null )
-            {
-                return;
-            }
-            Node obrXmlRoot = ( Element ) obrXmlDoc.getDocumentElement();
-            // sort the obr file
-            sortObrXml( obrXmlRoot );
-        }
-
-        // use bindex to extract bundle information
-        try
-        {
-            m_ebi = new ExtractBindexInfo( m_repoFilename, m_outputFile );
-        }
-        catch ( MojoExecutionException e )
-        {
-            m_logger.error( "unable to build Bindex informations" );
-            e.printStackTrace();
-            throw new MojoExecutionException( "MojoFailureException" );
-        }
-
-        m_resourceBundle.construct( m_project, m_ebi );
-
-        if ( !walkOnTree( m_root ) )
-        {
-            // the correct resource node was not found, we must create it
-            // we compute the new id
-            String id = m_resourceBundle.getId();
-            searchRepository( m_root, id );
-        }
-
-        // the repository.xml file have been modified, so we save it
-        m_logger.info( "Writing OBR metadata" );
-        writeToFile( m_repoFilename, m_root );
-    }
-
-
-    /**
-     * init the document builder from xerces.
-     * @return DocumentBuilder ready to create new document
-     */
-    private DocumentBuilder initConstructor()
-    {
-        DocumentBuilder constructor = null;
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        try
-        {
-            constructor = factory.newDocumentBuilder();
-        }
-        catch ( ParserConfigurationException e )
-        {
-            m_logger.error( "unable to create a new xml document" );
-            e.printStackTrace();
-        }
-        return constructor;
-
-    }
-
-
-    /**
-     * Parse the repository descriptor file.
-     * 
-     * @return 0 if the bundle is already in the descriptor, else -1
-     * @throws MojoExecutionException if the plugin failed
-     */
-    private int parseRepositoryXml() throws MojoExecutionException
-    {
-
-        File fout = new File( m_repoFilename );
-        if ( !fout.exists() )
-        {
-            // create the repository.xml
-            try
-            {
-                fout.createNewFile();
-                m_logger.info( "Created " + fout.getAbsolutePath() );
-            }
-            catch ( IOException e )
-            {
-                m_logger.error( "Cannot create file " + fout.getAbsolutePath() );
-                e.printStackTrace();
-                return -1;
-            }
-
-            Document doc = m_constructor.newDocument();
-            // create xml tree
-            Date d = new Date();
-            d.setTime( System.currentTimeMillis() );
-            Element root = doc.createElement( "repository" );
-            root.setAttribute( "lastmodified", m_format.format( d ) );
-            root.setAttribute( "name", "MyRepository" );
-            try
-            {
-                writeToFile( m_repoFilename, root );
-            }
-            catch ( MojoExecutionException e )
-            {
-                e.printStackTrace();
-                throw new MojoExecutionException( "MojoExecutionException" );
-            }
-        }
-
-        // now we parse the repository.xml file
-        m_repoDoc = parseFile( fout.getAbsolutePath(), m_constructor );
-        if ( m_repoDoc == null )
-        {
-            return -1;
-        }
-
-        m_root = ( Element ) m_repoDoc.getDocumentElement();
-        return 0;
-    }
-
-
-    /**
-     * transform a xml file to a xerces Document.
-     * @param filename path to the xml file
-     * @param constructor DocumentBuilder get from xerces
-     * @return Document which describe this file
-     */
-    private Document parseFile( String filename, DocumentBuilder constructor )
-    {
-        if ( constructor == null )
-        {
-            return null;
-        }
-        // The document is the root of the DOM tree.
-        m_logger.info( "Parsing " + filename );
-        Document doc = null;
-        try
-        {
-            doc = constructor.parse( new File( filename ) );
-        }
-        catch ( SAXException e )
-        {
-            e.printStackTrace();
-            return null;
-        }
-        catch ( IOException e )
-        {
-            m_logger.error( "cannot open file: " + filename );
-            e.printStackTrace();
-            return null;
-        }
-        return doc;
-    }
-
-
-    /**
-     * put the information from obr.xml into ressourceBundle object.
-     * @param node Node to the OBR.xml file
-     */
-    private void sortObrXml( Node node )
-    {
-        if ( node.getNodeName().compareTo( "require" ) == 0 )
-        {
-            Require newRequireNode = new Require();
-            NamedNodeMap list = node.getAttributes();
-            try
-            {
-                newRequireNode.setExtend( list.getNamedItem( "extend" ).getNodeValue() );
-                newRequireNode.setMultiple( list.getNamedItem( "multiple" ).getNodeValue() );
-                newRequireNode.setOptional( list.getNamedItem( "optional" ).getNodeValue() );
-                newRequireNode.setFilter( list.getNamedItem( "filter" ).getNodeValue() );
-                newRequireNode.setName( list.getNamedItem( "name" ).getNodeValue() );
-            }
-            catch ( NullPointerException e )
-            {
-                m_logger
-                    .error( "the obr.xml file seems to be invalid in a \"require\" tag (one or more attributes are missing)" );
-                // e.printStackTrace();
-            }
-            newRequireNode.setValue( XmlHelper.getTextContent( node ) );
-            m_resourceBundle.addRequire( newRequireNode );
-        }
-        else if ( node.getNodeName().compareTo( "capability" ) == 0 )
-        {
-            Capability newCapability = new Capability();
-            try
-            {
-                newCapability.setName( node.getAttributes().getNamedItem( "name" ).getNodeValue() );
-            }
-            catch ( NullPointerException e )
-            {
-                m_logger.error( "attribute \"name\" is missing in obr.xml in a \"capability\" tag" );
-                e.printStackTrace();
-            }
-            NodeList list = node.getChildNodes();
-            for ( int i = 0; i < list.getLength(); i++ )
-            {
-                PElement p = new PElement();
-                Node n = list.item( i );
-                Node item = null;
-                // System.err.println(n.getNodeName());
-                if ( n.getNodeName().compareTo( "p" ) == 0 )
-                {
-
-                    p.setN( n.getAttributes().getNamedItem( "n" ).getNodeValue() );
-                    item = n.getAttributes().getNamedItem( "t" );
-                    if ( item != null )
-                    {
-                        p.setT( item.getNodeValue() );
-                    }
-                    item = n.getAttributes().getNamedItem( "v" );
-                    if ( item != null )
-                    {
-                        p.setV( item.getNodeValue() );
-                    }
-
-                    newCapability.addP( p );
-                }
-            }
-            m_resourceBundle.addCapability( newCapability );
-        }
-        else if ( node.getNodeName().compareTo( "category" ) == 0 )
-        {
-            Category newCategory = new Category();
-            newCategory.setId( node.getAttributes().getNamedItem( "id" ).getNodeValue() );
-            m_resourceBundle.addCategory( newCategory );
-        }
-        else
-        {
-            NodeList list = node.getChildNodes();
-            for ( int i = 0; i < list.getLength(); i++ )
-            {
-                sortObrXml( list.item( i ) );
-            }
-        }
-    }
-
-
-    /**
-     * write a Node in a xml file.
-     * @param outputFilename URI to the output file
-     * @param treeToBeWrite Node root of the tree to be write in file
-     * @throws MojoExecutionException if the plugin failed
-     */
-    private void writeToFile( URI outputFilename, Node treeToBeWrite ) throws MojoExecutionException
-    {
-        // init the transformer
-        Transformer transformer = null;
-        TransformerFactory tfabrique = TransformerFactory.newInstance();
-        try
-        {
-            transformer = tfabrique.newTransformer();
-        }
-        catch ( TransformerConfigurationException e )
-        {
-            m_logger.error( "Unable to write to file: " + outputFilename.toString() );
-            e.printStackTrace();
-            throw new MojoExecutionException( "TransformerConfigurationException" );
-        }
-        Properties proprietes = new Properties();
-        proprietes.put( "method", "xml" );
-        proprietes.put( "version", "1.0" );
-        proprietes.put( "encoding", "ISO-8859-1" );
-        proprietes.put( "standalone", "yes" );
-        proprietes.put( "indent", "yes" );
-        proprietes.put( "omit-xml-declaration", "no" );
-        transformer.setOutputProperties( proprietes );
-
-        DOMSource input = new DOMSource( treeToBeWrite );
-
-        File fichier = new File( outputFilename );
-        FileOutputStream flux = null;
-        try
-        {
-            flux = new FileOutputStream( fichier );
-        }
-        catch ( FileNotFoundException e )
-        {
-            m_logger.error( "Unable to write to file: " + fichier.getName() );
-            e.printStackTrace();
-            throw new MojoExecutionException( "FileNotFoundException" );
-        }
-        Result output = new StreamResult( flux );
-        try
-        {
-            transformer.transform( input, output );
-        }
-        catch ( TransformerException e )
-        {
-            e.printStackTrace();
-            throw new MojoExecutionException( "TransformerException" );
-        }
-
-        try
-        {
-            flux.flush();
-            flux.close();
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoExecutionException( "IOException" );
-        }
-
-    }
-
-
-    /**
-     * walk on the tree until the targeted node was found.
-     * @param node targeted node
-     * @return true if the requiered node was found else false.
-     */
-    private boolean walkOnTree( Node node )
-    {
-
-        if ( node.getNodeName().compareTo( "resource" ) == 0 )
-        {
-            return resource( node );
-        }
-        else
-        { // look at the repository node (first in the file)
-            if ( node.getNodeName().compareTo( "repository" ) == 0 )
-            {
-                Date d = new Date();
-                d.setTime( System.currentTimeMillis() );
-                NamedNodeMap nList = node.getAttributes();
-                Node n = nList.getNamedItem( "lastmodified" );
-                n.setNodeValue( m_format.format( d ) );
-            }
-            NodeList list = node.getChildNodes();
-            if ( list.getLength() > 0 )
-            {
-                for ( int i = 0; i < list.getLength(); i++ )
-                {
-                    if ( walkOnTree( list.item( i ) ) )
-                    {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-
-    }
-
-
-    /**
-     * put the resource bundle in the tree.
-     * @param node Node on the xml file
-     * @param id id of the bundle ressource
-     */
-    private void searchRepository( Node node, String id )
-    {
-        if ( node.getNodeName().compareTo( "repository" ) == 0 )
-        {
-            node.appendChild( m_resourceBundle.getNode( m_repoDoc ) );
-            return;
-        }
-        else
-        {
-            System.out.println( "Second branch..." );
-            NodeList list = node.getChildNodes();
-            if ( list.getLength() > 0 )
-            {
-                for ( int i = 0; i < list.getLength(); i++ )
-                {
-                    searchRepository( list.item( i ), id );
-                }
-            }
-        }
-
-    }
-
-
-    /**
-     * compare two node and update the array which compute the smallest free id.
-     * @param node : node
-     * @return true if the node is the same bundle than the ressourceBundle, else false.
-     */
-    private boolean resource( Node node )
-    {
-
-        // this part save all the id free if we need to add resource
-        String id = node.getAttributes().getNamedItem( "id" ).getNodeValue();
-        NamedNodeMap map = node.getAttributes();
-
-        if ( m_resourceBundle.isSameBundleResource( map.getNamedItem( "symbolicname" ).getNodeValue(), map
-            .getNamedItem( "version" ).getNodeValue() ) )
-        {
-            m_resourceBundle.setId( String.valueOf( id ) );
-            node.getParentNode().replaceChild( m_resourceBundle.getNode( m_repoDoc ), node );
-            return true;
-        }
-        return false;
-    }
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+
+/**
+ * this class parse the old repository.xml file build the bundle resource description and update the repository.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+
+public class ObrUpdate
+{
+    /**
+     * generate the date format to insert it in repository descriptor file.
+     */
+    static SimpleDateFormat m_format = new SimpleDateFormat( "yyyyMMddHHmmss.SSS" );
+
+    /**
+     * logger for this plugin.
+     */
+    private Log m_logger;
+
+    /**
+     * name and path to the repository descriptor file.
+     */
+    private URI m_repoFilename;
+
+    /**
+     * name and path to the obr.xml file.
+     */
+    private String m_obrXml;
+
+    /**
+     * name and path to the bundle jar file.
+     */
+    private String m_outputFile;
+
+    /**
+     * maven project description.
+     */
+    private MavenProject m_project;
+
+    /**
+     * user configuration information.
+     */
+    private Config m_userConfig;
+
+    /**
+     * used to build another xml document.
+     */
+    private DocumentBuilder m_constructor;
+
+    /**
+     * root on parent document.
+     */
+    private Document m_repoDoc;
+
+    /**
+     * first Node on repository descriptor tree.
+     */
+    private Node m_root;
+
+    /**
+     * used to extract bindex bundle information.
+     */
+    private ExtractBindexInfo m_ebi;
+
+    /**
+     * used to store bundle information.
+     */
+    private ResourcesBundle m_resourceBundle;
+
+    /**
+     * pathfile to the repository descriptor file.
+     */
+    private PathFile m_repo;
+
+
+    /**
+     * initialize information.
+     * @param repoFilename path to the repository descriptor file
+     * @param obrXml path and filename to the obr.xml file
+     * @param project maven project description
+     * @param outputFile path to the bundle jar file
+     * @param localRepo only path to the local repository
+     * @param userConfig user information
+     * @param log plugin logger
+     */
+    public ObrUpdate( PathFile repoFilename, String obrXml, MavenProject project, String outputFile, String localRepo,
+        Config userConfig, Log log )
+    {
+        // this.m_localRepo = localRepo;
+        this.m_outputFile = outputFile;
+        this.m_repoFilename = repoFilename.getUri();
+        this.m_obrXml = obrXml;
+        this.m_project = project;
+        this.m_logger = log;
+
+        this.m_userConfig = userConfig;
+
+        m_resourceBundle = new ResourcesBundle( log );
+
+        if ( userConfig.isRemotely() )
+        {
+            this.m_repo = new PathFile( localRepo );
+        }
+        else
+        {
+            this.m_repo = repoFilename;
+        }
+    }
+
+
+    /**
+     * update the repository descriptor file. parse the old repository descriptor file, get the old reference of the bundle or determine the id for a new bundle, extract information from bindex set the new information in descriptor file and save it.
+     * @throws MojoExecutionException if the plugin failed
+     */
+    public void updateRepository() throws MojoExecutionException
+    {
+
+        m_logger.debug( " (f) m_obrXml = " + m_obrXml );
+        m_logger.debug( " (f) m_outputFile = " + m_outputFile );
+        m_logger.debug( " (f) m_repoFilename = " + m_repoFilename );
+
+        m_constructor = initConstructor();
+
+        if ( m_constructor == null )
+        {
+            return;
+        }
+
+        // get the file size
+        PathFile pf = new PathFile( m_outputFile );
+        File fout = pf.getFile();
+        pf.setBaseDir( m_repo.getOnlyAbsolutePath() );
+        if ( fout.exists() )
+        {
+            m_resourceBundle.setSize( String.valueOf( fout.length() ) );
+            if ( m_userConfig.isPathRelative() )
+            {
+                m_resourceBundle.setUri( pf.getOnlyRelativeFilename().replace( '\\', '/' ) );
+            }
+            else
+            {
+                m_resourceBundle.setUri( "file:" + m_outputFile );
+            }
+        }
+        else
+        {
+            m_logger.error( "file doesn't exist: " + m_outputFile );
+            return;
+        }
+
+        // parse repository
+        if ( parseRepositoryXml() == -1 )
+        {
+            return;
+        }
+
+        // parse the obr.xml file
+        if ( m_obrXml != null )
+        {
+            // URL url = getClass().getResource("/SchemaObr.xsd");
+            // TODO validate obr.xml file
+
+            Document obrXmlDoc = parseFile( m_obrXml, m_constructor );
+            if ( obrXmlDoc == null )
+            {
+                return;
+            }
+            Node obrXmlRoot = ( Element ) obrXmlDoc.getDocumentElement();
+            // sort the obr file
+            sortObrXml( obrXmlRoot );
+        }
+
+        // use bindex to extract bundle information
+        try
+        {
+            m_ebi = new ExtractBindexInfo( m_repoFilename, m_outputFile );
+        }
+        catch ( MojoExecutionException e )
+        {
+            m_logger.error( "unable to build Bindex informations" );
+            e.printStackTrace();
+            throw new MojoExecutionException( "MojoFailureException" );
+        }
+
+        m_resourceBundle.construct( m_project, m_ebi );
+
+        if ( !walkOnTree( m_root ) )
+        {
+            // the correct resource node was not found, we must create it
+            // we compute the new id
+            String id = m_resourceBundle.getId();
+            searchRepository( m_root, id );
+        }
+
+        // the repository.xml file have been modified, so we save it
+        m_logger.info( "Writing OBR metadata" );
+        writeToFile( m_repoFilename, m_root );
+    }
+
+
+    /**
+     * init the document builder from xerces.
+     * @return DocumentBuilder ready to create new document
+     */
+    private DocumentBuilder initConstructor()
+    {
+        DocumentBuilder constructor = null;
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        try
+        {
+            constructor = factory.newDocumentBuilder();
+        }
+        catch ( ParserConfigurationException e )
+        {
+            m_logger.error( "unable to create a new xml document" );
+            e.printStackTrace();
+        }
+        return constructor;
+
+    }
+
+
+    /**
+     * Parse the repository descriptor file.
+     * 
+     * @return 0 if the bundle is already in the descriptor, else -1
+     * @throws MojoExecutionException if the plugin failed
+     */
+    private int parseRepositoryXml() throws MojoExecutionException
+    {
+
+        File fout = new File( m_repoFilename );
+        if ( !fout.exists() )
+        {
+            // create the repository.xml
+            try
+            {
+                fout.createNewFile();
+                m_logger.info( "Created " + fout.getAbsolutePath() );
+            }
+            catch ( IOException e )
+            {
+                m_logger.error( "Cannot create file " + fout.getAbsolutePath() );
+                e.printStackTrace();
+                return -1;
+            }
+
+            Document doc = m_constructor.newDocument();
+            // create xml tree
+            Date d = new Date();
+            d.setTime( System.currentTimeMillis() );
+            Element root = doc.createElement( "repository" );
+            root.setAttribute( "lastmodified", m_format.format( d ) );
+            root.setAttribute( "name", "MyRepository" );
+            try
+            {
+                writeToFile( m_repoFilename, root );
+            }
+            catch ( MojoExecutionException e )
+            {
+                e.printStackTrace();
+                throw new MojoExecutionException( "MojoExecutionException" );
+            }
+        }
+
+        // now we parse the repository.xml file
+        m_repoDoc = parseFile( fout.getAbsolutePath(), m_constructor );
+        if ( m_repoDoc == null )
+        {
+            return -1;
+        }
+
+        m_root = ( Element ) m_repoDoc.getDocumentElement();
+        return 0;
+    }
+
+
+    /**
+     * transform a xml file to a xerces Document.
+     * @param filename path to the xml file
+     * @param constructor DocumentBuilder get from xerces
+     * @return Document which describe this file
+     */
+    private Document parseFile( String filename, DocumentBuilder constructor )
+    {
+        if ( constructor == null )
+        {
+            return null;
+        }
+        // The document is the root of the DOM tree.
+        m_logger.info( "Parsing " + filename );
+        Document doc = null;
+        try
+        {
+            doc = constructor.parse( new File( filename ) );
+        }
+        catch ( SAXException e )
+        {
+            e.printStackTrace();
+            return null;
+        }
+        catch ( IOException e )
+        {
+            m_logger.error( "cannot open file: " + filename );
+            e.printStackTrace();
+            return null;
+        }
+        return doc;
+    }
+
+
+    /**
+     * put the information from obr.xml into ressourceBundle object.
+     * @param node Node to the OBR.xml file
+     */
+    private void sortObrXml( Node node )
+    {
+        if ( node.getNodeName().compareTo( "require" ) == 0 )
+        {
+            Require newRequireNode = new Require();
+            NamedNodeMap list = node.getAttributes();
+            try
+            {
+                newRequireNode.setExtend( list.getNamedItem( "extend" ).getNodeValue() );
+                newRequireNode.setMultiple( list.getNamedItem( "multiple" ).getNodeValue() );
+                newRequireNode.setOptional( list.getNamedItem( "optional" ).getNodeValue() );
+                newRequireNode.setFilter( list.getNamedItem( "filter" ).getNodeValue() );
+                newRequireNode.setName( list.getNamedItem( "name" ).getNodeValue() );
+            }
+            catch ( NullPointerException e )
+            {
+                m_logger
+                    .error( "the obr.xml file seems to be invalid in a \"require\" tag (one or more attributes are missing)" );
+                // e.printStackTrace();
+            }
+            newRequireNode.setValue( XmlHelper.getTextContent( node ) );
+            m_resourceBundle.addRequire( newRequireNode );
+        }
+        else if ( node.getNodeName().compareTo( "capability" ) == 0 )
+        {
+            Capability newCapability = new Capability();
+            try
+            {
+                newCapability.setName( node.getAttributes().getNamedItem( "name" ).getNodeValue() );
+            }
+            catch ( NullPointerException e )
+            {
+                m_logger.error( "attribute \"name\" is missing in obr.xml in a \"capability\" tag" );
+                e.printStackTrace();
+            }
+            NodeList list = node.getChildNodes();
+            for ( int i = 0; i < list.getLength(); i++ )
+            {
+                PElement p = new PElement();
+                Node n = list.item( i );
+                Node item = null;
+                // System.err.println(n.getNodeName());
+                if ( n.getNodeName().compareTo( "p" ) == 0 )
+                {
+
+                    p.setN( n.getAttributes().getNamedItem( "n" ).getNodeValue() );
+                    item = n.getAttributes().getNamedItem( "t" );
+                    if ( item != null )
+                    {
+                        p.setT( item.getNodeValue() );
+                    }
+                    item = n.getAttributes().getNamedItem( "v" );
+                    if ( item != null )
+                    {
+                        p.setV( item.getNodeValue() );
+                    }
+
+                    newCapability.addP( p );
+                }
+            }
+            m_resourceBundle.addCapability( newCapability );
+        }
+        else if ( node.getNodeName().compareTo( "category" ) == 0 )
+        {
+            Category newCategory = new Category();
+            newCategory.setId( node.getAttributes().getNamedItem( "id" ).getNodeValue() );
+            m_resourceBundle.addCategory( newCategory );
+        }
+        else
+        {
+            NodeList list = node.getChildNodes();
+            for ( int i = 0; i < list.getLength(); i++ )
+            {
+                sortObrXml( list.item( i ) );
+            }
+        }
+    }
+
+
+    /**
+     * write a Node in a xml file.
+     * @param outputFilename URI to the output file
+     * @param treeToBeWrite Node root of the tree to be write in file
+     * @throws MojoExecutionException if the plugin failed
+     */
+    private void writeToFile( URI outputFilename, Node treeToBeWrite ) throws MojoExecutionException
+    {
+        // init the transformer
+        Transformer transformer = null;
+        TransformerFactory tfabrique = TransformerFactory.newInstance();
+        try
+        {
+            transformer = tfabrique.newTransformer();
+        }
+        catch ( TransformerConfigurationException e )
+        {
+            m_logger.error( "Unable to write to file: " + outputFilename.toString() );
+            e.printStackTrace();
+            throw new MojoExecutionException( "TransformerConfigurationException" );
+        }
+        Properties proprietes = new Properties();
+        proprietes.put( "method", "xml" );
+        proprietes.put( "version", "1.0" );
+        proprietes.put( "encoding", "ISO-8859-1" );
+        proprietes.put( "standalone", "yes" );
+        proprietes.put( "indent", "yes" );
+        proprietes.put( "omit-xml-declaration", "no" );
+        transformer.setOutputProperties( proprietes );
+
+        DOMSource input = new DOMSource( treeToBeWrite );
+
+        File fichier = new File( outputFilename );
+        FileOutputStream flux = null;
+        try
+        {
+            flux = new FileOutputStream( fichier );
+        }
+        catch ( FileNotFoundException e )
+        {
+            m_logger.error( "Unable to write to file: " + fichier.getName() );
+            e.printStackTrace();
+            throw new MojoExecutionException( "FileNotFoundException" );
+        }
+        Result output = new StreamResult( flux );
+        try
+        {
+            transformer.transform( input, output );
+        }
+        catch ( TransformerException e )
+        {
+            e.printStackTrace();
+            throw new MojoExecutionException( "TransformerException" );
+        }
+
+        try
+        {
+            flux.flush();
+            flux.close();
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw new MojoExecutionException( "IOException" );
+        }
+
+    }
+
+
+    /**
+     * walk on the tree until the targeted node was found.
+     * @param node targeted node
+     * @return true if the requiered node was found else false.
+     */
+    private boolean walkOnTree( Node node )
+    {
+
+        if ( node.getNodeName().compareTo( "resource" ) == 0 )
+        {
+            return resource( node );
+        }
+        else
+        { // look at the repository node (first in the file)
+            if ( node.getNodeName().compareTo( "repository" ) == 0 )
+            {
+                Date d = new Date();
+                d.setTime( System.currentTimeMillis() );
+                NamedNodeMap nList = node.getAttributes();
+                Node n = nList.getNamedItem( "lastmodified" );
+                n.setNodeValue( m_format.format( d ) );
+            }
+            NodeList list = node.getChildNodes();
+            if ( list.getLength() > 0 )
+            {
+                for ( int i = 0; i < list.getLength(); i++ )
+                {
+                    if ( walkOnTree( list.item( i ) ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+    }
+
+
+    /**
+     * put the resource bundle in the tree.
+     * @param node Node on the xml file
+     * @param id id of the bundle ressource
+     */
+    private void searchRepository( Node node, String id )
+    {
+        if ( node.getNodeName().compareTo( "repository" ) == 0 )
+        {
+            node.appendChild( m_resourceBundle.getNode( m_repoDoc ) );
+            return;
+        }
+        else
+        {
+            System.out.println( "Second branch..." );
+            NodeList list = node.getChildNodes();
+            if ( list.getLength() > 0 )
+            {
+                for ( int i = 0; i < list.getLength(); i++ )
+                {
+                    searchRepository( list.item( i ), id );
+                }
+            }
+        }
+
+    }
+
+
+    /**
+     * compare two node and update the array which compute the smallest free id.
+     * @param node : node
+     * @return true if the node is the same bundle than the ressourceBundle, else false.
+     */
+    private boolean resource( Node node )
+    {
+
+        // this part save all the id free if we need to add resource
+        String id = node.getAttributes().getNamedItem( "id" ).getNodeValue();
+        NamedNodeMap map = node.getAttributes();
+
+        if ( m_resourceBundle.isSameBundleResource( map.getNamedItem( "symbolicname" ).getNodeValue(), map
+            .getNamedItem( "version" ).getNodeValue() ) )
+        {
+            m_resourceBundle.setId( String.valueOf( id ) );
+            node.getParentNode().replaceChild( m_resourceBundle.getNode( m_repoDoc ), node );
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PElement.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PElement.java
index 8a51bd8..cdc21e9 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PElement.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PElement.java
@@ -1,131 +1,131 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-
-/**
- * this class describe the p element in a capability tag.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- * 
- */
-public class PElement
-{
-    /**
-     * store the v tag (value).
-     */
-    private String m_v;
-
-    /**
-     * store the t tag (type).
-     */
-    private String m_t;
-
-    /**
-     * store the n tag (name).
-     */
-    private String m_n;
-
-
-    /**
-     * get the n tag.
-     * @return attribute n
-     */
-    public String getN()
-    {
-        return m_n;
-    }
-
-
-    /**
-     * set the n tage.
-     * @param n new value
-     */
-    public void setN( String n )
-    {
-        this.m_n = n;
-    }
-
-
-    /**
-     * get the t tag.
-     * @return attribute t
-     */
-    public String getT()
-    {
-        return m_t;
-    }
-
-
-    /**
-     * set the t tag.
-     * @param t new value
-     */
-    public void setT( String t )
-    {
-        this.m_t = t;
-    }
-
-
-    /**
-     * get the v tag.
-     * @return attribute v
-     */
-    public String getV()
-    {
-        return m_v;
-    }
-
-
-    /**
-     * set the v tag.
-     * @param v new value
-     */
-    public void setV( String v )
-    {
-        this.m_v = v;
-    }
-
-
-    /**
-     * transform this object to node.
-     * @param father father document for create Node
-     * @return node
-     */
-    public Node getNode( Document father )
-    {
-        Element p = father.createElement( "p" );
-        p.setAttribute( "n", this.getN() );
-        if ( this.getT() != null )
-        {
-            p.setAttribute( "t", this.getT() );
-        }
-
-        if ( this.getV() != null )
-        {
-            p.setAttribute( "v", this.getV() );
-        }
-
-        return p;
-    }
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * this class describe the p element in a capability tag.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * 
+ */
+public class PElement
+{
+    /**
+     * store the v tag (value).
+     */
+    private String m_v;
+
+    /**
+     * store the t tag (type).
+     */
+    private String m_t;
+
+    /**
+     * store the n tag (name).
+     */
+    private String m_n;
+
+
+    /**
+     * get the n tag.
+     * @return attribute n
+     */
+    public String getN()
+    {
+        return m_n;
+    }
+
+
+    /**
+     * set the n tage.
+     * @param n new value
+     */
+    public void setN( String n )
+    {
+        this.m_n = n;
+    }
+
+
+    /**
+     * get the t tag.
+     * @return attribute t
+     */
+    public String getT()
+    {
+        return m_t;
+    }
+
+
+    /**
+     * set the t tag.
+     * @param t new value
+     */
+    public void setT( String t )
+    {
+        this.m_t = t;
+    }
+
+
+    /**
+     * get the v tag.
+     * @return attribute v
+     */
+    public String getV()
+    {
+        return m_v;
+    }
+
+
+    /**
+     * set the v tag.
+     * @param v new value
+     */
+    public void setV( String v )
+    {
+        this.m_v = v;
+    }
+
+
+    /**
+     * transform this object to node.
+     * @param father father document for create Node
+     * @return node
+     */
+    public Node getNode( Document father )
+    {
+        Element p = father.createElement( "p" );
+        p.setAttribute( "n", this.getN() );
+        if ( this.getT() != null )
+        {
+            p.setAttribute( "t", this.getT() );
+        }
+
+        if ( this.getV() != null )
+        {
+            p.setAttribute( "v", this.getV() );
+        }
+
+        return p;
+    }
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PathFile.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PathFile.java
index bd9e693..71c19d3 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PathFile.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/PathFile.java
@@ -1,739 +1,739 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.channels.FileChannel;
-
-
-/**
- * this class provide some functions to simplify file manipulation.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class PathFile
-{
-
-    /**
-     * full filename.
-     */
-    private String m_fullFilename;
-
-    /**
-     * store only the filename of the file.
-     */
-    private String m_fileName;
-
-    /**
-     * store only the path of this file.
-     */
-    private String m_pathFile;
-
-    /**
-     * store the base Directory in case of relative path.
-     */
-    private String m_baseDir;
-
-    /**
-     * store the protocol used (ie:file, http...).
-     */
-    private String m_protocol;
-
-    /**
-     * if the path is relative or absolute.
-     */
-    private boolean m_relative;
-
-    /**
-     * if this file is a folder.
-     */
-    private boolean m_folder;
-
-    /**
-     * if the file exist or not.
-     */
-    private boolean m_exist;
-
-    /**
-     * if this file is a file (not a folder).
-     */
-    private boolean m_file;
-
-    /**
-     * if this filename is valid or incomplete.
-     */
-    private boolean m_valid;
-
-
-    /**
-     * build all the attribute information.
-     * @param filename path to the file
-     */
-    public PathFile( String filename )
-    {
-
-        this.m_fullFilename = filename;
-        if ( filename == null )
-        {
-            this.m_valid = false;
-            return;
-        }
-        this.m_valid = true;
-        m_protocol = extractProtocol( filename );
-        m_pathFile = extractPathFile( filename );
-        if ( m_pathFile.startsWith( "//" ) )
-        {
-            // avoid problems on Unix like system
-            m_pathFile = m_pathFile.substring( 1 );
-        }
-        m_fileName = extractFileName( filename );
-        m_relative = extractRelative();
-        if ( !m_relative && ( getProtocol().compareTo( "file" ) == 0 || getProtocol().compareTo( "" ) == 0 ) )
-        {
-            File f = new File( getOnlyAbsoluteFilename() );
-            m_file = f.isFile();
-            m_folder = f.isDirectory();
-            m_exist = f.exists();
-            if ( m_folder )
-            {
-                m_pathFile = m_pathFile + m_fileName + File.separator;
-                m_fileName = "";
-            }
-        }
-        if ( m_exist )
-        {
-            m_protocol = "file";
-        }
-        else
-        {
-            if ( m_fileName.compareTo( "" ) == 0 )
-            {
-                m_folder = true;
-                m_file = false;
-            }
-            else
-            {
-                m_folder = false;
-                m_file = true;
-            }
-
-        }
-
-        // add the '/' before the complete path if it is absolute path
-        if ( !this.isRelative() && !m_pathFile.startsWith( "/" ) )
-        {
-            m_pathFile = "/".concat( m_pathFile );
-        }
-
-    }
-
-
-    /**
-     * get if the filename is relative or absolute.
-     * @return true if the path is relative, else false
-     */
-    private boolean extractRelative()
-    {
-        if ( m_pathFile.startsWith( "." + File.separator, 1 ) || m_pathFile.startsWith( ".." + File.separator, 1 ) )
-        {
-            m_pathFile = m_pathFile.substring( 1 );
-            m_valid = false;
-            return true;
-        }
-
-        return false;
-    }
-
-
-    /**
-     * get only the name from the filename.
-     * @param fullFilename full filename
-     * @return the name of the file or folder
-     */
-    private String extractFileName( String fullFilename )
-    {
-        int index = fullFilename.lastIndexOf( '/' ); // Given path 
-        return fullFilename.substring( index + 1, fullFilename.length() );
-    }
-
-
-    /**
-     * get the path from the filename.
-     * @param fullFilename full filename
-     * @return the path of the file
-     */
-    private String extractPathFile( String fullFilename )
-    {
-        String substring;
-        if ( extractFileName( fullFilename ).compareTo( "" ) == 0 )
-        {
-            // it is a folder
-            substring = fullFilename;
-        }
-        else
-        {
-            substring = fullFilename.substring( 0, fullFilename.indexOf( extractFileName( fullFilename ) ) );
-        }
-
-        if ( getProtocol().compareTo( "" ) != 0 )
-        {
-            substring = substring.substring( 5 );
-        }
-
-        return substring;
-    }
-
-
-    /**
-     * determine which protocol is used.
-     * @param filename the full fileneme
-     * @return "file" or "http" or ""
-     */
-    private String extractProtocol( String filename )
-    {
-        if ( filename.startsWith( "file:" ) )
-        {
-            return "file";
-        }
-        if ( filename.startsWith( "http:" ) )
-        {
-            return "http";
-        }
-        return "";
-    }
-
-
-    /**
-     * set the base directory.
-     * @param baseDir new value for the base directory
-     */
-    public void setBaseDir( String baseDir )
-    {
-        this.m_baseDir = baseDir;
-        if ( isRelative() && this.m_fullFilename != null )
-        {
-            this.m_valid = true;
-            if ( getProtocol().compareTo( "file" ) == 0 || getProtocol().compareTo( "" ) == 0 )
-            {
-                File f = new File( getOnlyAbsoluteFilename() );
-                m_file = f.isFile();
-                m_folder = f.isDirectory();
-                m_exist = f.exists();
-            }
-            if ( m_exist )
-            {
-                m_protocol = "file";
-            }
-        }
-
-    }
-
-
-    /**
-     * get the base directory.
-     * @return base directory
-     */
-    public String getBaseDir()
-    {
-        return this.m_baseDir;
-    }
-
-
-    public boolean isValid()
-    {
-        return m_valid;
-    }
-
-
-    public boolean isRelative()
-    {
-        return m_relative;
-    }
-
-
-    public boolean isExists()
-    {
-        return m_exist;
-    }
-
-
-    public boolean isFile()
-    {
-        return m_file;
-    }
-
-
-    public boolean isFolder()
-    {
-        return m_folder;
-    }
-
-
-    /**
-     * get a File which points on the same file.
-     * @return a File object
-     */
-    public File getFile()
-    {
-        if ( !this.isValid() )
-        {
-            return null;
-        }
-        String path = PathFile.uniformSeparator( this.getOnlyAbsoluteFilename() );
-        if ( File.separatorChar == '\\' )
-        {
-            path = path.replace( '\\', '/' );
-        }
-        File f = new File( path );
-        return f;
-    }
-
-
-    /**
-     * get an URI which points on the same file.
-     * @return an URI object
-     */
-    public URI getUri()
-    {
-        if ( !this.isValid() )
-        {
-            return null;
-        }
-        String path = PathFile.uniformSeparator( getAbsoluteFilename() );
-        if ( File.separatorChar == '\\' )
-        {
-            path = path.replace( '\\', '/' );
-        }
-
-        path = path.replaceAll( " ", "%20" );
-
-        URI uri = null;
-        try
-        {
-            uri = new URI( path );
-        }
-        catch ( URISyntaxException e )
-        {
-            System.err.println( "Malformed URI: " + path );
-            System.err.println( e.getMessage() );
-            return null;
-        }
-        return uri;
-    }
-
-
-    /**
-     * get protocol + relative path of this file.
-     * @return the relative path or null if it is not valid
-     */
-    public String getRelativePath()
-    {
-        if ( !this.isValid() )
-        {
-            return null;
-        }
-
-        return getProtocol() + ":/" + getOnlyRelativePath();
-    }
-
-
-    /**
-     * get only (without protocol) relative path of this file.
-     * @return the relative path or null if it is not valid
-     */
-    public String getOnlyRelativePath()
-    {
-        if ( !this.isValid() )
-        {
-            return null;
-        }
-        if ( this.isRelative() )
-        {
-            return m_pathFile;
-
-        }
-        else
-        {
-            if ( m_baseDir != null )
-            {
-                // System.err.println(m_pathFile);
-                // System.err.println(m_baseDir);
-                if ( m_pathFile.startsWith( m_baseDir ) )
-                {
-                    /*
-                     * String ch1 = m_pathFile; String ch2 = m_baseDir; System.err.println(ch1); System.err.println(ch2); System.err.println("."+File.separator+ch1.substring(ch2.length()));
-                     */
-                    return "." + File.separator + m_pathFile.substring( m_baseDir.length() );
-                }
-            }
-            return m_pathFile;
-        }
-    }
-
-
-    /**
-     * calcul absolute path from relative path.
-     * @param baseDir base directory
-     * @param path path to convert
-     * @return the absolute path or null
-     */
-    private String calculAbsolutePath( String baseDir, String path )
-    {
-        if ( path.startsWith( ".." + File.separatorChar ) )
-        {
-            String base = baseDir;
-            int lastIndex;
-            lastIndex = base.lastIndexOf( File.separator );
-            if ( lastIndex == base.length() )
-            {
-                base = base.substring( 0, base.length() - 1 );
-                lastIndex = base.lastIndexOf( File.separator );
-            }
-            if ( lastIndex < base.length() )
-            {
-                return calculAbsolutePath( base.substring( 0, lastIndex + 1 ), path.substring( 3 ) );
-            }
-            else
-            {
-                return null;
-            }
-        }
-        else if ( path.startsWith( "." + File.separatorChar ) )
-        {
-            String res;
-            if ( File.separatorChar == '\\' )
-            {
-                res = path.replaceFirst( ".", baseDir.replace( '\\', '/' ) );
-            }
-            else
-            {
-                res = path.replaceFirst( ".", baseDir );
-            }
-
-            return PathFile.uniformSeparator( res );
-        }
-        else
-        {
-            return PathFile.uniformSeparator( baseDir + path );
-        }
-    }
-
-
-    /**
-     * get only (without protocol) absolute path (without filename).
-     * @return absolute path
-     */
-    public String getOnlyAbsolutePath()
-    {
-        if ( !this.isValid() )
-        {
-            return null;
-        }
-        if ( isRelative() )
-        {
-            return calculAbsolutePath( m_baseDir, m_pathFile );
-        }
-        else
-        {
-            return m_pathFile;
-        }
-    }
-
-
-    /**
-     * get protocol + absolute path (without filename).
-     * @return absolute path
-     */
-    public String getAbsolutePath()
-    {
-
-        if ( isRelative() )
-        {
-            return getProtocol() + ":/" + calculAbsolutePath( m_baseDir, m_pathFile );
-        }
-        else
-        {
-            if ( getProtocol().compareTo( "" ) == 0 || m_pathFile == null )
-            {
-                return m_pathFile;
-            }
-            else
-            {
-                return getProtocol() + ":" + m_pathFile;
-            }
-        }
-    }
-
-
-    /**
-     * get only (without protocol) absolute path + filename.
-     * @return absolute filename
-     */
-    public String getOnlyAbsoluteFilename()
-    {
-        if ( getOnlyAbsolutePath() != null && getFilename() != null )
-        {
-            return getOnlyAbsolutePath() + getFilename();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * get protocol + absolute path + filename.
-     * @return absolute filenama
-     */
-    public String getAbsoluteFilename()
-    {
-        if ( getAbsolutePath() != null && getFilename() != null )
-        {
-            return getAbsolutePath() + getFilename();
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * get only (without protocol) relative path + filename.
-     * @return relative filename
-     */
-    public String getOnlyRelativeFilename()
-    {
-        if ( !this.isValid() )
-        {
-            return "";
-        }
-
-        return getOnlyRelativePath() + getFilename();
-
-    }
-
-
-    /**
-     * get protocol + relative path + filename.
-     * @return relative filename
-     */
-    public String getRelativeFilename()
-    {
-        if ( !this.isValid() )
-        {
-            return "";
-        }
-
-        if ( this.isRelative() )
-        {
-            return getRelativePath() + getFilename();
-        }
-        else
-        {
-            return getAbsoluteFilename();
-        }
-    }
-
-
-    public String getFilename()
-    {
-        return m_fileName;
-    }
-
-
-    public String getProtocol()
-    {
-        return m_protocol;
-    }
-
-
-    /**
-     * create all the directories not also present in the current path.
-     * @return true if all directories was created, else false
-     */
-    public boolean createPath()
-    {
-        File path = new File( this.getOnlyAbsolutePath() );
-        if ( path.exists() )
-        {
-            return true;
-        }
-        return path.mkdirs();
-    }
-
-
-    /**
-     * create all the directories not also present in the current path and the file.
-     * @return true it was created, else false
-     */
-    public boolean createFile()
-    {
-        File path = new File( this.getOnlyAbsolutePath() );
-        if ( !path.exists() )
-        {
-            if ( !this.createPath() )
-            {
-                return false;
-            }
-        }
-        path = new File( this.getOnlyAbsoluteFilename() );
-        try
-        {
-            return path.createNewFile();
-        }
-        catch ( IOException e )
-        {
-            return false;
-        }
-
-    }
-
-
-    /**
-     * delete the current file.
-     * @return true if it was deleted, else false
-     */
-    public boolean delete()
-    {
-        File path = new File( this.getAbsoluteFilename() );
-        if ( path.exists() )
-        {
-            return path.delete();
-        }
-        else
-        {
-            return true;
-        }
-
-    }
-
-    private static final String REGEXP_BACKSLASH = "\\\\";
-
-
-    /**
-     * replace all '\' by '\\' in the given string.
-     * @param path string where replace the search pattern
-     * @return string replaced
-     */
-    public static String doubleSeparator( String path )
-    {
-        // double the '\' in the path
-        if ( path != null && File.separatorChar == '\\' )
-        {
-            return path.replaceAll( REGEXP_BACKSLASH, REGEXP_BACKSLASH + REGEXP_BACKSLASH );
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * file separator('\' or '/') by the one of the current system.
-     * @param path string where replace the search pattern
-     * @return string replaced
-     */
-    public static String uniformSeparator( String path )
-    {
-        if ( File.separatorChar == '\\' )
-        {
-            if ( path.startsWith( "/" ) )
-            {
-                return path.substring( 1 ).replace( '/', File.separatorChar );
-            }
-            else
-            {
-                return path.replace( '/', File.separatorChar );
-            }
-        }
-        else
-        {
-            return path.replace( '\\', File.separatorChar );
-        }
-    }
-
-
-    /**
-     * copy file from src to dest.
-     * @param src source file
-     * @param dest destination file
-     * @return true if the file was correctly copied, else false
-     */
-    public static boolean copyFile( PathFile src, PathFile dest )
-    {
-        FileChannel in = null;
-        FileChannel out = null;
-
-        if ( !src.isExists() )
-        {
-            System.err.println( "src file must exist: " + src.getAbsoluteFilename() );
-            return false;
-        }
-        if ( !dest.isExists() )
-        {
-            dest.createFile();
-        }
-        try
-        {
-            in = new FileInputStream( src.getOnlyAbsoluteFilename() ).getChannel();
-            out = new FileOutputStream( dest.getOnlyAbsoluteFilename() ).getChannel();
-
-            in.transferTo( 0, in.size(), out );
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-        }
-        finally
-        {
-            if ( in != null )
-            {
-                try
-                {
-                    in.close();
-                }
-                catch ( IOException e )
-                {
-                    return false;
-                }
-            }
-            if ( out != null )
-            {
-                try
-                {
-                    out.close();
-                }
-                catch ( IOException e )
-                {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.channels.FileChannel;
+
+
+/**
+ * this class provide some functions to simplify file manipulation.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PathFile
+{
+
+    /**
+     * full filename.
+     */
+    private String m_fullFilename;
+
+    /**
+     * store only the filename of the file.
+     */
+    private String m_fileName;
+
+    /**
+     * store only the path of this file.
+     */
+    private String m_pathFile;
+
+    /**
+     * store the base Directory in case of relative path.
+     */
+    private String m_baseDir;
+
+    /**
+     * store the protocol used (ie:file, http...).
+     */
+    private String m_protocol;
+
+    /**
+     * if the path is relative or absolute.
+     */
+    private boolean m_relative;
+
+    /**
+     * if this file is a folder.
+     */
+    private boolean m_folder;
+
+    /**
+     * if the file exist or not.
+     */
+    private boolean m_exist;
+
+    /**
+     * if this file is a file (not a folder).
+     */
+    private boolean m_file;
+
+    /**
+     * if this filename is valid or incomplete.
+     */
+    private boolean m_valid;
+
+
+    /**
+     * build all the attribute information.
+     * @param filename path to the file
+     */
+    public PathFile( String filename )
+    {
+
+        this.m_fullFilename = filename;
+        if ( filename == null )
+        {
+            this.m_valid = false;
+            return;
+        }
+        this.m_valid = true;
+        m_protocol = extractProtocol( filename );
+        m_pathFile = extractPathFile( filename );
+        if ( m_pathFile.startsWith( "//" ) )
+        {
+            // avoid problems on Unix like system
+            m_pathFile = m_pathFile.substring( 1 );
+        }
+        m_fileName = extractFileName( filename );
+        m_relative = extractRelative();
+        if ( !m_relative && ( getProtocol().compareTo( "file" ) == 0 || getProtocol().compareTo( "" ) == 0 ) )
+        {
+            File f = new File( getOnlyAbsoluteFilename() );
+            m_file = f.isFile();
+            m_folder = f.isDirectory();
+            m_exist = f.exists();
+            if ( m_folder )
+            {
+                m_pathFile = m_pathFile + m_fileName + File.separator;
+                m_fileName = "";
+            }
+        }
+        if ( m_exist )
+        {
+            m_protocol = "file";
+        }
+        else
+        {
+            if ( m_fileName.compareTo( "" ) == 0 )
+            {
+                m_folder = true;
+                m_file = false;
+            }
+            else
+            {
+                m_folder = false;
+                m_file = true;
+            }
+
+        }
+
+        // add the '/' before the complete path if it is absolute path
+        if ( !this.isRelative() && !m_pathFile.startsWith( "/" ) )
+        {
+            m_pathFile = "/".concat( m_pathFile );
+        }
+
+    }
+
+
+    /**
+     * get if the filename is relative or absolute.
+     * @return true if the path is relative, else false
+     */
+    private boolean extractRelative()
+    {
+        if ( m_pathFile.startsWith( "." + File.separator, 1 ) || m_pathFile.startsWith( ".." + File.separator, 1 ) )
+        {
+            m_pathFile = m_pathFile.substring( 1 );
+            m_valid = false;
+            return true;
+        }
+
+        return false;
+    }
+
+
+    /**
+     * get only the name from the filename.
+     * @param fullFilename full filename
+     * @return the name of the file or folder
+     */
+    private String extractFileName( String fullFilename )
+    {
+        int index = fullFilename.lastIndexOf( '/' ); // Given path 
+        return fullFilename.substring( index + 1, fullFilename.length() );
+    }
+
+
+    /**
+     * get the path from the filename.
+     * @param fullFilename full filename
+     * @return the path of the file
+     */
+    private String extractPathFile( String fullFilename )
+    {
+        String substring;
+        if ( extractFileName( fullFilename ).compareTo( "" ) == 0 )
+        {
+            // it is a folder
+            substring = fullFilename;
+        }
+        else
+        {
+            substring = fullFilename.substring( 0, fullFilename.indexOf( extractFileName( fullFilename ) ) );
+        }
+
+        if ( getProtocol().compareTo( "" ) != 0 )
+        {
+            substring = substring.substring( 5 );
+        }
+
+        return substring;
+    }
+
+
+    /**
+     * determine which protocol is used.
+     * @param filename the full fileneme
+     * @return "file" or "http" or ""
+     */
+    private String extractProtocol( String filename )
+    {
+        if ( filename.startsWith( "file:" ) )
+        {
+            return "file";
+        }
+        if ( filename.startsWith( "http:" ) )
+        {
+            return "http";
+        }
+        return "";
+    }
+
+
+    /**
+     * set the base directory.
+     * @param baseDir new value for the base directory
+     */
+    public void setBaseDir( String baseDir )
+    {
+        this.m_baseDir = baseDir;
+        if ( isRelative() && this.m_fullFilename != null )
+        {
+            this.m_valid = true;
+            if ( getProtocol().compareTo( "file" ) == 0 || getProtocol().compareTo( "" ) == 0 )
+            {
+                File f = new File( getOnlyAbsoluteFilename() );
+                m_file = f.isFile();
+                m_folder = f.isDirectory();
+                m_exist = f.exists();
+            }
+            if ( m_exist )
+            {
+                m_protocol = "file";
+            }
+        }
+
+    }
+
+
+    /**
+     * get the base directory.
+     * @return base directory
+     */
+    public String getBaseDir()
+    {
+        return this.m_baseDir;
+    }
+
+
+    public boolean isValid()
+    {
+        return m_valid;
+    }
+
+
+    public boolean isRelative()
+    {
+        return m_relative;
+    }
+
+
+    public boolean isExists()
+    {
+        return m_exist;
+    }
+
+
+    public boolean isFile()
+    {
+        return m_file;
+    }
+
+
+    public boolean isFolder()
+    {
+        return m_folder;
+    }
+
+
+    /**
+     * get a File which points on the same file.
+     * @return a File object
+     */
+    public File getFile()
+    {
+        if ( !this.isValid() )
+        {
+            return null;
+        }
+        String path = PathFile.uniformSeparator( this.getOnlyAbsoluteFilename() );
+        if ( File.separatorChar == '\\' )
+        {
+            path = path.replace( '\\', '/' );
+        }
+        File f = new File( path );
+        return f;
+    }
+
+
+    /**
+     * get an URI which points on the same file.
+     * @return an URI object
+     */
+    public URI getUri()
+    {
+        if ( !this.isValid() )
+        {
+            return null;
+        }
+        String path = PathFile.uniformSeparator( getAbsoluteFilename() );
+        if ( File.separatorChar == '\\' )
+        {
+            path = path.replace( '\\', '/' );
+        }
+
+        path = path.replaceAll( " ", "%20" );
+
+        URI uri = null;
+        try
+        {
+            uri = new URI( path );
+        }
+        catch ( URISyntaxException e )
+        {
+            System.err.println( "Malformed URI: " + path );
+            System.err.println( e.getMessage() );
+            return null;
+        }
+        return uri;
+    }
+
+
+    /**
+     * get protocol + relative path of this file.
+     * @return the relative path or null if it is not valid
+     */
+    public String getRelativePath()
+    {
+        if ( !this.isValid() )
+        {
+            return null;
+        }
+
+        return getProtocol() + ":/" + getOnlyRelativePath();
+    }
+
+
+    /**
+     * get only (without protocol) relative path of this file.
+     * @return the relative path or null if it is not valid
+     */
+    public String getOnlyRelativePath()
+    {
+        if ( !this.isValid() )
+        {
+            return null;
+        }
+        if ( this.isRelative() )
+        {
+            return m_pathFile;
+
+        }
+        else
+        {
+            if ( m_baseDir != null )
+            {
+                // System.err.println(m_pathFile);
+                // System.err.println(m_baseDir);
+                if ( m_pathFile.startsWith( m_baseDir ) )
+                {
+                    /*
+                     * String ch1 = m_pathFile; String ch2 = m_baseDir; System.err.println(ch1); System.err.println(ch2); System.err.println("."+File.separator+ch1.substring(ch2.length()));
+                     */
+                    return "." + File.separator + m_pathFile.substring( m_baseDir.length() );
+                }
+            }
+            return m_pathFile;
+        }
+    }
+
+
+    /**
+     * calcul absolute path from relative path.
+     * @param baseDir base directory
+     * @param path path to convert
+     * @return the absolute path or null
+     */
+    private String calculAbsolutePath( String baseDir, String path )
+    {
+        if ( path.startsWith( ".." + File.separatorChar ) )
+        {
+            String base = baseDir;
+            int lastIndex;
+            lastIndex = base.lastIndexOf( File.separator );
+            if ( lastIndex == base.length() )
+            {
+                base = base.substring( 0, base.length() - 1 );
+                lastIndex = base.lastIndexOf( File.separator );
+            }
+            if ( lastIndex < base.length() )
+            {
+                return calculAbsolutePath( base.substring( 0, lastIndex + 1 ), path.substring( 3 ) );
+            }
+            else
+            {
+                return null;
+            }
+        }
+        else if ( path.startsWith( "." + File.separatorChar ) )
+        {
+            String res;
+            if ( File.separatorChar == '\\' )
+            {
+                res = path.replaceFirst( ".", baseDir.replace( '\\', '/' ) );
+            }
+            else
+            {
+                res = path.replaceFirst( ".", baseDir );
+            }
+
+            return PathFile.uniformSeparator( res );
+        }
+        else
+        {
+            return PathFile.uniformSeparator( baseDir + path );
+        }
+    }
+
+
+    /**
+     * get only (without protocol) absolute path (without filename).
+     * @return absolute path
+     */
+    public String getOnlyAbsolutePath()
+    {
+        if ( !this.isValid() )
+        {
+            return null;
+        }
+        if ( isRelative() )
+        {
+            return calculAbsolutePath( m_baseDir, m_pathFile );
+        }
+        else
+        {
+            return m_pathFile;
+        }
+    }
+
+
+    /**
+     * get protocol + absolute path (without filename).
+     * @return absolute path
+     */
+    public String getAbsolutePath()
+    {
+
+        if ( isRelative() )
+        {
+            return getProtocol() + ":/" + calculAbsolutePath( m_baseDir, m_pathFile );
+        }
+        else
+        {
+            if ( getProtocol().compareTo( "" ) == 0 || m_pathFile == null )
+            {
+                return m_pathFile;
+            }
+            else
+            {
+                return getProtocol() + ":" + m_pathFile;
+            }
+        }
+    }
+
+
+    /**
+     * get only (without protocol) absolute path + filename.
+     * @return absolute filename
+     */
+    public String getOnlyAbsoluteFilename()
+    {
+        if ( getOnlyAbsolutePath() != null && getFilename() != null )
+        {
+            return getOnlyAbsolutePath() + getFilename();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * get protocol + absolute path + filename.
+     * @return absolute filenama
+     */
+    public String getAbsoluteFilename()
+    {
+        if ( getAbsolutePath() != null && getFilename() != null )
+        {
+            return getAbsolutePath() + getFilename();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * get only (without protocol) relative path + filename.
+     * @return relative filename
+     */
+    public String getOnlyRelativeFilename()
+    {
+        if ( !this.isValid() )
+        {
+            return "";
+        }
+
+        return getOnlyRelativePath() + getFilename();
+
+    }
+
+
+    /**
+     * get protocol + relative path + filename.
+     * @return relative filename
+     */
+    public String getRelativeFilename()
+    {
+        if ( !this.isValid() )
+        {
+            return "";
+        }
+
+        if ( this.isRelative() )
+        {
+            return getRelativePath() + getFilename();
+        }
+        else
+        {
+            return getAbsoluteFilename();
+        }
+    }
+
+
+    public String getFilename()
+    {
+        return m_fileName;
+    }
+
+
+    public String getProtocol()
+    {
+        return m_protocol;
+    }
+
+
+    /**
+     * create all the directories not also present in the current path.
+     * @return true if all directories was created, else false
+     */
+    public boolean createPath()
+    {
+        File path = new File( this.getOnlyAbsolutePath() );
+        if ( path.exists() )
+        {
+            return true;
+        }
+        return path.mkdirs();
+    }
+
+
+    /**
+     * create all the directories not also present in the current path and the file.
+     * @return true it was created, else false
+     */
+    public boolean createFile()
+    {
+        File path = new File( this.getOnlyAbsolutePath() );
+        if ( !path.exists() )
+        {
+            if ( !this.createPath() )
+            {
+                return false;
+            }
+        }
+        path = new File( this.getOnlyAbsoluteFilename() );
+        try
+        {
+            return path.createNewFile();
+        }
+        catch ( IOException e )
+        {
+            return false;
+        }
+
+    }
+
+
+    /**
+     * delete the current file.
+     * @return true if it was deleted, else false
+     */
+    public boolean delete()
+    {
+        File path = new File( this.getAbsoluteFilename() );
+        if ( path.exists() )
+        {
+            return path.delete();
+        }
+        else
+        {
+            return true;
+        }
+
+    }
+
+    private static final String REGEXP_BACKSLASH = "\\\\";
+
+
+    /**
+     * replace all '\' by '\\' in the given string.
+     * @param path string where replace the search pattern
+     * @return string replaced
+     */
+    public static String doubleSeparator( String path )
+    {
+        // double the '\' in the path
+        if ( path != null && File.separatorChar == '\\' )
+        {
+            return path.replaceAll( REGEXP_BACKSLASH, REGEXP_BACKSLASH + REGEXP_BACKSLASH );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * file separator('\' or '/') by the one of the current system.
+     * @param path string where replace the search pattern
+     * @return string replaced
+     */
+    public static String uniformSeparator( String path )
+    {
+        if ( File.separatorChar == '\\' )
+        {
+            if ( path.startsWith( "/" ) )
+            {
+                return path.substring( 1 ).replace( '/', File.separatorChar );
+            }
+            else
+            {
+                return path.replace( '/', File.separatorChar );
+            }
+        }
+        else
+        {
+            return path.replace( '\\', File.separatorChar );
+        }
+    }
+
+
+    /**
+     * copy file from src to dest.
+     * @param src source file
+     * @param dest destination file
+     * @return true if the file was correctly copied, else false
+     */
+    public static boolean copyFile( PathFile src, PathFile dest )
+    {
+        FileChannel in = null;
+        FileChannel out = null;
+
+        if ( !src.isExists() )
+        {
+            System.err.println( "src file must exist: " + src.getAbsoluteFilename() );
+            return false;
+        }
+        if ( !dest.isExists() )
+        {
+            dest.createFile();
+        }
+        try
+        {
+            in = new FileInputStream( src.getOnlyAbsoluteFilename() ).getChannel();
+            out = new FileOutputStream( dest.getOnlyAbsoluteFilename() ).getChannel();
+
+            in.transferTo( 0, in.size(), out );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+        finally
+        {
+            if ( in != null )
+            {
+                try
+                {
+                    in.close();
+                }
+                catch ( IOException e )
+                {
+                    return false;
+                }
+            }
+            if ( out != null )
+            {
+                try
+                {
+                    out.close();
+                }
+                catch ( IOException e )
+                {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java
index 8c503c1..44702bd 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/RemoteFileManager.java
@@ -1,280 +1,280 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.maven.artifact.manager.WagonConfigurationException;
-import org.apache.maven.artifact.manager.WagonManager;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.settings.Proxy;
-import org.apache.maven.settings.Settings;
-import org.apache.maven.wagon.ConnectionException;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.TransferFailedException;
-import org.apache.maven.wagon.UnsupportedProtocolException;
-import org.apache.maven.wagon.Wagon;
-import org.apache.maven.wagon.authentication.AuthenticationException;
-import org.apache.maven.wagon.authorization.AuthorizationException;
-import org.apache.maven.wagon.observers.Debug;
-import org.apache.maven.wagon.proxy.ProxyInfo;
-import org.apache.maven.wagon.repository.Repository;
-
-
-/**
- * this class is used to manage all connections by wagon.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class RemoteFileManager
-{
-
-    /**
-     * save the connection.
-     */
-    private Wagon m_wagon;
-
-    /**
-     * the wagon manager.
-     */
-    private WagonManager m_wagonManager;
-
-    /**
-     * artifact repository.
-     */
-    private ArtifactRepository m_artifactRepository;
-
-    /**
-     * the project settings.
-     */
-    private Settings m_settings;
-
-    /**
-     * logger instance.
-     */
-    private Log m_log;
-
-
-    /**
-     * initialize main information.
-     * @param ar ArtifactRepository provides by maven
-     * @param wm WagonManager provides by maven
-     * @param settings settings of the current project provides by maven
-     * @param log logger
-     */
-    public RemoteFileManager( ArtifactRepository ar, WagonManager wm, Settings settings, Log log )
-    {
-        m_artifactRepository = ar;
-        m_wagonManager = wm;
-        m_settings = settings;
-        m_log = log;
-        m_wagon = null;
-    }
-
-
-    /**
-     * disconnect the current object.
-     *
-     */
-    public void disconnect()
-    {
-        if ( m_wagon == null )
-        {
-            m_log.error( "must be connected first!" );
-            return;
-        }
-        try
-        {
-            m_wagon.disconnect();
-        }
-        catch ( ConnectionException e )
-        {
-            m_log.error( "Error disconnecting wagon - ignored", e );
-        }
-    }
-
-
-    /**
-     * connect the current object to artifact repository given in constructor.
-     * @throws MojoExecutionException if connection failed
-     */
-    public void connect() throws MojoExecutionException
-    {
-        String url = m_artifactRepository.getUrl();
-        String id = m_artifactRepository.getId();
-
-        Repository repository = new Repository( id, url );
-
-        try
-        {
-            m_wagon = m_wagonManager.getWagon( repository );
-            //configureWagon(m_wagon, repository.getId());
-        }
-        catch ( UnsupportedProtocolException e )
-        {
-            throw new MojoExecutionException( "Unsupported protocol: '" + repository.getProtocol() + "'", e );
-        }
-        catch ( WagonConfigurationException e )
-        {
-            throw new MojoExecutionException( "Unable to configure Wagon: '" + repository.getProtocol() + "'", e );
-        }
-
-        try
-        {
-            Debug debug = new Debug();
-            m_wagon.addTransferListener( debug );
-
-            ProxyInfo proxyInfo = getProxyInfo( m_settings );
-            if ( proxyInfo != null )
-            {
-                m_wagon.connect( repository, m_wagonManager.getAuthenticationInfo( id ), proxyInfo );
-            }
-            else
-            {
-                m_wagon.connect( repository, m_wagonManager.getAuthenticationInfo( id ) );
-            }
-
-        }
-        catch ( ConnectionException e )
-        {
-            throw new MojoExecutionException( "Error uploading file", e );
-        }
-        catch ( AuthenticationException e )
-        {
-            throw new MojoExecutionException( "Error uploading file", e );
-        }
-    }
-
-
-    /**
-     * get a file from the current repository connected.
-     * @param url url to the targeted file
-     * @return  get a file descriptor on the requiered resource
-     * @throws IOException if an IO error occurs
-     * @throws TransferFailedException  if the transfer failed 
-     * @throws ResourceDoesNotExistException if the targeted resource doesn't exist
-     * @throws AuthorizationException if the connection authorization failed
-     */
-    public File get( String url ) throws IOException, TransferFailedException, ResourceDoesNotExistException,
-        AuthorizationException
-    {
-
-        if ( m_wagon == null )
-        {
-            m_log.error( "must be connected first!" );
-            return null;
-        }
-
-        File file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), "tmp" );
-        m_wagon.get( url, file );
-        return file;
-    }
-
-
-    /**
-     * put a file on the current repository connected.
-     * @param file file to upload
-     * @param url url to copy file
-     * @throws TransferFailedException if the transfer failed 
-     * @throws ResourceDoesNotExistException if the targeted resource doesn't exist
-     * @throws AuthorizationException if the connection authorization failed
-     */
-    public void put( File file, String url ) throws TransferFailedException, ResourceDoesNotExistException,
-        AuthorizationException
-    {
-        if ( m_wagon == null )
-        {
-            m_log.error( "must be connected first!" );
-            return;
-        }
-        m_wagon.put( file, url );
-    }
-
-
-    /**
-     * Convenience method to map a Proxy object from the user system settings to a ProxyInfo object.
-     * @param settings project settings given by maven
-     * @return a proxyInfo object instancied or null if no active proxy is define in the settings.xml
-     */
-    public static ProxyInfo getProxyInfo( Settings settings )
-    {
-        ProxyInfo proxyInfo = null;
-        if ( settings != null && settings.getActiveProxy() != null )
-        {
-            Proxy settingsProxy = settings.getActiveProxy();
-
-            proxyInfo = new ProxyInfo();
-            proxyInfo.setHost( settingsProxy.getHost() );
-            proxyInfo.setType( settingsProxy.getProtocol() );
-            proxyInfo.setPort( settingsProxy.getPort() );
-            proxyInfo.setNonProxyHosts( settingsProxy.getNonProxyHosts() );
-            proxyInfo.setUserName( settingsProxy.getUsername() );
-            proxyInfo.setPassword( settingsProxy.getPassword() );
-        }
-
-        return proxyInfo;
-    }
-
-
-    /**
-     * this method indicates if the targeted file is locked or not.
-     * @param remote connection manager
-     * @param fileName name targeted
-     * @return  true if thr reuiered file is locked, else false
-     * @throws MojoFailureException if the plugin failed
-     */
-    public boolean isLockedFile( RemoteFileManager remote, String fileName ) throws MojoFailureException
-    {
-        File file = null;
-        try
-        {
-            file = remote.get( fileName + ".lock" );
-        }
-        catch ( TransferFailedException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "TransferFailedException" );
-
-        }
-        catch ( ResourceDoesNotExistException e )
-        {
-            return false;
-        }
-        catch ( AuthorizationException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "AuthorizationException" );
-        }
-        catch ( IOException e )
-        {
-            e.printStackTrace();
-            throw new MojoFailureException( "IOException" );
-        }
-        if ( file != null && file.length() == 0 )
-        {
-            return false;
-        }
-        return true;
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.artifact.manager.WagonConfigurationException;
+import org.apache.maven.artifact.manager.WagonManager;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.wagon.ConnectionException;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.UnsupportedProtocolException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.observers.Debug;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.apache.maven.wagon.repository.Repository;
+
+
+/**
+ * this class is used to manage all connections by wagon.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class RemoteFileManager
+{
+
+    /**
+     * save the connection.
+     */
+    private Wagon m_wagon;
+
+    /**
+     * the wagon manager.
+     */
+    private WagonManager m_wagonManager;
+
+    /**
+     * artifact repository.
+     */
+    private ArtifactRepository m_artifactRepository;
+
+    /**
+     * the project settings.
+     */
+    private Settings m_settings;
+
+    /**
+     * logger instance.
+     */
+    private Log m_log;
+
+
+    /**
+     * initialize main information.
+     * @param ar ArtifactRepository provides by maven
+     * @param wm WagonManager provides by maven
+     * @param settings settings of the current project provides by maven
+     * @param log logger
+     */
+    public RemoteFileManager( ArtifactRepository ar, WagonManager wm, Settings settings, Log log )
+    {
+        m_artifactRepository = ar;
+        m_wagonManager = wm;
+        m_settings = settings;
+        m_log = log;
+        m_wagon = null;
+    }
+
+
+    /**
+     * disconnect the current object.
+     *
+     */
+    public void disconnect()
+    {
+        if ( m_wagon == null )
+        {
+            m_log.error( "must be connected first!" );
+            return;
+        }
+        try
+        {
+            m_wagon.disconnect();
+        }
+        catch ( ConnectionException e )
+        {
+            m_log.error( "Error disconnecting wagon - ignored", e );
+        }
+    }
+
+
+    /**
+     * connect the current object to artifact repository given in constructor.
+     * @throws MojoExecutionException if connection failed
+     */
+    public void connect() throws MojoExecutionException
+    {
+        String url = m_artifactRepository.getUrl();
+        String id = m_artifactRepository.getId();
+
+        Repository repository = new Repository( id, url );
+
+        try
+        {
+            m_wagon = m_wagonManager.getWagon( repository );
+            //configureWagon(m_wagon, repository.getId());
+        }
+        catch ( UnsupportedProtocolException e )
+        {
+            throw new MojoExecutionException( "Unsupported protocol: '" + repository.getProtocol() + "'", e );
+        }
+        catch ( WagonConfigurationException e )
+        {
+            throw new MojoExecutionException( "Unable to configure Wagon: '" + repository.getProtocol() + "'", e );
+        }
+
+        try
+        {
+            Debug debug = new Debug();
+            m_wagon.addTransferListener( debug );
+
+            ProxyInfo proxyInfo = getProxyInfo( m_settings );
+            if ( proxyInfo != null )
+            {
+                m_wagon.connect( repository, m_wagonManager.getAuthenticationInfo( id ), proxyInfo );
+            }
+            else
+            {
+                m_wagon.connect( repository, m_wagonManager.getAuthenticationInfo( id ) );
+            }
+
+        }
+        catch ( ConnectionException e )
+        {
+            throw new MojoExecutionException( "Error uploading file", e );
+        }
+        catch ( AuthenticationException e )
+        {
+            throw new MojoExecutionException( "Error uploading file", e );
+        }
+    }
+
+
+    /**
+     * get a file from the current repository connected.
+     * @param url url to the targeted file
+     * @return  get a file descriptor on the requiered resource
+     * @throws IOException if an IO error occurs
+     * @throws TransferFailedException  if the transfer failed 
+     * @throws ResourceDoesNotExistException if the targeted resource doesn't exist
+     * @throws AuthorizationException if the connection authorization failed
+     */
+    public File get( String url ) throws IOException, TransferFailedException, ResourceDoesNotExistException,
+        AuthorizationException
+    {
+
+        if ( m_wagon == null )
+        {
+            m_log.error( "must be connected first!" );
+            return null;
+        }
+
+        File file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), "tmp" );
+        m_wagon.get( url, file );
+        return file;
+    }
+
+
+    /**
+     * put a file on the current repository connected.
+     * @param file file to upload
+     * @param url url to copy file
+     * @throws TransferFailedException if the transfer failed 
+     * @throws ResourceDoesNotExistException if the targeted resource doesn't exist
+     * @throws AuthorizationException if the connection authorization failed
+     */
+    public void put( File file, String url ) throws TransferFailedException, ResourceDoesNotExistException,
+        AuthorizationException
+    {
+        if ( m_wagon == null )
+        {
+            m_log.error( "must be connected first!" );
+            return;
+        }
+        m_wagon.put( file, url );
+    }
+
+
+    /**
+     * Convenience method to map a Proxy object from the user system settings to a ProxyInfo object.
+     * @param settings project settings given by maven
+     * @return a proxyInfo object instancied or null if no active proxy is define in the settings.xml
+     */
+    public static ProxyInfo getProxyInfo( Settings settings )
+    {
+        ProxyInfo proxyInfo = null;
+        if ( settings != null && settings.getActiveProxy() != null )
+        {
+            Proxy settingsProxy = settings.getActiveProxy();
+
+            proxyInfo = new ProxyInfo();
+            proxyInfo.setHost( settingsProxy.getHost() );
+            proxyInfo.setType( settingsProxy.getProtocol() );
+            proxyInfo.setPort( settingsProxy.getPort() );
+            proxyInfo.setNonProxyHosts( settingsProxy.getNonProxyHosts() );
+            proxyInfo.setUserName( settingsProxy.getUsername() );
+            proxyInfo.setPassword( settingsProxy.getPassword() );
+        }
+
+        return proxyInfo;
+    }
+
+
+    /**
+     * this method indicates if the targeted file is locked or not.
+     * @param remote connection manager
+     * @param fileName name targeted
+     * @return  true if thr reuiered file is locked, else false
+     * @throws MojoFailureException if the plugin failed
+     */
+    public boolean isLockedFile( RemoteFileManager remote, String fileName ) throws MojoFailureException
+    {
+        File file = null;
+        try
+        {
+            file = remote.get( fileName + ".lock" );
+        }
+        catch ( TransferFailedException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "TransferFailedException" );
+
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            return false;
+        }
+        catch ( AuthorizationException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "AuthorizationException" );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            throw new MojoFailureException( "IOException" );
+        }
+        if ( file != null && file.length() == 0 )
+        {
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Require.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Require.java
index 76162fc..fdc104b 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Require.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/Require.java
@@ -1,204 +1,204 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-
-/**
- * this class store a Require tag.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class Require
-{
-
-    /**
-     * store the extend attribute.
-     */
-    private String m_extend;
-
-    /**
-     * store the multiple attribute.
-     */
-    private String m_multiple;
-
-    /**
-     * store the optional attribute.
-     */
-    private String m_optional;
-
-    /**
-     * store the name attribute.
-     */
-    private String m_name;
-
-    /**
-     * store the filter attribute.
-     */
-    private String m_filter;
-
-    /**
-     * store the value of the tag.
-     */
-    private String m_value;
-
-
-    /**
-     * get the extend attribute.
-     * @return a string which contains the value of the boolean
-     */
-    public String getExtend()
-    {
-        return m_extend;
-    }
-
-
-    /**
-     * set the extend attribute.
-     * @param extend new value for the extend attribute
-     */
-    public void setExtend( String extend )
-    {
-        this.m_extend = extend;
-    }
-
-
-    /**
-     * get the filter attribute.
-     * @return m_filter value
-     */
-    public String getFilter()
-    {
-        return m_filter;
-    }
-
-
-    /**
-     * set the filter attribute.
-     * @param filter new value for filter
-     */
-    public void setFilter( String filter )
-    {
-        this.m_filter = filter;
-    }
-
-
-    /**
-     * get multiple attribute.
-     * @return m_multiple value
-     */
-    public String getMultiple()
-    {
-        return m_multiple;
-    }
-
-
-    /**
-     * set multiple attribute.
-     * @param multiple new value for m_multiple
-     */
-    public void setMultiple( String multiple )
-    {
-        this.m_multiple = multiple;
-    }
-
-
-    /**
-     * get name attribute.
-     * @return m_name value
-     */
-    public String getName()
-    {
-        return m_name;
-    }
-
-
-    /**
-     * set name attribute.
-     * @param name new value for m_name
-     */
-    public void setName( String name )
-    {
-        this.m_name = name;
-    }
-
-
-    /**
-     * get the optional attribute.
-     * @return m_optional value
-     */
-    public String getOptional()
-    {
-        return m_optional;
-    }
-
-
-    /**
-     * set the optional attribute.
-     * @param optionnal new value for m_optional
-     */
-    public void setOptional( String optionnal )
-    {
-        this.m_optional = optionnal;
-    }
-
-
-    /**
-     * get value of the tag.
-     * @return value of this tag
-     */
-    public String getValue()
-    {
-        return m_value;
-    }
-
-
-    /**
-     * set the value of the tag.
-     * @param value new value for this tag
-     */
-    public void setValue( String value )
-    {
-        this.m_value = value;
-    }
-
-
-    /**
-     * transform this object to Node.
-     * 
-     * @param father father document for create Node
-     * @return node
-     */
-    public Node getNode( Document father )
-    {
-        Element require = father.createElement( "require" );
-        require.setAttribute( "name", this.getName() );
-        require.setAttribute( "filter", this.getFilter() );
-        require.setAttribute( "extend", this.getExtend() );
-        require.setAttribute( "multiple", this.getMultiple() );
-        require.setAttribute( "optional", this.getOptional() );
-        XmlHelper.setTextContent( require, this.getValue() );
-
-        return require;
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * this class store a Require tag.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Require
+{
+
+    /**
+     * store the extend attribute.
+     */
+    private String m_extend;
+
+    /**
+     * store the multiple attribute.
+     */
+    private String m_multiple;
+
+    /**
+     * store the optional attribute.
+     */
+    private String m_optional;
+
+    /**
+     * store the name attribute.
+     */
+    private String m_name;
+
+    /**
+     * store the filter attribute.
+     */
+    private String m_filter;
+
+    /**
+     * store the value of the tag.
+     */
+    private String m_value;
+
+
+    /**
+     * get the extend attribute.
+     * @return a string which contains the value of the boolean
+     */
+    public String getExtend()
+    {
+        return m_extend;
+    }
+
+
+    /**
+     * set the extend attribute.
+     * @param extend new value for the extend attribute
+     */
+    public void setExtend( String extend )
+    {
+        this.m_extend = extend;
+    }
+
+
+    /**
+     * get the filter attribute.
+     * @return m_filter value
+     */
+    public String getFilter()
+    {
+        return m_filter;
+    }
+
+
+    /**
+     * set the filter attribute.
+     * @param filter new value for filter
+     */
+    public void setFilter( String filter )
+    {
+        this.m_filter = filter;
+    }
+
+
+    /**
+     * get multiple attribute.
+     * @return m_multiple value
+     */
+    public String getMultiple()
+    {
+        return m_multiple;
+    }
+
+
+    /**
+     * set multiple attribute.
+     * @param multiple new value for m_multiple
+     */
+    public void setMultiple( String multiple )
+    {
+        this.m_multiple = multiple;
+    }
+
+
+    /**
+     * get name attribute.
+     * @return m_name value
+     */
+    public String getName()
+    {
+        return m_name;
+    }
+
+
+    /**
+     * set name attribute.
+     * @param name new value for m_name
+     */
+    public void setName( String name )
+    {
+        this.m_name = name;
+    }
+
+
+    /**
+     * get the optional attribute.
+     * @return m_optional value
+     */
+    public String getOptional()
+    {
+        return m_optional;
+    }
+
+
+    /**
+     * set the optional attribute.
+     * @param optionnal new value for m_optional
+     */
+    public void setOptional( String optionnal )
+    {
+        this.m_optional = optionnal;
+    }
+
+
+    /**
+     * get value of the tag.
+     * @return value of this tag
+     */
+    public String getValue()
+    {
+        return m_value;
+    }
+
+
+    /**
+     * set the value of the tag.
+     * @param value new value for this tag
+     */
+    public void setValue( String value )
+    {
+        this.m_value = value;
+    }
+
+
+    /**
+     * transform this object to Node.
+     * 
+     * @param father father document for create Node
+     * @return node
+     */
+    public Node getNode( Document father )
+    {
+        Element require = father.createElement( "require" );
+        require.setAttribute( "name", this.getName() );
+        require.setAttribute( "filter", this.getFilter() );
+        require.setAttribute( "extend", this.getExtend() );
+        require.setAttribute( "multiple", this.getMultiple() );
+        require.setAttribute( "optional", this.getOptional() );
+        XmlHelper.setTextContent( require, this.getValue() );
+
+        return require;
+    }
+
+}
diff --git a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ResourcesBundle.java b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ResourcesBundle.java
index 0c3fb45..a1e996d 100644
--- a/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ResourcesBundle.java
+++ b/maven-obr-plugin/src/main/java/org/apache/felix/obr/plugin/ResourcesBundle.java
@@ -1,678 +1,678 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.felix.obr.plugin;
-
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-
-/**
- * this class describe all information by bundle.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ResourcesBundle
-{
-    /**
-     * store the bundle symbolic name.
-     */
-    private String m_symbolicName;
-
-    /**
-     * store the bundle presentation name.
-     */
-    private String m_presentationName;
-
-    /**
-     * store the bundle version.
-     */
-    private String m_version;
-
-    /**
-     * store the bundle URI.
-     */
-    private String m_uri;
-
-    /**
-     * store the bundle description.
-     */
-    private String m_description;
-
-    /**
-     * store the bundle size.
-     */
-    private String m_size;
-
-    /**
-     * store the bundle documentation.
-     */
-    private String m_documentation;
-
-    /**
-     * store the bundle source.
-     */
-    private String m_source;
-
-    /**
-     * store the bundle license.
-     */
-    private String m_license;
-
-    /**
-     * store the bundle id.
-     */
-    private String m_id;
-
-    /**
-     * store the bundle categories.
-     */
-    private List m_category = new ArrayList();
-
-    /**
-     * store the bundle capabilities.
-     */
-    private List m_capability = new ArrayList();
-
-    /**
-     * store the bundle requirement.
-     */
-    private List m_require = new ArrayList();
-
-    /**
-     * get the plugin logger.
-     */
-    private Log m_logger;
-
-
-    /**
-     * initialize logger.
-     * @param log log use by plugin
-     */
-    public ResourcesBundle( Log log )
-    {
-        m_logger = log;
-    }
-
-
-    public List getCapability()
-    {
-        return m_capability;
-    }
-
-
-    public void setCapability( List capability )
-    {
-        this.m_capability = capability;
-    }
-
-
-    public List getCategory()
-    {
-        return m_category;
-    }
-
-
-    public void setCategory( List category )
-    {
-        this.m_category = category;
-    }
-
-
-    public String getLicense()
-    {
-        return m_license;
-    }
-
-
-    public void setLicense( String license )
-    {
-        this.m_license = license;
-    }
-
-
-    public String getDescription()
-    {
-        return m_description;
-    }
-
-
-    public void setDescription( String description )
-    {
-        this.m_description = description;
-    }
-
-
-    public String getDocumentation()
-    {
-        return m_documentation;
-    }
-
-
-    public void setDocumentation( String documentation )
-    {
-        this.m_documentation = documentation;
-    }
-
-
-    public String getPresentationName()
-    {
-        return m_presentationName;
-    }
-
-
-    public void setPresentationName( String name )
-    {
-        m_presentationName = name;
-    }
-
-
-    public String getSize()
-    {
-        return m_size;
-    }
-
-
-    public void setSize( String size )
-    {
-        this.m_size = size;
-    }
-
-
-    public String getSymbolicName()
-    {
-        return m_symbolicName;
-    }
-
-
-    public void setSymbolicName( String name )
-    {
-        m_symbolicName = name;
-    }
-
-
-    public String getUri()
-    {
-        return m_uri;
-    }
-
-
-    public void setUri( String url )
-    {
-        this.m_uri = url;
-    }
-
-
-    public String getVersion()
-    {
-        return m_version;
-    }
-
-
-    public void setVersion( String version )
-    {
-        this.m_version = version;
-    }
-
-
-    public List getRequire()
-    {
-        return m_require;
-    }
-
-
-    public void setRequire( List require )
-    {
-        this.m_require = require;
-    }
-
-
-    public String getSource()
-    {
-        return m_source;
-    }
-
-
-    public void setSource( String source )
-    {
-        this.m_source = source;
-    }
-
-
-    public String getId()
-    {
-        return m_id;
-    }
-
-
-    public void setId( String id )
-    {
-        this.m_id = id;
-    }
-
-
-    /**
-     * add a new capability for this bundle description.
-     * @param capability the Capability to add
-     */
-    public void addCapability( Capability capability )
-    {
-        m_capability.add( capability );
-    }
-
-
-    /**
-     * add a new requirement for this bundle description.
-     * @param require th Require to add
-     */
-    public void addRequire( Require require )
-    {
-        m_require.add( require );
-    }
-
-
-    /**
-     * add a new category for this bundle decription.
-     * @param category the Category to add
-     */
-    public void addCategory( Category category )
-    {
-        m_category.add( category );
-    }
-
-
-    /**
-     * transform this object to Node.
-     * tranform all sub-object to node also
-     * @param father father document for create Node
-     * @return node
-     */
-    public Node getNode( Document father )
-    {
-        // return the complete resource tree
-        if ( !this.isValid() || this.getId() == null )
-        {
-            m_logger.error( "those properties was not defined:" + this.getInvalidProperties() );
-            return null;
-        }
-
-        Element resource = father.createElement( "resource" );
-        Element description = father.createElement( "description" );
-        Element size = father.createElement( "size" );
-        Element documentation = father.createElement( "documentation" );
-        Element source = father.createElement( "source" );
-        Element license = father.createElement( "license" );
-
-        resource.setAttribute( "id", this.getId() );
-        resource.setAttribute( "symbolicname", this.getSymbolicName() );
-        resource.setAttribute( "presentationname", this.getPresentationName() );
-        resource.setAttribute( "uri", this.getUri() );
-        resource.setAttribute( "version", this.getVersion() );
-
-        XmlHelper.setTextContent( description, this.getDescription() );
-        resource.appendChild( description );
-
-        XmlHelper.setTextContent( size, this.getSize() );
-        resource.appendChild( size );
-
-        if ( this.getDocumentation() != null )
-        {
-            XmlHelper.setTextContent( documentation, this.getDocumentation() );
-            resource.appendChild( documentation );
-        }
-
-        if ( this.getSource() != null )
-        {
-            XmlHelper.setTextContent( source, this.getSource() );
-            resource.appendChild( source );
-        }
-
-        if ( this.getLicense() != null )
-        {
-            XmlHelper.setTextContent( license, this.getLicense() );
-            resource.appendChild( license );
-        }
-
-        List list = ( ArrayList ) this.getNodeCategories( father );
-        for ( int i = 0; i < list.size(); i++ )
-        {
-            resource.appendChild( ( Node ) list.get( i ) );
-        }
-
-        list = ( ArrayList ) this.getNodeCapabilities( father );
-        for ( int i = 0; i < list.size(); i++ )
-        {
-            resource.appendChild( ( Node ) list.get( i ) );
-        }
-
-        list = ( ArrayList ) this.getNodeRequirement( father );
-        for ( int i = 0; i < list.size(); i++ )
-        {
-            resource.appendChild( ( Node ) list.get( i ) );
-        }
-
-        return resource;
-    }
-
-
-    /**
-     * this method gets information form pom.xml to complete missing data from those given by user.
-     * @param project project information given by maven
-     * @param ebi bundle information extracted from bindex
-     * @return true
-     */
-    public boolean construct( MavenProject project, ExtractBindexInfo ebi )
-    {
-
-        if ( ebi.getPresentationName() != null )
-        {
-            this.setPresentationName( ebi.getPresentationName() );
-            if ( project.getName() != null )
-            {
-                m_logger.debug( "pom property override:<presentationname> " + project.getName() );
-            }
-        }
-        else
-        {
-            this.setPresentationName( project.getName() );
-        }
-
-        if ( ebi.getSymbolicName() != null )
-        {
-            this.setSymbolicName( ebi.getSymbolicName() );
-            if ( project.getArtifactId() != null )
-            {
-                m_logger.debug( "pom property override:<symbolicname> " + project.getArtifactId() );
-            }
-        }
-        else
-        {
-            this.setSymbolicName( project.getArtifactId() );
-        }
-
-        if ( ebi.getVersion() != null )
-        {
-            this.setVersion( ebi.getVersion() );
-            if ( project.getVersion() != null )
-            {
-                m_logger.debug( "pom property override:<version> " + project.getVersion() );
-            }
-        }
-        else
-        {
-            this.setVersion( project.getVersion() );
-        }
-
-        if ( ebi.getId() != null )
-        {
-            this.setId( ebi.getId() );
-        }
-
-        if ( ebi.getDescription() != null )
-        {
-            this.setDescription( ebi.getDescription() );
-            if ( project.getDescription() != null )
-            {
-                m_logger.debug( "pom property override:<description> " + project.getDescription() );
-            }
-        }
-        else
-        {
-            this.setDescription( project.getDescription() );
-        }
-
-        if ( ebi.getDocumentation() != null )
-        {
-            this.setDocumentation( ebi.getDocumentation() );
-            if ( project.getUrl() != null )
-            {
-                m_logger.debug( "pom property override:<documentation> " + project.getUrl() );
-            }
-        }
-        else
-        {
-            this.setDocumentation( project.getUrl() );
-        }
-
-        if ( ebi.getSource() != null )
-        {
-            this.setSource( ebi.getSource() );
-            if ( project.getScm() != null )
-            {
-                m_logger.debug( "pom property override:<source> " + project.getScm() );
-            }
-        }
-        else
-        {
-            String src = null;
-            if ( project.getScm() != null )
-            {
-                src = project.getScm().getUrl();
-            }
-            this.setSource( src );
-        }
-
-        if ( ebi.getLicense() != null )
-        {
-            this.setLicense( ebi.getLicense() );
-            String lic = null;
-            List l = project.getLicenses();
-            Iterator it = l.iterator();
-            while ( it.hasNext() )
-            {
-                if ( it.next() != null )
-                {
-                    m_logger.debug( "pom property override:<license> " + lic );
-                    break;
-                }
-            }
-        }
-        else
-        {
-            String lic = null;
-            List l = project.getLicenses();
-            Iterator it = l.iterator();
-            while ( it.hasNext() )
-            {
-                lic = it.next() + ";";
-            }
-
-            this.setLicense( lic );
-        }
-
-        // create the first capability (ie : bundle)
-        Capability capability = new Capability();
-        capability.setName( "bundle" );
-        PElement p = new PElement();
-        p.setN( "manifestversion" );
-        p.setV( "2" );
-        capability.addP( p );
-
-        p = new PElement();
-        p.setN( "presentationname" );
-        p.setV( this.getPresentationName() );
-        capability.addP( p );
-
-        p = new PElement();
-        p.setN( "symbolicname" );
-        p.setV( this.getSymbolicName() );
-        capability.addP( p );
-
-        p = new PElement();
-        p.setN( "version" );
-        p.setT( "version" );
-        p.setV( this.getVersion() );
-        capability.addP( p );
-
-        this.addCapability( capability );
-
-        List capabilities = ( ArrayList ) ebi.getCapabilities();
-        for ( int i = 0; i < capabilities.size(); i++ )
-        {
-            this.addCapability( ( Capability ) capabilities.get( i ) );
-        }
-
-        List requirement = ( ArrayList ) ebi.getRequirement();
-        for ( int i = 0; i < requirement.size(); i++ )
-        {
-            this.addRequire( ( Require ) requirement.get( i ) );
-        }
-
-        // we also add the goupId
-        Category category = new Category();
-        category.setId( project.getGroupId() );
-        this.addCategory( category );
-
-        return true;
-    }
-
-
-    /**
-     * return if the bundle resource is complete.
-     * @return false if an information is missing, else true
-     */
-    public boolean isValid()
-    {
-        // we must verify required properties are present
-        return this.getPresentationName() != null && this.getSymbolicName() != null && this.getVersion() != null
-            && this.getUri() != null && this.getSize() != null;
-    }
-
-
-    /**
-     * test if this bundle has the same symbolicname, and version number.
-     * @param symbolicName symbolicName to compare with current bundle
-     * @param presentationName presentationName to compare with current bundlde
-     * @param version version to compare with current bundle
-     * @return true if the information are the same, else false
-     */
-    public boolean isSameBundleResource( String symbolicName, String version )
-    {
-        if ( this.isValid() )
-        {
-            return ( symbolicName.compareTo( this.getSymbolicName() ) == 0 )
-                && ( version.compareTo( this.getVersion() ) == 0 );
-        }
-        else
-        {
-            return false;
-        }
-
-    }
-
-
-    /**
-     * return a list of categories transformed to node.
-     * @param father father document to create node from same document
-     * @return List of Node
-     */
-    private List getNodeCategories( Document father )
-    {
-        List listNode = new ArrayList();
-        List listCategory = ( ArrayList ) this.getCategory();
-        for ( int i = 0; i < listCategory.size(); i++ )
-        {
-            listNode.add( ( ( Category ) listCategory.get( i ) ).getNode( father ) );
-        }
-        return listNode;
-    }
-
-
-    /**
-     * return a list of capabilities transformed to node.
-     * @param father father document to create node from same document
-     * @return List of Node
-     */
-    private List getNodeCapabilities( Document father )
-    {
-        List listNode = new ArrayList();
-        List listCapability = ( ArrayList ) this.getCapability();
-        for ( int i = 0; i < listCapability.size(); i++ )
-        {
-            listNode.add( ( ( Capability ) listCapability.get( i ) ).getNode( father ) );
-        }
-        return listNode;
-    }
-
-
-    /**
-     * return a list of requirement transformed to node.
-     * @param father father document to create node from same document
-     * @return List of Node.
-     */
-    private List getNodeRequirement( Document father )
-    {
-        List listNode = new ArrayList();
-        List listRequirement = ( ArrayList ) this.getRequire();
-        for ( int i = 0; i < listRequirement.size(); i++ )
-        {
-            listNode.add( ( ( Require ) listRequirement.get( i ) ).getNode( father ) );
-        }
-        return listNode;
-    }
-
-
-    /**
-     * return the list of properties not define in this bundle resource.
-     * @return list of properties not define
-     */
-    private String getInvalidProperties()
-    {
-        if ( this.isValid() )
-        {
-            if ( this.getId() == null )
-            {
-                return "id";
-            }
-            else
-            {
-                return "";
-            }
-        }
-        String result = "";
-        if ( this.getPresentationName() == null )
-        {
-            result = result + "presentationName;";
-        }
-        if ( this.getSymbolicName() == null )
-        {
-            result = result + "symbolicName;";
-        }
-        if ( this.getVersion() == null )
-        {
-            result = result + "version;";
-        }
-        if ( this.getUri() == null )
-        {
-            result = result + "Uri;";
-        }
-        if ( this.getSize() == null )
-        {
-            result = result + "Size";
-        }
-        return result;
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.obr.plugin;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * this class describe all information by bundle.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourcesBundle
+{
+    /**
+     * store the bundle symbolic name.
+     */
+    private String m_symbolicName;
+
+    /**
+     * store the bundle presentation name.
+     */
+    private String m_presentationName;
+
+    /**
+     * store the bundle version.
+     */
+    private String m_version;
+
+    /**
+     * store the bundle URI.
+     */
+    private String m_uri;
+
+    /**
+     * store the bundle description.
+     */
+    private String m_description;
+
+    /**
+     * store the bundle size.
+     */
+    private String m_size;
+
+    /**
+     * store the bundle documentation.
+     */
+    private String m_documentation;
+
+    /**
+     * store the bundle source.
+     */
+    private String m_source;
+
+    /**
+     * store the bundle license.
+     */
+    private String m_license;
+
+    /**
+     * store the bundle id.
+     */
+    private String m_id;
+
+    /**
+     * store the bundle categories.
+     */
+    private List m_category = new ArrayList();
+
+    /**
+     * store the bundle capabilities.
+     */
+    private List m_capability = new ArrayList();
+
+    /**
+     * store the bundle requirement.
+     */
+    private List m_require = new ArrayList();
+
+    /**
+     * get the plugin logger.
+     */
+    private Log m_logger;
+
+
+    /**
+     * initialize logger.
+     * @param log log use by plugin
+     */
+    public ResourcesBundle( Log log )
+    {
+        m_logger = log;
+    }
+
+
+    public List getCapability()
+    {
+        return m_capability;
+    }
+
+
+    public void setCapability( List capability )
+    {
+        this.m_capability = capability;
+    }
+
+
+    public List getCategory()
+    {
+        return m_category;
+    }
+
+
+    public void setCategory( List category )
+    {
+        this.m_category = category;
+    }
+
+
+    public String getLicense()
+    {
+        return m_license;
+    }
+
+
+    public void setLicense( String license )
+    {
+        this.m_license = license;
+    }
+
+
+    public String getDescription()
+    {
+        return m_description;
+    }
+
+
+    public void setDescription( String description )
+    {
+        this.m_description = description;
+    }
+
+
+    public String getDocumentation()
+    {
+        return m_documentation;
+    }
+
+
+    public void setDocumentation( String documentation )
+    {
+        this.m_documentation = documentation;
+    }
+
+
+    public String getPresentationName()
+    {
+        return m_presentationName;
+    }
+
+
+    public void setPresentationName( String name )
+    {
+        m_presentationName = name;
+    }
+
+
+    public String getSize()
+    {
+        return m_size;
+    }
+
+
+    public void setSize( String size )
+    {
+        this.m_size = size;
+    }
+
+
+    public String getSymbolicName()
+    {
+        return m_symbolicName;
+    }
+
+
+    public void setSymbolicName( String name )
+    {
+        m_symbolicName = name;
+    }
+
+
+    public String getUri()
+    {
+        return m_uri;
+    }
+
+
+    public void setUri( String url )
+    {
+        this.m_uri = url;
+    }
+
+
+    public String getVersion()
+    {
+        return m_version;
+    }
+
+
+    public void setVersion( String version )
+    {
+        this.m_version = version;
+    }
+
+
+    public List getRequire()
+    {
+        return m_require;
+    }
+
+
+    public void setRequire( List require )
+    {
+        this.m_require = require;
+    }
+
+
+    public String getSource()
+    {
+        return m_source;
+    }
+
+
+    public void setSource( String source )
+    {
+        this.m_source = source;
+    }
+
+
+    public String getId()
+    {
+        return m_id;
+    }
+
+
+    public void setId( String id )
+    {
+        this.m_id = id;
+    }
+
+
+    /**
+     * add a new capability for this bundle description.
+     * @param capability the Capability to add
+     */
+    public void addCapability( Capability capability )
+    {
+        m_capability.add( capability );
+    }
+
+
+    /**
+     * add a new requirement for this bundle description.
+     * @param require th Require to add
+     */
+    public void addRequire( Require require )
+    {
+        m_require.add( require );
+    }
+
+
+    /**
+     * add a new category for this bundle decription.
+     * @param category the Category to add
+     */
+    public void addCategory( Category category )
+    {
+        m_category.add( category );
+    }
+
+
+    /**
+     * transform this object to Node.
+     * tranform all sub-object to node also
+     * @param father father document for create Node
+     * @return node
+     */
+    public Node getNode( Document father )
+    {
+        // return the complete resource tree
+        if ( !this.isValid() || this.getId() == null )
+        {
+            m_logger.error( "those properties was not defined:" + this.getInvalidProperties() );
+            return null;
+        }
+
+        Element resource = father.createElement( "resource" );
+        Element description = father.createElement( "description" );
+        Element size = father.createElement( "size" );
+        Element documentation = father.createElement( "documentation" );
+        Element source = father.createElement( "source" );
+        Element license = father.createElement( "license" );
+
+        resource.setAttribute( "id", this.getId() );
+        resource.setAttribute( "symbolicname", this.getSymbolicName() );
+        resource.setAttribute( "presentationname", this.getPresentationName() );
+        resource.setAttribute( "uri", this.getUri() );
+        resource.setAttribute( "version", this.getVersion() );
+
+        XmlHelper.setTextContent( description, this.getDescription() );
+        resource.appendChild( description );
+
+        XmlHelper.setTextContent( size, this.getSize() );
+        resource.appendChild( size );
+
+        if ( this.getDocumentation() != null )
+        {
+            XmlHelper.setTextContent( documentation, this.getDocumentation() );
+            resource.appendChild( documentation );
+        }
+
+        if ( this.getSource() != null )
+        {
+            XmlHelper.setTextContent( source, this.getSource() );
+            resource.appendChild( source );
+        }
+
+        if ( this.getLicense() != null )
+        {
+            XmlHelper.setTextContent( license, this.getLicense() );
+            resource.appendChild( license );
+        }
+
+        List list = ( ArrayList ) this.getNodeCategories( father );
+        for ( int i = 0; i < list.size(); i++ )
+        {
+            resource.appendChild( ( Node ) list.get( i ) );
+        }
+
+        list = ( ArrayList ) this.getNodeCapabilities( father );
+        for ( int i = 0; i < list.size(); i++ )
+        {
+            resource.appendChild( ( Node ) list.get( i ) );
+        }
+
+        list = ( ArrayList ) this.getNodeRequirement( father );
+        for ( int i = 0; i < list.size(); i++ )
+        {
+            resource.appendChild( ( Node ) list.get( i ) );
+        }
+
+        return resource;
+    }
+
+
+    /**
+     * this method gets information form pom.xml to complete missing data from those given by user.
+     * @param project project information given by maven
+     * @param ebi bundle information extracted from bindex
+     * @return true
+     */
+    public boolean construct( MavenProject project, ExtractBindexInfo ebi )
+    {
+
+        if ( ebi.getPresentationName() != null )
+        {
+            this.setPresentationName( ebi.getPresentationName() );
+            if ( project.getName() != null )
+            {
+                m_logger.debug( "pom property override:<presentationname> " + project.getName() );
+            }
+        }
+        else
+        {
+            this.setPresentationName( project.getName() );
+        }
+
+        if ( ebi.getSymbolicName() != null )
+        {
+            this.setSymbolicName( ebi.getSymbolicName() );
+            if ( project.getArtifactId() != null )
+            {
+                m_logger.debug( "pom property override:<symbolicname> " + project.getArtifactId() );
+            }
+        }
+        else
+        {
+            this.setSymbolicName( project.getArtifactId() );
+        }
+
+        if ( ebi.getVersion() != null )
+        {
+            this.setVersion( ebi.getVersion() );
+            if ( project.getVersion() != null )
+            {
+                m_logger.debug( "pom property override:<version> " + project.getVersion() );
+            }
+        }
+        else
+        {
+            this.setVersion( project.getVersion() );
+        }
+
+        if ( ebi.getId() != null )
+        {
+            this.setId( ebi.getId() );
+        }
+
+        if ( ebi.getDescription() != null )
+        {
+            this.setDescription( ebi.getDescription() );
+            if ( project.getDescription() != null )
+            {
+                m_logger.debug( "pom property override:<description> " + project.getDescription() );
+            }
+        }
+        else
+        {
+            this.setDescription( project.getDescription() );
+        }
+
+        if ( ebi.getDocumentation() != null )
+        {
+            this.setDocumentation( ebi.getDocumentation() );
+            if ( project.getUrl() != null )
+            {
+                m_logger.debug( "pom property override:<documentation> " + project.getUrl() );
+            }
+        }
+        else
+        {
+            this.setDocumentation( project.getUrl() );
+        }
+
+        if ( ebi.getSource() != null )
+        {
+            this.setSource( ebi.getSource() );
+            if ( project.getScm() != null )
+            {
+                m_logger.debug( "pom property override:<source> " + project.getScm() );
+            }
+        }
+        else
+        {
+            String src = null;
+            if ( project.getScm() != null )
+            {
+                src = project.getScm().getUrl();
+            }
+            this.setSource( src );
+        }
+
+        if ( ebi.getLicense() != null )
+        {
+            this.setLicense( ebi.getLicense() );
+            String lic = null;
+            List l = project.getLicenses();
+            Iterator it = l.iterator();
+            while ( it.hasNext() )
+            {
+                if ( it.next() != null )
+                {
+                    m_logger.debug( "pom property override:<license> " + lic );
+                    break;
+                }
+            }
+        }
+        else
+        {
+            String lic = null;
+            List l = project.getLicenses();
+            Iterator it = l.iterator();
+            while ( it.hasNext() )
+            {
+                lic = it.next() + ";";
+            }
+
+            this.setLicense( lic );
+        }
+
+        // create the first capability (ie : bundle)
+        Capability capability = new Capability();
+        capability.setName( "bundle" );
+        PElement p = new PElement();
+        p.setN( "manifestversion" );
+        p.setV( "2" );
+        capability.addP( p );
+
+        p = new PElement();
+        p.setN( "presentationname" );
+        p.setV( this.getPresentationName() );
+        capability.addP( p );
+
+        p = new PElement();
+        p.setN( "symbolicname" );
+        p.setV( this.getSymbolicName() );
+        capability.addP( p );
+
+        p = new PElement();
+        p.setN( "version" );
+        p.setT( "version" );
+        p.setV( this.getVersion() );
+        capability.addP( p );
+
+        this.addCapability( capability );
+
+        List capabilities = ( ArrayList ) ebi.getCapabilities();
+        for ( int i = 0; i < capabilities.size(); i++ )
+        {
+            this.addCapability( ( Capability ) capabilities.get( i ) );
+        }
+
+        List requirement = ( ArrayList ) ebi.getRequirement();
+        for ( int i = 0; i < requirement.size(); i++ )
+        {
+            this.addRequire( ( Require ) requirement.get( i ) );
+        }
+
+        // we also add the goupId
+        Category category = new Category();
+        category.setId( project.getGroupId() );
+        this.addCategory( category );
+
+        return true;
+    }
+
+
+    /**
+     * return if the bundle resource is complete.
+     * @return false if an information is missing, else true
+     */
+    public boolean isValid()
+    {
+        // we must verify required properties are present
+        return this.getPresentationName() != null && this.getSymbolicName() != null && this.getVersion() != null
+            && this.getUri() != null && this.getSize() != null;
+    }
+
+
+    /**
+     * test if this bundle has the same symbolicname, and version number.
+     * @param symbolicName symbolicName to compare with current bundle
+     * @param presentationName presentationName to compare with current bundlde
+     * @param version version to compare with current bundle
+     * @return true if the information are the same, else false
+     */
+    public boolean isSameBundleResource( String symbolicName, String version )
+    {
+        if ( this.isValid() )
+        {
+            return ( symbolicName.compareTo( this.getSymbolicName() ) == 0 )
+                && ( version.compareTo( this.getVersion() ) == 0 );
+        }
+        else
+        {
+            return false;
+        }
+
+    }
+
+
+    /**
+     * return a list of categories transformed to node.
+     * @param father father document to create node from same document
+     * @return List of Node
+     */
+    private List getNodeCategories( Document father )
+    {
+        List listNode = new ArrayList();
+        List listCategory = ( ArrayList ) this.getCategory();
+        for ( int i = 0; i < listCategory.size(); i++ )
+        {
+            listNode.add( ( ( Category ) listCategory.get( i ) ).getNode( father ) );
+        }
+        return listNode;
+    }
+
+
+    /**
+     * return a list of capabilities transformed to node.
+     * @param father father document to create node from same document
+     * @return List of Node
+     */
+    private List getNodeCapabilities( Document father )
+    {
+        List listNode = new ArrayList();
+        List listCapability = ( ArrayList ) this.getCapability();
+        for ( int i = 0; i < listCapability.size(); i++ )
+        {
+            listNode.add( ( ( Capability ) listCapability.get( i ) ).getNode( father ) );
+        }
+        return listNode;
+    }
+
+
+    /**
+     * return a list of requirement transformed to node.
+     * @param father father document to create node from same document
+     * @return List of Node.
+     */
+    private List getNodeRequirement( Document father )
+    {
+        List listNode = new ArrayList();
+        List listRequirement = ( ArrayList ) this.getRequire();
+        for ( int i = 0; i < listRequirement.size(); i++ )
+        {
+            listNode.add( ( ( Require ) listRequirement.get( i ) ).getNode( father ) );
+        }
+        return listNode;
+    }
+
+
+    /**
+     * return the list of properties not define in this bundle resource.
+     * @return list of properties not define
+     */
+    private String getInvalidProperties()
+    {
+        if ( this.isValid() )
+        {
+            if ( this.getId() == null )
+            {
+                return "id";
+            }
+            else
+            {
+                return "";
+            }
+        }
+        String result = "";
+        if ( this.getPresentationName() == null )
+        {
+            result = result + "presentationName;";
+        }
+        if ( this.getSymbolicName() == null )
+        {
+            result = result + "symbolicName;";
+        }
+        if ( this.getVersion() == null )
+        {
+            result = result + "version;";
+        }
+        if ( this.getUri() == null )
+        {
+            result = result + "Uri;";
+        }
+        if ( this.getSize() == null )
+        {
+            result = result + "Size";
+        }
+        return result;
+    }
+
+}
