[maven-release-plugin] copy for tag filevault-package-maven-plugin-1.0.0

git-svn-id: https://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/tags/filevault-package-maven-plugin-1.0.0@1813131 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/trunk/.gitignore b/trunk/.gitignore
new file mode 100644
index 0000000..4ad033d
--- /dev/null
+++ b/trunk/.gitignore
@@ -0,0 +1,7 @@
+target
+.idea
+.classpath
+.project
+.settings
+*.iml
+.DS_Store
diff --git a/trunk/.ratignore b/trunk/.ratignore
new file mode 100644
index 0000000..f8f3704
--- /dev/null
+++ b/trunk/.ratignore
@@ -0,0 +1,6 @@
+.ratignore
+src/test/resources/test-projects/**/*.txt
+src/test/resources/test-projects/**/*.xml
+src/test/resources/test-projects/**/.vlt
+src/test/resources/test-projects/**/.vltignore
+src/test/resources/test-projects/**/.dummy
\ No newline at end of file
diff --git a/trunk/LICENSE b/trunk/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/trunk/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/trunk/NOTICE b/trunk/NOTICE
new file mode 100644
index 0000000..a774a58
--- /dev/null
+++ b/trunk/NOTICE
@@ -0,0 +1,9 @@
+Apache Jackrabbit Filevault Package Maven Plugin
+Copyright 2017 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Based on source code originally developed by
+* Day Software (http://www.day.com/).
+* Adobe Systems Incorporated (http://www.adobe.com/).
\ No newline at end of file
diff --git a/trunk/README.md b/trunk/README.md
new file mode 100644
index 0000000..bc643ef
--- /dev/null
+++ b/trunk/README.md
@@ -0,0 +1,79 @@
+Welcome to Apache Jackrabbit FileVault Package Maven Plugin
+===========================================================
+
+The Apache Jackrabbit FileVault package maven plugin is an Apache maven plugin 
+that simplifies the creation of content package maven artifacts. The content 
+packages can later be used to install content into a JCR repository using the 
+Apache Jackrabbit FileVault packaging runtime.
+
+Apache Jackrabbit FileVault is a project of the Apache Software Foundation.
+
+Documentation
+=============
+Please refer to the plugin documentation at 
+http://jackrabbit.apache.org/filevault-package-maven-plugin/index.html
+
+
+Building the FileVault Package Maven Plugin
+===========================================
+
+You can build the plugin like this:
+
+    mvn clean install
+
+You need Maven 3.2.5 (or higher) with Java 7 (or higher) for the build.
+For more instructions, please see the documentation at:
+
+   http://jackrabbit.apache.org/building-jackrabbit.html
+
+License (see also LICENSE)
+==============================
+
+```
+Collective work: Copyright 2013 The Apache Software Foundation.
+
+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.
+```
+
+Mailing Lists
+=============
+
+To get involved with the Apache Jackrabbit project, start by having a
+look at our website and joining our mailing lists. For more details about
+Jackrabbit mailing lists as well as links to list archives, please see:
+
+   http://jackrabbit.apache.org/mailing-lists.html
+
+Latest development
+==================
+
+The latest FileVault package plugin source code is available via Subversion at
+
+   https://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/trunk/
+
+or with ViewVC at
+
+   https://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/
+
+To checkout the main source tree, run
+
+   svn checkout https://svn.apache.org/repos/asf/commons/filevault-package-maven-plugin/trunk filevault-package-maven-plugin
+
+Credits
+=======
+
+See http://jackrabbit.apache.org/jackrabbit-team.html for the list of
+Jackrabbit committers and main contributors.
diff --git a/trunk/RELEASE-NOTES.md b/trunk/RELEASE-NOTES.md
new file mode 100644
index 0000000..a365223
--- /dev/null
+++ b/trunk/RELEASE-NOTES.md
@@ -0,0 +1,88 @@
+<!--
+   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.
+  -->
+
+Release Notes -- Apache Jackrabbit FileVault Package Maven Plugin -- Version 1.0.0
+==================================================================================
+
+Introduction
+------------
+The Apache Jackrabbit FileVault package maven plugin is an Apache maven plugin that simplifies the creation of
+content package maven artifacts. The content packages can later be used to install content into a JCR repository
+using the Apache Jackrabbit FileVault packaging runtime.
+
+Changes in Jackrabbit FileVault Package Maven Plugin 1.0.0
+----------------------------------------------------------
+
+#### Notes
+Version 1.0.0 is the initial version of this contribution to the Apache
+Jackrabbit project.
+
+For more detailed information about all the changes in this and other
+FileVault releases, please see the FileVault issue tracker at
+https://issues.apache.org/jira/browse/JCRVLT
+
+#### Bug Fixes
+* [JCRVLT-206] Auto import-statement too big in case no compiled classes found
+
+#### Improvements
+* [JCRVLT-202] Import Adobe's content package maven plugin
+* [JCRVLT-204] Create documentation site for maven plugin
+* [JCRVLT-207] Make auto-import package a analyzer work with htl scripts
+* [JCRVLT-209] Always write to the filter.xml inside the vaultDir but never to filter-plugin-generated.xml
+
+#### New Features
+* [JCRVLT-205] Add support for cleanup filter entries
+* [JCRVLT-210] Allow to define excludes for the ContentPackageArchiver to prevent copying of script files from src to target
+* [JCRVLT-214] auto-import package analyzer needs option to exclude compiletime bundles
+
+
+Release Contents
+----------------
+This release consists of a single source archive packaged as a zip file.
+The archive can be unpacked with the jar tool from your JDK installation.
+See the [README](./README.md) file for instructions on how to build this release.
+
+The source archive is accompanied by SHA1 and MD5 checksums and a PGP
+signature that you can use to verify the authenticity of your download.
+The public key used for the PGP signature can be found at
+https://www.apache.org/dist/jackrabbit/KEYS
+
+About Apache Jackrabbit
+-----------------------
+Apache Jackrabbit is a fully conforming implementation of the Content
+Repository for Java Technology API (JCR). A content repository is a
+hierarchical content store with support for structured and unstructured
+content, full text search, versioning, transactions, observation, and
+more.
+
+For more information, visit http://jackrabbit.apache.org/
+
+About The Apache Software Foundation
+------------------------------------
+Established in 1999, The Apache Software Foundation provides organizational,
+legal, and financial support for more than 100 freely-available,
+collaboratively-developed Open Source projects. The pragmatic Apache License
+enables individual and commercial users to easily deploy Apache software;
+the Foundation's intellectual property framework limits the legal exposure
+of its 2,500+ contributors.
+
+For more information, visit http://www.apache.org/
+
+Trademarks
+----------
+Apache Jackrabbit, Jackrabbit, Apache, the Apache feather logo, and the Apache
+Jackrabbit project logo are trademarks of The Apache Software Foundation.
diff --git a/trunk/pom.xml b/trunk/pom.xml
new file mode 100644
index 0000000..4b1b1b9
--- /dev/null
+++ b/trunk/pom.xml
@@ -0,0 +1,550 @@
+<?xml version="1.0"?>
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
+    <modelVersion>4.0.0</modelVersion>
+    <!-- ====================================================================== -->
+    <!-- P A R E N T  P R O J E C T  D E S C R I P T I O N                      -->
+    <!-- ====================================================================== -->
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>18</version>
+        <relativePath />
+    </parent>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit</groupId>
+    <artifactId>filevault-package-maven-plugin</artifactId>
+    <version>1.0.0</version>
+    <packaging>maven-plugin</packaging>
+
+    <name>Apache Jackrabbit FileVault - Package Maven Plugin</name>
+    <description>Maven Plugin supporting creation of content packages.</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <mavenVersion>3.3.9</mavenVersion> <!-- required for https://issues.apache.org/jira/browse/MNG-5440 -->
+        <aether.version>1.0.2.v20150114</aether.version>
+    </properties>
+
+    <prerequisites>
+        <maven>3.2.5</maven>
+    </prerequisites>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/tags/filevault-package-maven-plugin-1.0.0</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/tags/filevault-package-maven-plugin-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/asf/jackrabbit/commons/filevault-package-maven-plugin/tags/filevault-package-maven-plugin-1.0.0</url>
+    </scm>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  I N F O                                                 -->
+    <!-- ====================================================================== -->
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <mailingLists>
+        <mailingList>
+            <name>Jackrabbit Developer List</name>
+            <subscribe>dev-subscribe@jackrabbit.apache.org</subscribe>
+            <unsubscribe>dev-unsubscribe@jackrabbit.apache.org</unsubscribe>
+            <post>mailto:dev@jackrabbit.apache.org</post>
+            <archive>http://mail-archives.apache.org/mod_mbox/jackrabbit-dev/</archive>
+        </mailingList>
+
+        <mailingList>
+            <name>Jackrabbit User List</name>
+            <subscribe>users-subscribe@jackrabbit.apache.org</subscribe>
+            <unsubscribe>users-unsubscribe@jackrabbit.apache.org</unsubscribe>
+            <post>mailto:users@jackrabbit.apache.org</post>
+            <archive>http://mail-archives.apache.org/mod_mbox/jackrabbit-users/</archive>
+        </mailingList>
+    </mailingLists>
+
+    <issueManagement>
+        <url>https://issues.apache.org/jira/browse/JCRVLT</url>
+    </issueManagement>
+
+    <!-- ====================================================================== -->
+    <!-- B U I L D   D E F I N I T I O N                                        -->
+    <!-- ====================================================================== -->
+    <build>
+        <plugins>
+            <!-- ====================================================================== -->
+            <!-- C O M P I L E R   P L U G I N                                          -->
+            <!-- ====================================================================== -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.7</source>
+                    <target>1.7</target>
+                    <debug>true</debug>
+                    <showDeprecation>false</showDeprecation>
+                    <showWarnings>true</showWarnings>
+                    <optimize>false</optimize>
+                </configuration>
+            </plugin>
+            <!-- ====================================================================== -->
+            <!-- M A V E N   P L U G I N                                                -->
+            <!-- ====================================================================== -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+                <version>3.5</version>
+                <executions>
+                    <execution>
+                        <id>default-descriptor</id>
+                        <phase>process-classes</phase>
+                    </execution>
+                    <!-- if you want to generate help goal -->
+                    <execution>
+                        <id>help-goal</id>
+                        <goals>
+                            <goal>helpmojo</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- ====================================================================== -->
+            <!-- I N S T A L L   P L U G I N                                            -->
+            <!-- ====================================================================== -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-install-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <!--
+                            make sure this plugin in installed in the local repository before the integration tests run
+                            maybe switching back to a reactor project might be better again
+                         -->
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>install</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- ====================================================================== -->
+            <!-- F A I L S A F E   P L U G I N                                          -->
+            <!-- ====================================================================== -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>2.20.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                        <configuration>
+                            <systemPropertyVariables>
+                                <plugin.version>${project.version}</plugin.version>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- ====================================================================== -->
+            <!-- S I T E   P L U G I N                                                  -->
+            <!-- ====================================================================== -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-site-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <generateReports>true</generateReports>
+                    <relativizeDecorationLinks>false</relativizeDecorationLinks>
+                    <skipDeploy>true</skipDeploy>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.maven.doxia</groupId>
+                        <artifactId>doxia-module-markdown</artifactId>
+                        <version>1.5</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <!-- ====================================================================== -->
+            <!-- S C M   P U B L I S H   P L U G I N                                    -->
+            <!-- ====================================================================== -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-scm-publish-plugin</artifactId>
+                <version>1.1</version>
+                <executions>
+                    <execution>
+                        <id>scm-publish</id>
+                        <phase>site-deploy</phase>
+                        <goals>
+                            <goal>publish-scm</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <content>target/site</content>
+                    <checkinComment>@trivial: Site checkin for project ${project.name}-${project.version}
+                    </checkinComment>
+                    <ignorePathsToDelete>
+                        <ignorePathToDelete>apidocs</ignorePathToDelete>
+                    </ignorePathsToDelete>
+                </configuration>
+            </plugin>
+            <!-- ====================================================================== -->
+            <!-- R A T   P L U G I N                                                    -->
+            <!-- ====================================================================== -->
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <version>0.12</version>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                        <configuration>
+                            <excludesFile>${project.basedir}/.ratignore</excludesFile>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!-- ====================================================================== -->
+    <!-- R E P O R T I N G                                                      -->
+    <!-- ====================================================================== -->
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+                <version>3.5</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>2.4</version>
+                <configuration>
+                    <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
+                    <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+
+    <!-- ====================================================================== -->
+    <!-- D I S T R I B U T I O N   M A N A G E M E N T                          -->
+    <!-- ====================================================================== -->
+    <distributionManagement>
+        <site>
+            <id>jackrabbit.filevault.site-deploy</id>
+            <url>scm:svn:https://svn.apache.org/repos/asf/jackrabbit/site/live/filevault-package-maven-plugin</url>
+        </site>
+    </distributionManagement>
+
+    <!-- ====================================================================== -->
+    <!-- D E P E N D E N C I E S                                                -->
+    <!-- ====================================================================== -->
+    <dependencies>
+        <!-- Maven Plugin stuff -->
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+            <version>${mavenVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>${mavenVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>3.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-project</artifactId>
+            <version>3.0-alpha-2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-artifact</artifactId>
+            <version>${mavenVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-compat</artifactId>
+            <version>${mavenVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-model</artifactId>
+            <version>${mavenVersion}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-archiver</artifactId>
+            <version>3.0.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.codehaus.plexus</groupId>
+                    <artifactId>plexus-component-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+            <version>3.0.22</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>animal-sniffer-maven-plugin</artifactId>
+            <version>1.14</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>findbugs</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>1.7.5</version>
+        </dependency>
+
+        <!-- bundle tools -->
+        <dependency>
+            <groupId>biz.aQute.bnd</groupId>
+            <artifactId>biz.aQute.bndlib</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+
+        <!-- class analyzer -->
+        <dependency>
+            <groupId>io.github.lukehutch</groupId>
+            <artifactId>fast-classpath-scanner</artifactId>
+            <version>2.0.21</version>
+        </dependency>
+
+        <!-- oak:index definition checker -->
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.10.3</version>
+        </dependency>
+
+        <!-- testing -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.10</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>1.7.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-testing</groupId>
+            <artifactId>maven-plugin-testing-harness</artifactId>
+            <version>3.3.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.json</artifactId>
+            <version>2.0.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.aether</groupId>
+            <artifactId>aether-api</artifactId>
+            <version>${aether.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-aether-provider</artifactId>
+            <version>${mavenVersion}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+            <version>2.0.0.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-verifier</artifactId>
+            <version>1.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-shared-io</artifactId>
+            <version>3.0.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-shared-utils</artifactId>
+            <version>3.2.0</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <!-- ====================================================================== -->
+    <!-- P R O F I L E S                                                        -->
+    <!-- ====================================================================== -->
+    <profiles>
+        <profile>
+            <id>apache-release</id>
+            <properties>
+                <username>${user.name}</username>
+                <keyfile>${user.home}/.ssh/id_rsa</keyfile>
+                <passphrase />
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>sign-release-artifacts</id>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                                <configuration>
+                                    <keyname>${gpg.keyname}</keyname>
+                                    <passphraseServerId>${gpg.keyname}</passphraseServerId>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <phase>deploy</phase>
+                                <configuration>
+                                    <tasks>
+                                        <mkdir dir="${basedir}/target/${project.version}" />
+                                        <copy todir="${basedir}/target/${project.version}" flatten="true">
+                                            <fileset dir="${basedir}">
+                                                <include name="RELEASE-NOTES.md" />
+                                                <include name="target/*-source-release.zip*" />
+                                            </fileset>
+                                        </copy>
+                                        <checksum algorithm="MD5" fileext=".md5">
+                                            <fileset dir="${basedir}/target/${project.version}">
+                                                <include name="*.zip" />
+                                            </fileset>
+                                        </checksum>
+                                        <checksum algorithm="SHA1" fileext=".sha">
+                                            <fileset dir="${basedir}/target/${project.version}">
+                                                <include name="*.zip" />
+                                            </fileset>
+                                        </checksum>
+                                        <checksum file="${basedir}/target/${project.version}/filevault-package-maven-plugin-${project.version}-source-release.zip" algorithm="SHA1" property="checksum" />
+                                        <echo file="${basedir}/target/vote.txt">
+                                            From: ${username}@apache.org
+                                            To: dev@jackrabbit.apache.org
+                                            Subject: [VOTE] Release Apache Jackrabbit Filevault Package Maven Plugin
+                                            ${project.version}
+
+                                            A candidate for the Jackrabbit Filevault Package Maven Plugin
+                                            ${project.version} release is available at:
+
+                                            https://dist.apache.org/repos/dist/dev/jackrabbit/filevault-package-maven-plugin/${project.version}/
+
+                                            The release candidate is a zip archive of the sources in:
+
+                                            https://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/tags/jackrabbit-filevault-${project.version}/
+
+                                            The SHA1 checksum of the archive is ${checksum}.
+
+                                            A staged Maven repository is available for review at:
+
+                                            https://repository.apache.org/
+
+                                            Please vote on releasing this package as Apache Jackrabbit Filevault Package
+                                            Maven Plugin ${project.version}.
+                                            The vote is open for the next 72 hours and passes if a majority of at
+                                            least three +1 Jackrabbit PMC votes are cast.
+
+                                            [ ] +1 Release this package as Apache Jackrabbit Filevault Package Maven
+                                            Plugin ${project.version}
+                                            [ ] -1 Do not release this package because...${line.separator}
+                                        </echo>
+                                        <echo />
+                                        <echo>
+                                            The release candidate has been prepared in:
+
+                                            ${basedir}/target/${project.version}
+
+                                            Please deploy it to
+                                            https://dist.apache.org/repos/dist/dev/jackrabbit/filevault-package-maven-plugin:
+
+                                            cd /path/to/jackrabbit-dev/filevault-package-maven-plugin
+                                            mv ${basedir}/target/${project.version} ${project.version}
+                                            svn add ${project.version}
+                                            svn commit -m 'Apache Jackrabbit Filevault Package Maven Plugin
+                                            ${project.version} release candidate' ${project.version}
+
+                                            A release vote template has been generated for you:
+
+                                            file://${basedir}/target/vote.txt
+                                        </echo>
+                                        <echo />
+                                    </tasks>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.apache.ant</groupId>
+                                <artifactId>ant-nodeps</artifactId>
+                                <version>1.8.1</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/AnalyzeClassesMojo.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/AnalyzeClassesMojo.java
new file mode 100644
index 0000000..a0cd637
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/AnalyzeClassesMojo.java
@@ -0,0 +1,110 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
+
+import aQute.bnd.osgi.Processor;
+
+/**
+ * Maven goal which analyzes the generated class files and generates a usage report
+ */
+@Mojo(
+        name = "analyze-classes",
+        defaultPhase = LifecyclePhase.PROCESS_CLASSES,
+        requiresDependencyResolution = ResolutionScope.COMPILE
+)
+public class AnalyzeClassesMojo extends AbstractMojo {
+
+    /**
+     * The Maven project.
+     */
+    @Parameter(property = "project", readonly = true, required = true)
+    private MavenProject project;
+
+    /**
+     * Location of class files
+     */
+    @Parameter(property = "vault.classesDirectory", defaultValue = "${project.build.outputDirectory}")
+    private File sourceDirectory;
+
+    /**
+     * Controls if the output should contain the package report.
+     */
+    @Parameter(property = "vault.showPackageReport", defaultValue = "true")
+    private boolean showImportPackageReport;
+
+    /**
+     * File to store the generated manifest snippet.
+     */
+    @Parameter(property = "vault.generatedImportPackage", defaultValue = "${project.build.directory}/vault-generated-import.txt")
+    private File generatedImportPackage;
+
+    /**
+     * Defines if unused packages should be included in the import-package entry if no classes exist in the project
+     */
+    @Parameter(property = "vault.importUnusedPackages")
+    private boolean importUnusedPackages;
+
+    /**
+     * Defines a list of libraries in partial maven coordinates that are not used for analysis.
+     */
+    @Parameter(property = "vault.excludedLibraries")
+    private String[] excludedLibraries;
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        try {
+            getLog().info("Analyzing java package dependencies.");
+            List<String> excluded = new ArrayList<String>(excludedLibraries.length);
+            for (String lib: excludedLibraries) {
+                excluded.add(lib.trim());
+            }
+
+            ImportPackageBuilder builder = new ImportPackageBuilder()
+                    .withFilter(new PatternExcludesArtifactFilter(excluded))
+                    .withDependenciesFromProject(project)
+                    .withClassFileDirectory(sourceDirectory)
+                    .withIncludeUnused(importUnusedPackages)
+                    .analyze();
+
+            String report = builder.createExportPackageReport();
+            if (showImportPackageReport) {
+                getLog().info(report);
+            }
+
+            String importParams = Processor.printClauses(builder.getImportParameters());
+            FileUtils.write(generatedImportPackage, importParams, "utf-8");
+
+        } catch (IOException e) {
+            throw new MojoExecutionException("Error while analysing imports", e);
+        }
+    }
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/CheckSignatureMojo.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/CheckSignatureMojo.java
new file mode 100644
index 0000000..a7aba77
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/CheckSignatureMojo.java
@@ -0,0 +1,202 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.mojo.animal_sniffer.ClassListBuilder;
+import org.codehaus.mojo.animal_sniffer.SignatureChecker;
+import org.codehaus.mojo.animal_sniffer.maven.MavenLogger;
+import org.codehaus.mojo.animal_sniffer.maven.Signature;
+
+/**
+ * Maven goal which checks the embedded libraries against a defined
+ * signature. Based on the Animal Sniffer project.
+ */
+@Mojo(
+        name = "check-signature",
+        defaultPhase = LifecyclePhase.PROCESS_CLASSES,
+        requiresDependencyResolution = ResolutionScope.COMPILE
+)
+public class CheckSignatureMojo extends AbstractMojo {
+
+    /**
+     * The Maven project.
+     */
+    @Parameter(property = "project", readonly = true, required = true)
+    private MavenProject project;
+
+    /**
+     * list of embedded bundles
+     */
+    @Parameter
+    private Embedded[] embeddeds = new Embedded[0];
+
+    /**
+     * Defines whether to fail the build when an embedded artifact is not
+     * found in the project's dependencies
+     */
+    @Parameter(property = "vault.failOnMissingEmbed", defaultValue = "false", required = true)
+    private boolean failOnMissingEmbed;
+
+
+    /**
+     */
+    @Component
+    private ArtifactFactory artifactFactory;
+
+    /**
+     * Project classpath.
+     */
+    @Parameter(property = "project.compileClasspathElements", required = true, readonly = true)
+    private List classpathElements;
+
+    /**
+     * Class names to ignore signatures for (wildcards accepted).
+     */
+    @Parameter
+    private String[] ignores;
+
+    /**
+     */
+    @Parameter(property = "localRepository", readonly = true)
+    private ArtifactRepository localRepository;
+
+    /**
+     */
+    @Component
+    private ArtifactResolver resolver;
+
+    /**
+     * Signature module to use.
+     */
+    @Parameter
+    private Signature signature;
+
+    /**
+     * If true, skip the signature check.
+     */
+    @Parameter(property = "vault.checksignature.skip", defaultValue="false")
+    private boolean skipCheckSignature;
+
+    /**
+     * List of packages defined in the application.
+     */
+    private Set<String> buildPackageList() throws IOException {
+        ClassListBuilder plb = new ClassListBuilder(new MavenLogger(getLog()));
+        for (Object classpathElement : classpathElements) {
+            String path = (String) classpathElement;
+            plb.process(new File(path));
+        }
+        return plb.getPackages();
+    }
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (skipCheckSignature) {
+            getLog().info("Skipping signature check.");
+            return;
+        }
+        if (signature == null) {
+            getLog().info("No signature defined. Skipping signature check.");
+            return;
+        }
+        
+        try {
+            getLog().info("Checking unresolved references to " + signature);
+
+            org.apache.maven.artifact.Artifact a = signature.createArtifact(artifactFactory);
+
+            resolver.resolve(a, project.getRemoteArtifactRepositories(), localRepository);
+            // just check code from this module
+            final Set<String> ignoredPackages = buildPackageList();
+
+            if (ignores != null) {
+                for (String ignore : ignores) {
+                    if (ignore == null) {
+                        continue;
+                    }
+                    ignoredPackages.add(ignore.replace('.', '/'));
+                }
+            }
+
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(ignoredPackages.toString());
+            }
+
+            final SignatureChecker signatureChecker = new SignatureChecker(new FileInputStream(a.getFile()),
+                    ignoredPackages, new MavenLogger(getLog()));
+            signatureChecker.setCheckJars(true);
+            signatureChecker.setSourcePath(Collections.singletonList(new File(project.getBuild().getSourceDirectory())));
+            signatureChecker.process(getEmbeddeds().toArray(new File[0]));
+
+            if (signatureChecker.isSignatureBroken()) {
+                throw new MojoFailureException(
+                        "Signature errors found. Verify them and put @IgnoreJRERequirement on them.");
+            }
+        } catch (IOException e) {
+            throw new MojoExecutionException("Failed to check signatures", e);
+        } catch (AbstractArtifactResolutionException e) {
+            throw new MojoExecutionException("Failed to obtain signature: " + signature, e);
+        }
+    }
+
+    private Collection<File> getEmbeddeds() throws MojoFailureException {
+        Set<File> files = new HashSet<File>();
+        for (Embedded emb : embeddeds) {
+            final List<Artifact> artifacts = emb.getMatchingArtifacts(project);
+            if (artifacts.isEmpty()) {
+                if (failOnMissingEmbed) {
+                    throw new MojoFailureException(
+                            "Embedded artifact specified "
+                                    + emb
+                                    + ", but no matching dependency artifact found. Add the missing dependency or fix the embed definition.");
+                } else {
+                    getLog().warn("No matching artifacts for " + emb);
+                    continue;
+                }
+            }
+
+            for (Artifact artifact : artifacts) {
+                final File source = artifact.getFile();
+                files.add(source);
+            }
+        }
+        return files;
+    }
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ContentPackageArchiver.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ContentPackageArchiver.java
new file mode 100644
index 0000000..986b6b0
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ContentPackageArchiver.java
@@ -0,0 +1,28 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+
+public class ContentPackageArchiver extends JarArchiver {
+    
+    public ContentPackageArchiver() {
+        super();
+        archiveType = "content-package";
+    }
+
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Dependency.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Dependency.java
new file mode 100644
index 0000000..dcae917
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Dependency.java
@@ -0,0 +1,182 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.io.IOException;
+
+import javax.annotation.Nullable;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.StringUtils;
+
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PackageInfo;
+
+/**
+ * The {@code Dependency} class represents a dependency to another content package.
+ * A dependency consists of a group name, a package name and a version range.
+ * <p>
+ * A dependency is declared as a {@code <dependency>} element of a list
+ * style {@code <dependencies>} element:
+ * <pre>
+ * &lt;dependency&gt;
+ * 	   &lt;group&gt;theGroup&lt;/group&gt;
+ * 	   &lt;name&gt;theName&lt;/name&gt;
+ * 	   &lt;version&gt;1.5&lt;/version&gt;
+ * &lt;/dependency&gt;
+ * </pre>
+ * <p>
+ * The dependency can also reference a maven project dependency, this is preferred
+ * as it yields to more robust builds.
+ * <pre>
+ * &lt;dependency&gt;
+ * 	   &lt;groupId&gt;theGroup&lt;/groupId&gt;
+ * 	   &lt;artifactId&gt;theName&lt;/artifactId&gt;
+ * &lt;/dependency&gt;
+ * </pre>
+ * <p>
+ * The {@code versionRange} may be indicated as a single version, in which
+ * case the version range has no upper bound and defines the minimal version
+ * accepted. Otherwise, the version range defines a lower and upper bound of
+ * accepted versions, where the bounds are either included using parentheses
+ * {@code ()} or excluded using brackets {@code []}
+ */
+public class Dependency {
+
+    /**
+     * The group name, required for package-id references
+     */
+    @Parameter
+    private String group;
+
+    /**
+     * The group id, required for maven coordinate references
+     */
+    @Parameter
+    private String groupId;
+
+    /**
+     * The package name, required for package-id references.
+     */
+    @Parameter
+    private String name;
+
+    /**
+     * The artifact id, required for maven coordinate references
+     */
+    @Parameter
+    private String artifactId;
+
+    /**
+     * The version range (optional)
+     */
+    @Parameter
+    private String version;
+
+    /**
+     * Package information of this dependency. only available for maven referenced dependencies after {@link #resolve(MavenProject, Log)}
+     */
+    private PackageInfo info;
+
+    /**
+     * Resolved package dependency. only available after {@link #resolve(MavenProject, Log)}
+     */
+    private PackageDependency dependency;
+
+    /**
+     * Converts a list of {@link Dependency} instances to vault dependencies.
+     *
+     * @param log the Logger
+     * @param dependencyList The list of {@link Dependency} instances to convert.
+     * @return The Vault Packaging Dependency representing the dependencies.
+     */
+    static PackageDependency[] resolve(final MavenProject project, final Log log, final Dependency... dependencyList) throws IOException {
+        PackageDependency[] dependencies = new PackageDependency[dependencyList.length];
+        for (int i = 0; i < dependencies.length; i++) {
+            dependencies[i] = dependencyList[i].resolve(project, log);
+        }
+        return dependencies;
+    }
+
+    /**
+     * Helper method for {@link #toString)} to convert an instance of this
+     * class to a Vault Packaging Dependency for easy string conversion.
+     */
+    private PackageDependency resolve(final MavenProject project, final Log log) throws IOException {
+        if (!StringUtils.isEmpty(group) || !StringUtils.isEmpty(name)) {
+            log.warn("Using package id in dependencies is deprecated. use maven coordinates instead: " + group + ":" + name);
+        }
+        if (!StringUtils.isEmpty(groupId) && !StringUtils.isEmpty(artifactId)) {
+            for (Artifact a : project.getDependencyArtifacts()) {
+                if (a.getArtifactId().equals(artifactId) && a.getGroupId().equals(groupId)) {
+                    PackageInfo info = PackageInfo.read(a.getFile());
+                    if (info != null) {
+                        PackageId id = info.getId();
+                        group = id.getGroup();
+                        name = id.getName();
+                        if (StringUtils.isEmpty(version)) {
+                            version = new VersionRange(id.getVersion(), true, null, false).toString();
+                        }
+                        this.info = info;
+                        break;
+                    } else {
+                        throw new IOException("Specified dependency " + this + " is not a package.");
+                    }
+                }
+            }
+        }
+        if (StringUtils.isEmpty(group) || StringUtils.isEmpty(name)) {
+            throw new IOException("Specified dependency " + this + " is not qualified.");
+        }
+        VersionRange range = StringUtils.isEmpty(version) ? VersionRange.INFINITE : VersionRange.fromString(version);
+        return dependency = new PackageDependency(group, name, range);
+    }
+
+    /**
+     * Returns the package info or {@code null}.
+     *
+     * @return the info.
+     */
+    @Nullable
+    public PackageInfo getInfo() {
+        return info;
+    }
+
+    /**
+     * Returns the package dependency or {@code null} if not resolved.
+     *
+     * @return the package dependency.
+     */
+    @Nullable
+    public PackageDependency getPackageDependency() {
+        return dependency;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("Dependency{");
+        sb.append("group='").append(group).append('\'');
+        sb.append(", groupId='").append(groupId).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", artifactId='").append(artifactId).append('\'');
+        sb.append(", version='").append(version).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/DependencyValidator.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/DependencyValidator.java
new file mode 100644
index 0000000..11cae46
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/DependencyValidator.java
@@ -0,0 +1,122 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+
+import org.apache.jackrabbit.filevault.maven.packaging.impl.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PackageInfo;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PathFilterSet;
+
+/**
+ * {@code DependencyValidator}...
+ */
+public class DependencyValidator {
+
+    private List<Dependency> dependencies = new LinkedList<>();
+
+    private DefaultWorkspaceFilter filters;
+
+    private List<String> errors = new LinkedList<String>();
+
+    public DependencyValidator addDependencies(Dependency ... dependencies) {
+        this.dependencies.addAll(Arrays.asList(dependencies));
+        return this;
+    }
+
+    public DependencyValidator setFilters(DefaultWorkspaceFilter filters) {
+        this.filters = filters;
+        return this;
+    }
+
+    public List<String> getErrors() {
+        return errors;
+    }
+
+    /**
+     * Checks if the filter roots of this package are covered by the dependencies and also checks for colliding roots
+     * in the dependencies.
+     *
+     * @return this validator
+     */
+    public DependencyValidator validate() {
+        // check for overlapping dependency roots
+        Map<String, Dependency> roots = new HashMap<String, Dependency>();
+        for (Dependency dep: dependencies) {
+            PackageInfo info = dep.getInfo();
+            if (info == null) {
+                String msg = String.format("Dependency '%s' is not using maven coordinates and cannot be used for analysis.", dep.getPackageDependency());
+                errors.add(msg);
+                continue;
+            }
+            for (PathFilterSet set : info.getFilter().getFilterSets()) {
+                String root = set.getRoot();
+                Dependency existing = roots.get(root);
+                if (existing != null) {
+                    String msg = String.format("Dependency '%s' defines same filter root '%s' as dependency '%s'",
+                            dep.getPackageDependency(), root, existing.getPackageDependency());
+                    errors.add(msg);
+                }
+                roots.put(root, dep);
+            }
+        }
+        // check that this filter is covered.
+        Set<String> ancestors = new HashSet<String>();
+        for (PathFilterSet set: filters.getFilterSets()) {
+            if (set.isCleanUp()) {
+                continue;
+            }
+            String root = StringUtils.substringBeforeLast(set.getRoot(), "/");
+            // ignore root node as ancestor
+            if ("/".equals(root)) {
+                continue;
+            }
+            ancestors.add(root);
+        }
+        for (String root: ancestors) {
+            String isCovered = null;
+            boolean isContained = false;
+            for (Dependency dep: roots.values()) {
+                DefaultWorkspaceFilter filter = dep.getInfo().getFilter();
+                if (filter.contains(root)) {
+                    isContained = true;
+                }
+                if (filter.covers(root)) {
+                    isCovered = dep.getPackageDependency().toString();
+                }
+            }
+            if (!isContained) {
+                String msg;
+                if (isCovered == null) {
+                    msg = String.format("Filter root's ancestor '%s' is not covered by any of the specified dependencies.", root);
+                } else {
+                    msg = String.format("Filter root's ancestor '%s' is covered by '%s' but excluded by its patterns.", root, isCovered);
+                }
+                errors.add(msg);
+            }
+        }
+        return this;
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Embedded.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Embedded.java
new file mode 100644
index 0000000..2021b06
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Embedded.java
@@ -0,0 +1,185 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+
+import org.apache.jackrabbit.filevault.maven.packaging.impl.StringFilterSet;
+
+/**
+ * The {@code Embedded} class represents an embedded artifact dependency
+ * from the project descriptor. Such an embedding is declared in
+ * {@code <embedded>} elements inside the list style
+ * {@code <embeddeds>} element as follows:
+ * <pre>
+ * &lt;embedded&gt;
+ *     &lt;groupId&gt;artifact.groupId.pattern&lt;/groupId&gt;
+ *     &lt;artifactId&gt;artifact.artifactId.pattern&lt;/artifactId&gt;
+ *     &lt;scope&gt;compile&lt;/scope&gt;
+ *     &lt;type&gt;jar&lt;/type&gt;
+ *     &lt;classifier&gt;sources&lt;/classifier&gt;
+ *     &lt;filter&gt;true&lt;/filter&gt;
+ *     &lt;target&gt;/libs/sling/install&lt;/target&gt;
+ * &lt;/embedded&gt;
+ * </pre>
+ */
+public class Embedded {
+
+    /**
+     * A group filter string, consisted of one or several comma separated patterns.
+     */
+    private final StringFilterSet groupId = new StringFilterSet();
+
+    /**
+     * A artifact filter string, consisted of one or several comma separated patterns.
+     */
+    private final StringFilterSet artifactId = new StringFilterSet();
+
+    @Parameter
+    private ScopeArtifactFilter scope;
+
+    @Parameter
+    private String type;
+
+    @Parameter
+    private String classifier;
+
+    /**
+     * If {@code true} a filter entry will be generated for all embedded artifacts.
+     */
+    @Parameter
+    private boolean filter;
+
+    /**
+     * Target location.
+     */
+    @Parameter
+    private String target;
+
+    /**
+     * Name to use for the artifact in the destination
+     */
+    @Parameter
+    private String destFileName;
+
+    @Parameter
+    private boolean excludeTransitive;
+
+    public void setGroupId(String groupId) {
+        this.groupId.addEntries(groupId);
+    }
+
+    public void setArtifactId(String artifactId) {
+        this.artifactId.addEntries(artifactId);
+    }
+
+    public void setScope(String scope) {
+        this.scope = new ScopeArtifactFilter(scope);
+    }
+
+    public void setAddFilter(boolean filter) {
+        this.filter = filter;
+    }
+
+    public boolean isFilter() {
+        return filter;
+    }
+
+    public String getDestFileName() {
+        return destFileName;
+    }
+
+    public void setDestFileName(String destFileName) {
+        this.destFileName = destFileName;
+    }
+
+    public void setTarget(String target) {
+        // need trailing slash
+        if (!target.endsWith("/")) {
+            target += "/";
+        }
+
+        this.target = target;
+    }
+
+    public String getTarget() {
+        return target;
+    }
+
+    public void setExcludeTransitive(boolean excludeTransitive) {
+        this.excludeTransitive = excludeTransitive;
+    }
+
+    public boolean isExcludeTransitive() {
+        return excludeTransitive;
+    }
+
+    public List<Artifact> getMatchingArtifacts(final MavenProject project) {
+
+        // get artifacts depending on whether we exclude transitives or not
+        final Set<Artifact> deps;
+        if (excludeTransitive) {
+            // only direct dependencies, transitives excluded
+            deps = project.getDependencyArtifacts();
+        } else {
+            // all dependencies, transitives included
+            deps = project.getArtifacts();
+        }
+
+        final List<Artifact> matches = new ArrayList<Artifact>();
+        for (Artifact artifact : deps) {
+            if (groupId.contains(artifact.getGroupId())
+                    && artifactId.contains(artifact.getArtifactId())
+                    && (scope == null || scope.include(artifact))
+                    && (type == null || type.equals(artifact.getType()))
+                    && (classifier == null || classifier.equals(artifact.getClassifier()))) {
+                matches.add(artifact);
+            }
+        }
+        return matches;
+    }
+
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Embedded: ");
+        if (groupId != null) {
+            builder.append("groupId=").append(groupId).append(",");
+        }
+        if (artifactId != null) {
+            builder.append("artifactId=").append(artifactId).append(",");
+        }
+        if (scope != null) {
+            builder.append("scope=").append(scope).append(",");
+        }
+        builder.append("filter=").append(filter);
+        builder.append(",excludeTransitive=").append(excludeTransitive);
+        if (target != null) {
+            builder.append(",target=").append(target);
+        }
+        if (destFileName != null) {
+            builder.append(",destFileName=").append(destFileName);
+        }
+        return builder.toString();
+    }
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/FileValidator.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/FileValidator.java
new file mode 100644
index 0000000..b771e09
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/FileValidator.java
@@ -0,0 +1,129 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Parser;
+
+/**
+ * This helper class checks for index definitions within packages
+ */
+public class FileValidator {
+    public boolean isContainingIndexDef;
+
+    //store entries of index found in META-INF/vault/filter.xml
+    List<String> indexPaths = new ArrayList<String>();
+
+    //store entries of index found in _oak_index/.content.xml
+    Map<String, String> foundIndexes = new HashMap<String, String>();
+
+    public void lookupIndexDefinitionInArtifact(InputStream artifactFileInputStream, String artifactName) throws IOException, MojoExecutionException {
+        if (artifactName.endsWith("zip")) {
+            ZipInputStream zipArtifactStream = new ZipInputStream(artifactFileInputStream);
+            String entryName = "";
+            ZipEntry entry = zipArtifactStream.getNextEntry();
+            while (entry != null) {
+                entryName = entry.getName();
+                if (entryName.endsWith("zip")) {
+                    //recur if the entry is a zip file
+                    lookupIndexDefinitionInArtifact(zipArtifactStream, artifactName + "/" + entryName);
+                } else if ("META-INF/vault/filter.xml".equals(entryName) || entryName.contains("/_oak_index/")) {
+                    //if entry is an vault filter file or an oak index definition file, parse it to check for indexes
+                    this.parseXMLForIndexDefinition(zipArtifactStream, entryName, artifactName + "/" + entryName);
+                }
+                entry = zipArtifactStream.getNextEntry();
+            }
+        } else if ("META-INF/vault/filter.xml".equals(artifactName) || artifactName.contains("/_oak_index/")) {
+            //if entry is an vault filter file or an oak index definition file, parse it to check for indexes
+            this.parseXMLForIndexDefinition(artifactFileInputStream, artifactName, artifactName);
+        }
+    }
+
+    private void parseXMLForIndexDefinition(InputStream xmlInputStream, String entryName, String absoluteEntryName) throws MojoExecutionException {
+        try {
+            Document xml = Jsoup.parse(xmlInputStream, "UTF-8", "", Parser.xmlParser());
+            if ("META-INF/vault/filter.xml".equals(entryName)) {
+                for (Element filter : xml.select("filter[root]")) {
+                    String root = filter.attr("root");
+                    int oakIndexPosition = root.indexOf("/oak:index");
+                    if (oakIndexPosition >= 0) {
+                        isContainingIndexDef = true;
+                        int nextSlash = root.indexOf("/", oakIndexPosition + "oak:index".length() + 2);
+                        String baseIndexPath;
+
+                        if (nextSlash > -1) {
+                            baseIndexPath = root.substring(0, nextSlash);
+                        } else {
+                            baseIndexPath = root;
+                        }
+                        indexPaths.add(baseIndexPath);
+                    }
+
+                }
+            } else if (entryName.contains("/_oak_index/")) {
+                String basePath = entryName.substring(8).replace("_oak_index", "oak:index").replace("/.content.xml", "");
+
+                // search for "jcr:primaryType" properties that have a value ending in oak:QueryIndexDefinition
+                // as it can also be "{Name}oak:QueryIndexDefinition"
+                for (Element element : xml.select("*[jcr:primaryType$=oak:QueryIndexDefinition]")) {
+                    String xmlPath = getXmlPath(element);
+                    String jcrPath = StringUtils.removeStart(xmlPath, "/jcr:root");
+                    foundIndexes.put(basePath + jcrPath, absoluteEntryName);
+                }
+            }
+        } catch (Exception e) {
+            throw new MojoExecutionException("Error while trying to parse xml " + absoluteEntryName, e);
+        }
+    }
+
+    private static String getXmlPath(Element element) {
+        if (element.ownerDocument() == element) {
+            return "";
+        } else {
+            return getXmlPath(element.parent()) + "/" + element.nodeName();
+        }
+    }
+
+    public String getMessageWithPathsOfIndexDef() {
+        StringBuilder msg = new StringBuilder();
+
+        for (String path : indexPaths) {
+            String completePath = foundIndexes.get(path);
+
+            if (completePath != null) {
+                msg.append(" Package contains index ").append(path).append(" in ").append(completePath).append(".").append(System.lineSeparator());
+            } else {
+                msg.append(" Package contains index ").append(path).append(" in filter, but not in package. Existing index will be removed.").append(System.lineSeparator());
+            }
+        }
+        return msg.toString();
+    }
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Filter.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Filter.java
new file mode 100644
index 0000000..4f6126b
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Filter.java
@@ -0,0 +1,102 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import org.apache.jackrabbit.filevault.maven.packaging.impl.DefaultPathFilter;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.ImportMode;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PathFilterSet;
+
+public class Filter {
+
+    /**
+     * General format:
+     *
+     * <pre>
+     *
+     * &lt;filter&gt;
+     *      &lt;root&gt;/var&lt;/root&gt;
+     *      &lt;type&gt;cleanup&lt;/type&gt;
+     *      &lt;mode&gt;merge&lt;/mode&gt;
+     *      &lt;includes&gt;
+     *          &lt;include&gt;dam/sharepoint(/.*)?&lt;/include&gt;
+     *          &lt;include&gt;/var/dam&lt;/include&gt;
+     *      &lt;/includes&gt;
+     * &lt;/filter&gt;
+     * </pre>
+     */
+
+    static final String INDENT = "    ";
+
+    private String root;
+
+    /** ImportMode defaulting to REPLACE */
+    private ImportMode mode = ImportMode.REPLACE;
+
+    private boolean cleanupType;
+
+    private final IncludeExcludeList includes = new IncludeExcludeList();
+
+    private final IncludeExcludeList excludes = new IncludeExcludeList();
+
+    public Filter() {
+    }
+
+    public Filter(String root) {
+        setRoot(root);
+    }
+
+    public void setRoot(final String root) {
+        this.root = root;
+    }
+
+    public String getRoot() {
+        return root;
+    }
+
+    public void setMode(String mode) {
+        if (mode != null) {
+            this.mode = ImportMode.valueOf(mode.toUpperCase());
+        }
+    }
+
+    public ImportMode getMode() {
+        return mode;
+    }
+
+    public boolean isCleanupType() {
+        return cleanupType;
+    }
+
+    public void setType(String type) {
+        cleanupType = "cleanup".equals(type);
+    }
+
+    public PathFilterSet toPathFilterSet() {
+        PathFilterSet set = new PathFilterSet();
+        set.setRoot(root);
+        set.setImportMode(mode);
+        set.setCleanUp(cleanupType);
+        for (String pattern: includes) {
+            set.addInclude(new DefaultPathFilter(pattern));
+        }
+        for (String pattern: excludes) {
+            set.addExclude(new DefaultPathFilter(pattern));
+        }
+        return set;
+    }
+
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ImportPackageBuilder.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ImportPackageBuilder.java
new file mode 100644
index 0000000..dc3f49a
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ImportPackageBuilder.java
@@ -0,0 +1,529 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import javax.annotation.Nonnull;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.StringUtils;
+
+import aQute.bnd.header.Attrs;
+import aQute.bnd.header.Parameters;
+import aQute.bnd.osgi.Analyzer;
+import aQute.bnd.osgi.Clazz;
+import aQute.bnd.osgi.Constants;
+import aQute.bnd.osgi.Descriptors;
+import aQute.bnd.osgi.FileResource;
+import aQute.bnd.osgi.Processor;
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
+
+/**
+ * The import package builder is used to analyze the classes and dependencies of the project and calculate the
+ * import-package statement for this package.
+ */
+public class ImportPackageBuilder {
+
+    /**
+     * class file directory
+     */
+    private File classFileDirectory;
+
+    /**
+     * list of class files. initialized during {@link #analyze()}
+     */
+    private List<File> classFiles;
+
+    /**
+     * list of artifacts relevant for analysis
+     */
+    private List<Artifact> artifacts;
+
+    /**
+     * BND analyzer
+     */
+    private Analyzer analyzer;
+
+    /**
+     * The scan result from the fast-classpath analyzer
+     */
+    private ScanResult scanResult;
+
+    /**
+     * artifact-id -> bundle info mapping
+     */
+    private Map<String, BundleInfo> bundles = new HashMap<String, BundleInfo>();
+
+    /**
+     * map of all exported packaged by the bundles.
+     */
+    private Map<String, PackageInfo> exported = new HashMap<String, PackageInfo>();
+
+    /**
+     * map of all classes
+     */
+    private Map<String, ClassInfo> classes = new HashMap<String, ClassInfo>();
+
+    /**
+     * the calculated import parameters.
+     */
+    private Map<String, Attrs> importParameters = Collections.emptyMap();
+
+    /**
+     * specifies if unused packages should be included if there are not classes in the project
+     */
+    private boolean includeUnused;
+
+    /**
+     * filter for project artifacts
+     */
+    private ArtifactFilter filter = new ArtifactFilter() {
+        @Override
+        public boolean include(Artifact artifact) {
+            return true;
+        }
+    };
+
+    /**
+     * Sets the class files directory
+     * @param classes the directory
+     * @return this.
+     */
+    @Nonnull
+    public ImportPackageBuilder withClassFileDirectory(File classes) {
+        classFileDirectory = classes;
+        return this;
+    }
+
+    /**
+     * defines the project from which the artifacts should be loaded.
+     * The current implementation requires the filter to be set before calling this method.
+     * @param project the maven project
+     * @return this
+     */
+    @Nonnull
+    public ImportPackageBuilder withDependenciesFromProject(@Nonnull MavenProject project) {
+        artifacts = new ArrayList<Artifact>();
+        for (Artifact a : project.getDependencyArtifacts()) {
+            if (!filter.include(a)) {
+                continue;
+            }
+            if (!Artifact.SCOPE_PROVIDED.equals(a.getScope()) && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
+                continue;
+            }
+            if (!"jar".equals(a.getType())) {
+                continue;
+            }
+            artifacts.add(a);
+        }
+        return this;
+    }
+
+    /**
+     * defines if unused packages should be included if no classes exist in the project.
+     * @param includeUnused {@code true} to include unused.
+     * @return this
+     */
+    @Nonnull
+    public ImportPackageBuilder withIncludeUnused(boolean includeUnused) {
+        this.includeUnused = includeUnused;
+        return this;
+    }
+
+    /**
+     * defines the filter for the project artifact
+     * @param filter the filter
+     * @return this
+     */
+    @Nonnull
+    public ImportPackageBuilder withFilter(@Nonnull ArtifactFilter filter) {
+        this.filter = filter;
+        return this;
+    }
+
+    /**
+     * analyzes the imports
+     * @return this
+     * @throws IOException if an error occurrs.
+     */
+    @Nonnull
+    public ImportPackageBuilder analyze() throws IOException {
+        initClassFiles();
+        initAnalyzer();
+        scanClassPath();
+        scanBundles();
+        scanClasses();
+        calculateImportParameters();
+        return this;
+    }
+
+    /**
+     * returns the import parameter header. only available after {@link #analyze()}
+     * @return the parameters
+     */
+    @Nonnull
+    public Map<String, Attrs> getImportParameters() {
+        return importParameters;
+    }
+
+    /**
+     * generates a package report
+     * @return the report
+     */
+    @Nonnull
+    public String createExportPackageReport() {
+        TreeSet<String> unusedBundles = new TreeSet<String>(bundles.keySet());
+        StringBuilder report = new StringBuilder("Export package report:\n\n");
+        List<String> packages = new ArrayList<String>(exported.keySet());
+        Collections.sort(packages);
+        int pad = 18;
+        for (String packageName : packages) {
+            pad = Math.max(pad, packageName.length());
+        }
+        pad += 2;
+
+        report
+                .append(StringUtils.rightPad("Exported packages", pad))
+                .append(StringUtils.rightPad("Uses", 5))
+                .append(StringUtils.rightPad("Version", 10))
+                .append("Dependency\n");
+        report.append(StringUtils.repeat("-", pad + 30)).append("\n");
+        for (String packageName : packages) {
+            PackageInfo info = exported.get(packageName);
+
+            report.append(StringUtils.rightPad(packageName, pad));
+            report.append(StringUtils.rightPad(String.valueOf(info.usedBy.size()), 5));
+            boolean first = true;
+            for (BundleInfo bInfo : info.bundles.values()) {
+                if (first) {
+                    String version = bInfo.packageVersions.get(packageName);
+                    if (StringUtils.isEmpty(version)) {
+                        version = "0.0.0";
+                    }
+                    report.append(StringUtils.rightPad(version, 10));
+                    report.append(bInfo.getId());
+                    first = false;
+                }
+                if (!info.usedBy.isEmpty()) {
+                    unusedBundles.remove(bInfo.getId());
+                }
+            }
+            if (first) {
+                report.append(StringUtils.rightPad("n/a", 10));
+            }
+            report.append("\n");
+        }
+
+        report.append("\n").append(unusedBundles.size()).append(" unused bundles\n");
+        report.append("------------------------------\n");
+        for (String bundleId : unusedBundles) {
+            report.append(bundleId).append("\n");
+        }
+
+        report.append("\nPackages used in the analyzed classes: \n");
+        report.append("------------------------------\n");
+        for (Map.Entry<String, Attrs> e: importParameters.entrySet()) {
+            report.append(e.getKey());
+            try {
+                Processor.printClause(e.getValue(), report);
+            } catch (IOException e1) {
+                throw new IllegalStateException("Internal error while generating report", e1);
+            }
+            report.append("\n");
+        }
+
+        return report.toString();
+    }
+
+    /**
+     * internally scans all the class files.
+     */
+    private void initClassFiles() {
+        if (!classFileDirectory.exists()) {
+            classFiles = Collections.emptyList();
+            return;
+        }
+        DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir(classFileDirectory);
+        scanner.setIncludes(new String[]{"**/*.class"});
+        scanner.scan();
+        String[] paths = scanner.getIncludedFiles();
+        classFiles = new ArrayList<File>(paths.length);
+        for (String path : paths) {
+            File file = new File(path);
+            if (!file.isAbsolute()) {
+                file = new File(classFileDirectory, path);
+            }
+            classFiles.add(file);
+        }
+    }
+
+    /**
+     * Returns the classloader for the analysis. this should exclude the classes of the maven runtime.
+     *
+     * @throws IOException If an error occurs
+     */
+    private ClassLoader getClassLoader() throws IOException,
+            DependencyResolutionRequiredException {
+        List<URL> classPath = new ArrayList<URL>();
+
+        // add output directory to classpath
+        classPath.add(classFileDirectory.toURI().toURL());
+
+        // add artifacts from project
+        for (Artifact a: artifacts) {
+            classPath.add(a.getFile().toURI().toURL());
+        }
+
+        // use our parent as parent, in order to exclude the maven runtime.
+        return new URLClassLoader(classPath.toArray(new URL[classPath.size()]), this.getClass().getClassLoader().getParent());
+    }
+
+    /**
+     * scans the classpath
+     * @throws IOException if an error occurrs.
+     */
+    private void scanClassPath() throws IOException {
+        try {
+            scanResult = new FastClasspathScanner()
+                    .overrideClassLoaders(getClassLoader())
+                    .scan();
+
+        } catch (Exception e) {
+            throw new IOException("Failed to scan the classpath", e);
+        }
+    }
+
+    /**
+     * initializes the bnd analyzer
+     */
+    private void initAnalyzer() {
+        analyzer = new Analyzer();
+    }
+
+    /**
+     * scans all the bundles and initializes their export packages.
+     * @throws IOException if an error occurrs
+     */
+    private void scanBundles() throws IOException {
+        for (Artifact a : artifacts) {
+            BundleInfo info = new BundleInfo(a);
+            bundles.put(info.getId(), info);
+
+            // update the reverse map
+            for (String pkgName : info.packageVersions.keySet()) {
+                PackageInfo pkg = exported.get(pkgName);
+                if (pkg == null) {
+                    pkg = new PackageInfo(pkgName);
+                    exported.put(pkgName, pkg);
+                }
+                pkg.bundles.put(info.getId(), info);
+            }
+        }
+    }
+
+    /**
+     * Registers the package reference from the given class
+     * @param info the class info that references the package
+     * @param pkgName the package that is referenced
+     */
+    private void registerPackageReference(ClassInfo info, String pkgName) {
+        PackageInfo pkgInfo = exported.get(pkgName);
+        if (pkgInfo == null) {
+            pkgInfo = new PackageInfo(pkgName);
+            exported.put(pkgName, pkgInfo);
+        }
+        info.resolved.put(pkgName, pkgInfo);
+        pkgInfo.usedBy.add(info.getName());
+    }
+
+    /**
+     * scans the classes and resolves them against the bundles.
+     * @throws IOException if an error occurrs.
+     */
+    private void scanClasses() throws IOException {
+        for (File file : classFiles) {
+            try {
+                Clazz clazz = new Clazz(analyzer, file.getPath(), new FileResource(file));
+                clazz.parseClassFile();
+                ClassInfo info = new ClassInfo(clazz);
+                classes.put(info.getName(), info);
+
+                String myPackage = getPackageName(info.getName());
+                for (Descriptors.PackageRef ref : clazz.getReferred()) {
+                    String importPkgName = ref.getFQN();
+                    if (!importPkgName.equals(myPackage)) {
+                        registerPackageReference(info, importPkgName);
+                    }
+                }
+
+                // checking for super classes
+                io.github.lukehutch.fastclasspathscanner.scanner.ClassInfo clzInfo = scanResult.getClassNameToClassInfo().get(clazz.getFQN());
+                if (clzInfo != null) {
+                    for (String name: clzInfo.getNamesOfImplementedInterfaces()) {
+                        registerPackageReference(info, getPackageName(name));
+                    }
+                    for (String name: clzInfo.getNamesOfSuperclasses()) {
+                        registerPackageReference(info, getPackageName(name));
+                    }
+                }
+            } catch (Exception e) {
+                throw new IOException("Error while parsing class: " + file.getPath(), e);
+            }
+        }
+    }
+
+    /**
+     * Returns the package name for the given class name
+     * @param className the class name
+     * @return the package name
+     */
+    private static String getPackageName(String className) {
+        return StringUtils.chomp(className, ".");
+    }
+
+    /**
+     * Calculates returns the import parameter header.
+     */
+    private void calculateImportParameters() {
+        importParameters = new TreeMap<String, Attrs>();
+        for (PackageInfo info : exported.values()) {
+            if (!classFiles.isEmpty() && info.usedBy.isEmpty()) {
+                // skip if not used.
+                continue;
+            }
+            if (classFiles.isEmpty() && !includeUnused) {
+                continue;
+            }
+            if (info.bundles.isEmpty()) {
+                // skip if no bundle
+                continue;
+            }
+            // get first version
+            BundleInfo bInfo = info.bundles.values().iterator().next();
+            String version = bInfo.packageVersions.get(info.getName());
+            Attrs options = new Attrs();
+            if (!StringUtils.isEmpty(version)) {
+                options.put(Constants.VERSION_ATTRIBUTE, new aQute.bnd.version.VersionRange("@" + version).toString());
+            }
+            importParameters.put(info.getName(), options);
+        }
+    }
+
+
+    private static class PackageInfo {
+
+        private final String name;
+
+        private final Map<String, BundleInfo> bundles = new HashMap<String, BundleInfo>();
+
+        private final Set<String> usedBy = new HashSet<String>();
+
+        private PackageInfo(String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    private static class BundleInfo {
+
+        private final String id;
+
+        private final Map<String, String> packageVersions = new HashMap<String, String>();
+
+        private BundleInfo(Artifact artifact) throws IOException {
+            id = artifact.getId();
+            JarFile jar = new JarFile(artifact.getFile());
+            Manifest manifest = jar.getManifest();
+            String exportPackages = manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE);
+            if (exportPackages != null) {
+                for (Map.Entry<String, Attrs> entry : new Parameters(exportPackages).entrySet()) {
+                    Attrs options = entry.getValue();
+                    String version = options.getVersion();
+                    packageVersions.put(entry.getKey(), version == null ? "" : version);
+                }
+            } else {
+                // scan the jar and associate the version
+                Enumeration<JarEntry> entries = jar.entries();
+                while (entries.hasMoreElements()) {
+                    JarEntry e = entries.nextElement();
+                    if (e.isDirectory()) {
+                        continue;
+                    }
+                    String path = e.getName();
+                    if (path.endsWith(".class")) {
+                        // skip internal / impl
+                        if (path.contains("/impl/") || path.contains("/internal/")) {
+                            continue;
+                        }
+                        path = StringUtils.chomp(path, "/");
+                        if (path.charAt(0) == '/') {
+                            path = path.substring(1);
+                        }
+                        String packageName = path.replaceAll("/", ".");
+                        packageVersions.put(packageName, "");
+                    }
+                }
+            }
+            jar.close();
+        }
+
+        public String getId() {
+            return id;
+        }
+    }
+
+    private static class ClassInfo {
+
+        private final Clazz clazz;
+
+        private final Map<String, PackageInfo> resolved = new HashMap<String, PackageInfo>();
+
+        private ClassInfo(Clazz clazz) {
+            this.clazz = clazz;
+        }
+
+        public String getName() {
+            return clazz.getFQN();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/IncludeExcludeList.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/IncludeExcludeList.java
new file mode 100644
index 0000000..d9e4d66
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/IncludeExcludeList.java
@@ -0,0 +1,40 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+public class IncludeExcludeList extends ArrayList<String> {
+
+    public boolean add(String entry) {
+        return entry != null && super.add(entry);
+    }
+
+    public void write(PrintWriter pw, String tag) {
+        for (String include: this) {
+            pw.print(Filter.INDENT);
+            pw.print(Filter.INDENT);
+            pw.print('<');
+            pw.print(tag);
+            pw.print(" pattern=\"");
+            pw.print(include);
+            pw.print("\" />");
+            pw.println();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/PackageDependency.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/PackageDependency.java
new file mode 100644
index 0000000..51e2c63
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/PackageDependency.java
@@ -0,0 +1,264 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Implements a package dependency reference.
+ */
+public class PackageDependency {
+
+    /**
+     * An empty dependency array
+     */
+    public static final PackageDependency[] EMPTY = new PackageDependency[0];
+
+    /**
+     * group id of the dependency
+     */
+    private final String groupId;
+
+    /**
+     * name of the dependency
+     */
+    private final String name;
+
+    /**
+     * Version range of the dependency
+     */
+    private final VersionRange range;
+
+    /**
+     * internal string representation
+     */
+    private final String str;
+
+    /**
+     * Creates a new dependency reference.
+     * @param groupId group id
+     * @param name name
+     * @param range version range
+     */
+    public PackageDependency(String groupId, String name, VersionRange range) {
+        if (groupId.startsWith(PackageId.ETC_PACKAGES_PREFIX)) {
+            groupId = groupId.substring(PackageId.ETC_PACKAGES_PREFIX.length());
+        }
+        this.groupId = groupId;
+        this.name = name;
+        this.range = range == null ? VersionRange.INFINITE : range;
+        StringBuilder b = new StringBuilder();
+        if (groupId.length() > 0 || !VersionRange.INFINITE.equals(this.range)) {
+            b.append(groupId);
+            b.append(":");
+        }
+        b.append(name);
+        if (!VersionRange.INFINITE.equals(this.range)) {
+            b.append(":");
+            b.append(range);
+        }
+        this.str = b.toString();
+    }
+
+    /**
+     * Creates a new dependency to the specified package id
+     * @param id package id.
+     */
+    public PackageDependency(PackageId id) {
+        this(id.getGroup(), id.getName(), new VersionRange(id.getVersion()));
+    }
+
+    /**
+     * Returns the group id of the dependency
+     * @return the gorup id
+     */
+    public String getGroupId() {
+        return groupId;
+    }
+
+    /**
+     * Returns the name of the dependency
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the version range
+     * @return the version range
+     */
+    public VersionRange getRange() {
+        return range;
+    }
+
+    /**
+     * Returns the installation path of this dependency
+     * @return the installation path;
+     */
+    public String getPath() {
+        StringBuilder b = new StringBuilder();
+        if (groupId.length() > 0) {
+            if (groupId.charAt(0) != '/') {
+                b.append(PackageId.ETC_PACKAGES_PREFIX);
+            }
+            b.append(groupId);
+            b.append("/");
+        }
+        b.append(name);
+        return b.toString();
+    }
+
+    /**
+     * Checks if the given package id matches this dependency specification.
+     * @param id the package id
+     * @return {@code true} if matches
+     */
+    public boolean matches(PackageId id) {
+        return groupId.equals(id.getGroup())
+                && name.equals(id.getName())
+                && range.isInRange(id.getVersion());
+    }
+
+    /**
+     * Returns a dependency from a string. if the given id is null or an
+     * empty string, {@code null} is returned.
+     * @param str the string
+     * @return the dependency
+     */
+    public static PackageDependency fromString(String str) {
+        if (str == null || str.length() == 0) {
+            return null;
+        }
+        String[] segs = str.split(":");
+        String name;
+        String groupId = "";
+        String range = null;
+        if (segs.length == 1) {
+            name = segs[0];
+            // be backward compatible, respect group in name
+            int idx = name.lastIndexOf('/');
+            if (idx >= 0) {
+                groupId = name.substring(0, idx);
+                name = name.substring(idx + 1);
+            }
+        } else if (segs.length == 2) {
+            groupId = segs[0];
+            name = segs[1];
+            boolean isVersion = true;
+            if (name.length() > 0) {
+                char c = name.charAt(0);
+                isVersion = Character.isDigit(c) || c == '[' || c == ')';
+            }
+            // be backward compatible, respect group in name
+            int idx = name.lastIndexOf('/');
+            if (idx >= 0 && groupId.length() == 0) {
+                groupId = name.substring(0, idx);
+                name = name.substring(idx + 1);
+            } else if ((idx = groupId.lastIndexOf('/')) >=0 && isVersion) {
+                groupId = segs[0].substring(0, idx);
+                name = segs[0].substring(idx + 1);
+                range = segs[1];
+            }
+        } else {
+            groupId = segs[0];
+            name = segs[1];
+            range = segs[2];
+        }
+        return new PackageDependency(groupId, name, range == null ? null : VersionRange.fromString(range));
+    }
+
+    /**
+     * Parses a string serialization of dependency references generated by
+     * {@link #toString(PackageDependency...)})}
+     *
+     * @param str serialized string
+     * @return array of dependency references
+     */
+    public static PackageDependency[] parse(String str) {
+        List<PackageDependency> deps = new ArrayList<PackageDependency>();
+        boolean inRange = false;
+        int start = 0;
+        boolean wasSeg = false;
+        for (int i=0; i<str.length(); i++) {
+            char c = str.charAt(i);
+            if (c == ',') {
+                if (!inRange) {
+                    deps.add(PackageDependency.fromString(str.substring(start, i)));
+                    start = i + 1;
+                }
+            } else if (c == '[' || c == '(') {
+                if (wasSeg) {
+                    inRange = true;
+                }
+            } else if (c == ']' || c == ')') {
+                inRange = false;
+            }
+            wasSeg = c == ':';
+        }
+        if (start < str.length()) {
+            deps.add(PackageDependency.fromString(str.substring(start)));
+        }
+        return deps.toArray(new PackageDependency[deps.size()]);
+    }
+    
+    /**
+     * Returns dependencies from the given strings.
+     * @param str the strings
+     * @return the dependencies
+     */
+    public static PackageDependency[] fromString(String ... str) {
+        PackageDependency[] ret = new PackageDependency[str.length];
+        for (int i=0; i<str.length;i++) {
+            ret[i] = PackageDependency.fromString(str[i]);
+        }
+        return ret;
+    }
+
+    /**
+     * Returns a string representation from given dependencies.
+     * @param deps the dependencies
+     * @return the strings
+     */
+    public static String toString(PackageDependency ... deps) {
+        String delim = "";
+        StringBuilder b = new StringBuilder();
+        for (PackageDependency dep: deps) {
+            b.append(delim).append(dep);
+            delim=",";
+        }
+        return b.toString();
+    }
+
+    @Override
+    public String toString() {
+        return str;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return this == obj ||
+                obj instanceof PackageDependency && str.equals(obj.toString());
+    }
+
+    @Override
+    public int hashCode() {
+        return str.hashCode();
+    }
+
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/PackageId.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/PackageId.java
new file mode 100644
index 0000000..cf1e21c
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/PackageId.java
@@ -0,0 +1,407 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+/**
+ * {@code PackageId} provides the basic metrics for identifying a package.
+ * A package id consists of a group id, a name and a version.
+ * the group is a relative path, eg: "day/cq5/hotfix", the name and the version
+ * can be of any format.
+ */
+public class PackageId implements Comparable<PackageId> {
+
+    public static final String ETC_PACKAGES = "/etc/packages";
+
+    public static final String ETC_PACKAGES_PREFIX = "/etc/packages/";
+
+    public static final PackageId[] EMPTY = new PackageId[0];
+    
+    private final String group;
+
+    private final String name;
+
+    private final Version version;
+
+    private final String str;
+
+    private final boolean fromPath;
+
+    /**
+     * Creates a new package id
+     * @param path path of the package
+     */
+    public PackageId(String path) {
+        fromPath = true;
+        path = path.trim();
+        int idx = path.lastIndexOf('.');
+        if (idx > 0) {
+            String ext = path.substring(idx);
+            if (ext.equalsIgnoreCase(".zip") || ext.equalsIgnoreCase(".jar")) {
+                path = path.substring(0, idx);
+            }
+        }
+        idx = path.lastIndexOf('/');
+        String name;
+        if (idx < 0) {
+            name = path;
+            this.group = "";
+        } else {
+            name = path.substring(idx + 1);
+            String grp = path.substring(0, idx);
+            if (grp.equals(ETC_PACKAGES)) {
+                grp = "";
+            } else if (grp.startsWith(ETC_PACKAGES_PREFIX)) {
+                grp = grp.substring(ETC_PACKAGES_PREFIX.length());
+            } else if (grp.startsWith("/")) {
+                grp = grp.substring(1);
+            }
+            this.group = grp;
+        }
+        // check if name contains a version
+        String[] segs = name.split("-");
+        int i=segs.length-1;
+        while (i>0) {
+            try {
+                // accept numbers < 1000 (hotfix case)
+                if (Integer.parseInt(segs[i]) >= 1000) {
+                    break;
+                }
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+            // check if starts with a letter'
+            if (Character.isJavaIdentifierStart(segs[i].charAt(0))) {
+                // then need a digit
+                if (segs[i].length() == 1 || !Character.isDigit(segs[i].charAt(1)) && !segs[i].equals("SNAPSHOT")) {
+                    break;
+                }
+            }
+            i--;
+        }
+        if (i == segs.length-1) {
+            this.name = name;
+            version = Version.EMPTY;
+        } else {
+            StringBuilder str = new StringBuilder();
+            for (int j = 0; j<= i; j++) {
+                if (j > 0) {
+                    str.append('-');
+                }
+                str.append(segs[j]);
+            }
+            this.name = str.toString();
+            str.setLength(0);
+            for (int j = i+1; j<segs.length; j++) {
+                if (j > i+1) {
+                    str.append('-');
+                }
+                str.append(segs[j]);
+            }
+            this.version = Version.create(str.toString());
+        }
+        this.str = getString(group, this.name, version);
+
+    }
+    /**
+     * Creates a new package id
+     * @param path path of the package
+     * @param version version of the package
+     */
+    public PackageId(String path, String version) {
+        this(path, Version.create(version));
+    }
+
+    /**
+     * Creates a new package id
+     * @param path path of the package
+     * @param version version of the package
+     */
+    public PackageId(String path, Version version) {
+        fromPath = true;
+        path = path.trim();
+        int idx = path.lastIndexOf('.');
+        if (idx > 0) {
+            String ext = path.substring(idx);
+            if (ext.equalsIgnoreCase(".zip") || ext.equalsIgnoreCase(".jar")) {
+                path = path.substring(0, idx);
+            }
+        }
+        if (version != null && path.endsWith('-'+version.toString())) {
+            path = path.substring(0, path.length() - version.toString().length() - 1);
+        }
+        idx = path.lastIndexOf('/');
+        if (idx < 0) {
+            this.name = path;
+            this.group = "";
+        } else {
+            this.name = path.substring(idx + 1);
+            String grp = path.substring(0, idx);
+            if (grp.equals(ETC_PACKAGES)) {
+                grp = "";
+            } else if (grp.startsWith(ETC_PACKAGES_PREFIX)) {
+                grp = grp.substring(ETC_PACKAGES_PREFIX.length());
+            } else if (grp.startsWith("/")) {
+                grp = grp.substring(1);
+            }
+            this.group = grp;
+        }
+        // sanitize version
+        if (version == null || version.toString().length() == 0) {
+            version = Version.EMPTY;
+        }
+        this.version = version;
+        this.str = getString(group, name, version);
+    }
+
+    /**
+     * Creates a new package id
+     * @param group group id
+     * @param name name
+     * @param version version
+     */
+    public PackageId(String group, String name, String version) {
+        this(group, name, Version.create(version));
+    }
+
+    /**
+     * Creates a new package id
+     * @param group group id
+     * @param name name
+     * @param version version
+     */
+    public PackageId(String group, String name, Version version) {
+        fromPath = false;
+        // validate group
+        if (group.equals(ETC_PACKAGES)) {
+            group = "";
+        } else if (group.startsWith(ETC_PACKAGES_PREFIX)) {
+            group = group.substring(ETC_PACKAGES_PREFIX.length());
+        } else if (group.startsWith("/")) {
+            group = group.substring(1);
+        }
+        this.group = group;
+        this.name = name;
+        this.version = version == null ? Version.EMPTY : version;
+        this.str = getString(this.group, name, this.version);
+    }
+
+    /**
+     * Returns a package id from a id string. if the given id is null or an
+     * empty string, {@code null} is returned.
+     * @param str the string
+     * @return the package id
+     */
+    public static PackageId fromString(String str) {
+        if (str == null || str.length() == 0) {
+            return null;
+        }
+        String[] segs = str.split(":");
+        if (segs.length == 1) {
+            return new PackageId("", segs[0], "");
+        } else if (segs.length == 2) {
+            return new PackageId(segs[0], segs[1], "");
+        } else {
+            return new PackageId(segs[0], segs[1], segs[2]);
+        }
+    }
+
+    /**
+     * Returns an array of package id from strings
+     * @param str the strings
+     * @return the array of package ids
+     */
+    public static PackageId[] fromString(String ... str) {
+        PackageId[] ret = new PackageId[str.length];
+        for (int i=0; i<str.length; i++) {
+            ret[i] = PackageId.fromString(str[i]);
+        }
+        return ret;
+    }
+
+    /**
+     * Creates a comma separated list of id strings.
+     * @param packs the ids
+     * @return the string
+     */
+    public static String toString(PackageId ... packs) {
+        String delim = "";
+        StringBuilder b = new StringBuilder();
+        for (PackageId pack: packs) {
+            b.append(delim).append(pack);
+            delim=",";
+        }
+        return b.toString();
+    }
+
+    /**
+     * Returns the path of this package
+     * @return the path of this package
+     * @deprecated use {@link #getInstallationPath()} instead
+     */
+    public String getPath() {
+        return getInstallationPath();
+    }
+
+    /**
+     * Checks if this definition was constructed from a path, rather from a
+     * group and name.
+     * @return {@code true} if constructed from path.
+     */
+    public boolean isFromPath() {
+        return fromPath;
+    }
+
+    /**
+     * Returns the path of this package. please note that since 2.3 this also
+     * includes the version, but never the extension (.zip).
+     *
+     * @return the path of this package
+     */
+    public String getInstallationPath() {
+        StringBuilder b = new StringBuilder(ETC_PACKAGES_PREFIX);
+        if (group.length() > 0) {
+            b.append(group);
+            b.append("/");
+        }
+        b.append(name);
+        if (version.toString().length() > 0) {
+            b.append("-").append(version);
+        }
+        return b.toString();
+    }
+
+    /**
+     * Returns the group id of this package
+     * @return the group id;
+     * @deprecated use {@link #getGroup()} instead.
+     */
+    public String getGroupId() {
+        return group;
+    }
+
+    /**
+     * Returns the group id of this package
+     * @return the group id;
+     */
+    public String getGroup() {
+        return group;
+    }
+
+    /**
+     * Returns the name of this package which is the last segment of the path.
+     * @return the name of this package.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the version of this package or and empty string if n/a.
+     * @return the version of this package
+     */
+    public String getVersionString() {
+        return version.toString();
+    }
+
+    /**
+     * Returns a download name in the form
+     * {@code name [ "-" version ] ".zip"}
+     * @return the download name
+     */
+    public String getDownloadName() {
+        StringBuilder str = new StringBuilder(name);
+        if (version.toString().length() > 0) {
+            str.append("-").append(version);
+        }
+        str.append(".zip");
+        return str.toString();
+    }
+
+    /**
+     * Returns the version of this package or {@code null} if n/a.
+     * @return the version of this package
+     */
+    public Version getVersion() {
+        return version;
+    }
+
+    /**
+     * Returns a string representation of this id
+     */
+    @Override
+    public String toString() {
+        return str;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return this == o ||
+                o instanceof PackageId && str.equals(o.toString());
+
+    }
+
+    @Override
+    public int hashCode() {
+        return str.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     *  
+     * Compares this id with the given one.
+     */
+    public int compareTo(PackageId o) {
+        int comp = group.compareTo(o.getGroup());
+        if (comp != 0) {
+            return comp;
+        }
+        comp = name.compareTo(o.getName());
+        if (comp != 0) {
+            return comp;
+        }
+        return version.compareTo(o.getVersion());
+    }
+
+    /**
+     * Internally get the string representation, colon separated.
+     * @param group group name
+     * @param name name
+     * @param version version
+     * @return string version
+     */
+    private static String getString(String group, String name, Version version) {
+        return getString(group, name, version == null ? "" : version.toString());
+    }
+
+    /**
+     * Internally get the string representation, colon separated.
+     * @param group group name
+     * @param name name
+     * @param version version
+     * @return string version
+     */
+    private static String getString(String group, String name, String version) {
+        StringBuilder b = new StringBuilder();
+        b.append(group).append(':');
+        b.append(name);
+        if (version.length() > 0) {
+            b.append(':').append(version);
+        }
+        return b.toString();
+    }
+
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/SubPackage.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/SubPackage.java
new file mode 100644
index 0000000..4409129
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/SubPackage.java
@@ -0,0 +1,148 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+
+import org.apache.jackrabbit.filevault.maven.packaging.impl.StringFilterSet;
+
+/**
+ * The {@code SubPackage} class represents an subpackage artifact dependency
+ * from the project descriptor. Such a package is declared in
+ * {@code &lt;subPackages&gt;} elements inside the list style
+ * {@code &lt;subPackage&gt;} element as follows:
+ * <pre>
+ * &lt;subPackage&gt;
+ *     &lt;groupId&gt;artifact.groupId.pattern&lt;/groupId&gt;
+ *     &lt;artifactId&gt;artifact.artifactId.pattern&lt;/artifactId&gt;
+ *     &lt;scope&gt;compile&lt;/scope&gt;
+ *     &lt;type&gt;jar&lt;/type&gt;
+ *     &lt;classifier&gt;sources&lt;/classifier&gt;
+ *     &lt;filter&gt;true&lt;/filter&gt;
+ * &lt;/subPackage&gt;
+ * </pre>
+ */
+public class SubPackage {
+
+    /**
+     * A group filter string, consisted of one or several comma separated patterns.
+     */
+    @Parameter
+    private final StringFilterSet groupId = new StringFilterSet();
+
+    /**
+     * A artifact filter string, consisted of one or several comma separated patterns.
+     */
+    @Parameter
+    private final StringFilterSet artifactId = new StringFilterSet();
+
+    @Parameter
+    private ScopeArtifactFilter scope;
+
+    @Parameter
+    private String type;
+
+    @Parameter
+    private String classifier;
+
+    /**
+     * If {@code true} a filter entry will be generated for all embedded artifacts.
+     */
+    @Parameter
+    private boolean filter;
+
+    @Parameter
+    private boolean excludeTransitive;
+
+    public void setGroupId(String groupId) {
+        this.groupId.addEntries(groupId);
+    }
+
+    public void setArtifactId(String artifactId) {
+        this.artifactId.addEntries(artifactId);
+    }
+
+    public void setScope(String scope) {
+        this.scope = new ScopeArtifactFilter(scope);
+    }
+
+    public void setAddFilter(boolean filter) {
+        this.filter = filter;
+    }
+
+    public boolean isFilter() {
+        return filter;
+    }
+
+    public void setExcludeTransitive(boolean excludeTransitive) {
+        this.excludeTransitive = excludeTransitive;
+    }
+
+    public boolean isExcludeTransitive() {
+        return excludeTransitive;
+    }
+
+    public List<Artifact> getMatchingArtifacts(final MavenProject project) {
+
+        // get artifacts depending on whether we exclude transitives or not
+        final Set deps;
+        if (excludeTransitive) {
+            // only direct dependencies, transitives excluded
+            deps = project.getDependencyArtifacts();
+        } else {
+            // all dependencies, transitives included
+            deps = project.getArtifacts();
+        }
+
+        final List<Artifact> matches = new ArrayList<Artifact>();
+        for (Object dep : deps) {
+            final Artifact artifact = (Artifact) dep;
+            if (groupId.contains(artifact.getGroupId())
+                    && artifactId.contains(artifact.getArtifactId())
+                    && (scope == null || scope.include(artifact))
+                    && (type == null || type.equals(artifact.getType()))
+                    && (classifier == null || classifier.equals(artifact.getClassifier()))) {
+                matches.add(artifact);
+            }
+        }
+        return matches;
+    }
+
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Sub Packages: ");
+        if (groupId != null) {
+            builder.append("groupId=").append(groupId).append(",");
+        }
+        if (artifactId != null) {
+            builder.append("artifactId=").append(artifactId).append(",");
+        }
+        if (scope != null) {
+            builder.append("scope=").append(scope).append(",");
+        }
+        builder.append("filter=").append(filter);
+        builder.append(",excludeTransitive=").append(excludeTransitive);
+        return builder.toString();
+    }
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java
new file mode 100644
index 0000000..a166dbb
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java
@@ -0,0 +1,1016 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.annotation.Nonnull;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.archiver.ManifestConfiguration;
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.ArchiveEntry;
+import org.codehaus.plexus.archiver.FileSet;
+import org.codehaus.plexus.util.AbstractScanner;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+
+import aQute.bnd.header.Attrs;
+import aQute.bnd.header.Parameters;
+import aQute.bnd.osgi.Processor;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PackageType;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PathFilterSet;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PlatformNameFormat;
+
+import static org.codehaus.plexus.archiver.util.DefaultFileSet.fileSet;
+
+/**
+ * Build a content package.
+ */
+@Mojo(
+        name = "package",
+        defaultPhase = LifecyclePhase.PACKAGE,
+        requiresDependencyResolution = ResolutionScope.COMPILE
+)
+public class VaultMojo extends AbstractMojo {
+
+    private static final String JCR_ROOT = "jcr_root/";
+
+    private static final String VAULT_DIR = "META-INF/vault";
+
+    public static final String PROPERTIES_FILE = VAULT_DIR + "/properties.xml";
+
+    public static final String FILTER_FILE = VAULT_DIR + "/filter.xml";
+
+    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+
+    private static final String PACKAGE_TYPE = "zip";
+
+    private static final String PACKAGE_EXT = "." + PACKAGE_TYPE;
+
+    public static final String MF_KEY_PACKAGE_TYPE = "Content-Package-Type";
+
+    public static final String MF_KEY_PACKAGE_ID = "Content-Package-Id";
+
+    private static final String MF_KEY_PACKAGE_DEPENDENCIES = "Content-Package-Dependencies";
+
+    public static final String MF_KEY_PACKAGE_ROOTS = "Content-Package-Roots";
+
+    private static final String MF_KEY_PACKAGE_DESC = "Content-Package-Description";
+
+    private static final String MF_KEY_IMPORT_PACKAGE = "Import-Package";
+
+    @Component
+    private ArtifactHandlerManager artifactHandlerManager;
+
+    /**
+     * The Maven project.
+     */
+    @Parameter(property = "project", readonly = true, required = true)
+    private MavenProject project;
+
+    /**
+     * The directory containing the content to be packaged up into the content
+     * package.
+     *
+     * This property is deprecated; use jcrRootSourceDirectory instead.
+     */
+    @Deprecated
+    @Parameter
+    private File builtContentDirectory;
+
+    /**
+     * The directory that contains the jcr_root of the content. Multiple directories can be specified as a comma separated list,
+     * which will act as a search path and cause the plugin to look for the first existing directory.
+     */
+    @Parameter(
+            property = "vault.jcrRootSourceDirectory",
+            required = true,
+            defaultValue =
+                    "${project.basedir}/jcr_root," +
+                    "${project.basedir}/src/main/jcr_root," +
+                    "${project.basedir}/src/main/content/jcr_root," +
+                    "${project.basedir}/src/content/jcr_root," +
+                    "${project.build.outputDirectory}"
+    )
+    private File[] jcrRootSourceDirectory;
+
+    /**
+     * The directory containing the compiled classes to use to import analysis.
+     */
+    @Parameter(
+            defaultValue = "${project.build.outputDirectory}",
+            required = true)
+    private File classesDirectory;
+
+    /**
+     * The name of the generated package ZIP file without the ".zip" file
+     * extension.
+     */
+    @Parameter(
+            property = "vault.finalName",
+            defaultValue = "${project.build.finalName}",
+            required = true)
+    private String finalName;
+
+    /**
+     * Directory in which the built content package will be output.
+     */
+    @Parameter(
+            defaultValue="${project.build.directory}",
+            required = true)
+    private File outputDirectory;
+
+    /**
+     * Optional file that specifies the source of the workspace filter. The filters specified in the configuration
+     * and injected via emebedds or subpackages are merged into it.
+     */
+    @Parameter
+    private File filterSource;
+
+    /**
+     * The directory containing the content to be packaged up into the content
+     * package.
+     */
+    @Parameter(
+            defaultValue = "${project.build.directory}/vault-work",
+            required = true)
+    private File workDirectory;
+
+    /**
+     * The archive configuration to use. See <a
+     * href="http://maven.apache.org/shared/maven-archiver/index.html">the
+     * documentation for Maven Archiver</a>.
+     */
+    @Parameter
+    private MavenArchiveConfiguration archive;
+
+    /**
+     * Adds a path prefix to all resources useful for shallower source trees.
+     */
+    @Parameter(property = "vault.prefix")
+    private String prefix;
+
+    /**
+     * The groupId used for the generated content package. This will be part of
+     * the target installation path of the content package.
+     */
+    @Parameter(
+            property = "vault.group",
+            defaultValue="${project.groupId}",
+            required = true)
+    private String group;
+
+    /**
+     * The name of the content package
+     */
+    @Parameter(
+            property = "vault.name",
+            defaultValue="${project.artifactId}",
+            required = true)
+    private String name;
+
+    /**
+     * The version of the content package.
+     */
+    @Parameter(
+            property = "vault.version",
+            defaultValue = "${project.version}",
+            required = true)
+    private String version;
+
+    /**
+     * Defines whether the package requires root. This will become the
+     * {@code requiresRoot} property of the properties.xml file.
+     */
+    @Parameter(
+            property = "vault.requiresRoot",
+            defaultValue="false",
+            required = true)
+    private boolean requiresRoot;
+
+    /**
+     * Defines whether the package is allowed to contain index definitions. This will become the
+     * {@code allowIndexDefinitions} property of the properties.xml file.
+     */
+    @Parameter(
+            property = "vault.allowIndexDefinitions",
+            defaultValue="false",
+            required = true)
+    private boolean allowIndexDefinitions;
+
+    /**
+     * Controls if errors during dependency validation should fail the build.
+     */
+    @Parameter(
+            property = "vault.failOnDependencyErrors",
+            defaultValue="true",
+            required = true)
+    private boolean failOnDependencyErrors;
+
+    /**
+     * Controls if empty workspace filter fails the build.
+     */
+    @Parameter(
+            property = "vault.failOnEmptyFilter",
+            defaultValue="true",
+            required = true)
+    private boolean failOnEmptyFilter;
+
+
+    /**
+     * The file name patterns to exclude in addition to the ones listed in 
+     * {@link AbstractScanner#DEFAULTEXCLUDES}. The format of each pattern is described in {@link DirectoryScanner}.
+     */
+    @Parameter(property = "vault.excludes",
+               defaultValue="**/.vlt,**/.vltignore,**/.DS_Store",
+               required = true)
+    private String[] excludes;
+
+    /**
+     * Defines the path under which the embedded bundles are placed. defaults to '/apps/bundles/install'
+     */
+    @Parameter(property = "vault.embeddedTarget")
+    private String embeddedTarget;
+
+    /**
+     * list of embedded bundles
+     */
+    @Parameter
+    private Embedded[] embeddeds = new Embedded[0];
+
+    /**
+     * Defines whether to fail the build when an embedded artifact is not
+     * found in the project's dependencies
+     */
+    @Parameter(property = "vault.failOnMissingEmbed", defaultValue = "false", required = true)
+    private boolean failOnMissingEmbed;
+
+    /**
+     * Defines the content package type. this is either 'application', 'content', 'container' or 'mixed'.
+     * If omitted, it is calculated automatically based on filter definitions. certain package types imply restrictions,
+     * for example, 'application' and 'content' packages are not allowed to contain sub packages or embedded bundles.
+     */
+    @Parameter(property = "vault.packageType")
+    private PackageType packageType;
+
+    /**
+     * Sets the package type.
+     * @param type the string representation of the package type
+     * @throws MojoFailureException if an error occurrs
+     */
+    public void setPackageType(String type) throws MojoFailureException {
+        try {
+            packageType = PackageType.valueOf(type.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            throw new MojoFailureException("Invalid package type specified: " + type +".\n" +
+                    "Must be empty or one of 'application', 'content', 'container', 'mixed'");
+        }
+
+    }
+
+    /**
+     * Defines additional bundle dependency via the osgi import-package entry in the manifest.
+     */
+    @Parameter(
+            property = "vault.importPackage",
+            defaultValue =
+                    // exclude HTL compiler packages as they are never real dependencies of the content
+                    "-org.apache.sling.scripting.sightly.compiler.expression.nodes," +
+                    "-org.apache.sling.scripting.sightly.java.compiler," +
+                    "-org.apache.sling.scripting.sightly.render"
+    )
+    private String importPackage;
+
+    /**
+     * Defines the content of the filter.xml file
+     */
+    @Parameter
+    private final DefaultWorkspaceFilter filters = new DefaultWorkspaceFilter();
+
+    /**
+     * Defines the list of dependencies
+     */
+    @Parameter
+    private Dependency[] dependencies = new Dependency[0];
+
+    /**
+     * Defines the packages that define the repository structure
+     */
+    @Parameter
+    private Dependency[] repositoryStructurePackages = new Dependency[0];
+
+    /**
+     * computed dependency string
+     * @see #computeDependencies()
+     */
+    private String dependenciesString;
+
+    /**
+     * Defines the list of sub packages.
+     */
+    @Parameter
+    private SubPackage[] subPackages = new SubPackage[0];
+
+    /**
+     * File to store the generated manifest snippet.
+     */
+    @Parameter(property = "vault.generatedImportPackage", defaultValue = "${project.build.directory}/vault-generated-import.txt")
+    private File generatedImportPackage;
+
+    /**
+     * Specifies additional properties to be set in the properties.xml file.
+     * These properties cannot overwrite the following predefined properties:
+     * <p>
+     * <table>
+     * <tr><td>group</td><td>Use <i>group</i> parameter to set</td></tr>
+     * <tr><td>name</td><td>Use <i>name</i> parameter to set</td></tr>
+     * <tr><td>version</td><td>Use <i>version</i> parameter to set</td></tr>
+     * <tr><td>groupId</td><td><i>groupId</i> of the Maven project descriptor</td></tr>
+     * <tr><td>artifactId</td><td><i>artifactId</i> of the Maven project descriptor</td></tr>
+     * <tr><td>dependencies</td><td>Use <i>dependencies</i> parameter to set</td></tr>
+     * <tr><td>createdBy</td><td>The value of the <i>user.name</i> system property</td></tr>
+     * <tr><td>created</td><td>The current system time</td></tr>
+     * <tr><td>requiresRoot</td><td>Use <i>requiresRoot</i> parameter to set</td></tr>
+     * <tr><td>allowIndexDefinitions</td><td>Use <i>allowIndexDefinitions</i> parameter to set</td></tr>
+     * <tr><td>packagePath</td><td>Automatically generated from the group and package name</td></tr>
+     * <tr><td>packageType</td><td>Set via the package type parameter</td></tr>
+     * </table>
+     */
+    @Parameter
+    private final Properties properties = new Properties();
+
+    /**
+     * Creates a {@link FileSet} for the archiver
+     * @param directory the directory
+     * @param prefix the prefix
+     * @return the fileset
+     */
+    @Nonnull
+    private FileSet createFileSet(@Nonnull File directory, @Nonnull String prefix) {
+        return fileSet(directory)
+                .prefixed(prefix)
+                .includeExclude(null, excludes)
+                .includeEmptyDirs(true);
+    }
+
+    /**
+     * Executes this mojo
+     */
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (prefix == null) {
+            prefix = "";
+        } else if (!prefix.endsWith("/")) {
+            prefix += "/";
+        }
+
+        final File vaultDir = new File(workDirectory, VAULT_DIR);
+        final File finalFile = new File(outputDirectory, finalName + PACKAGE_EXT);
+
+        try {
+            vaultDir.mkdirs();
+
+            Map<String, File> embeddedFiles = copyEmbeddeds();
+            embeddedFiles.putAll(copySubPackages());
+
+            computePackageFilters(vaultDir);
+            validatePackageType();
+            computeImportPackage();
+            computeDependencies();
+            if (packageType == PackageType.APPLICATION) {
+                validateDependencies();
+            } else {
+                getLog().info("Ignoring dependency validation due to non-application package type: " + packageType);
+            }
+
+            final Properties vaultProperties = computeProperties();
+            final FileOutputStream fos = new FileOutputStream(new File(vaultDir, "properties.xml"));
+            vaultProperties.storeToXML(fos, project.getName());
+
+            copyFile("/vault/config.xml", new File(vaultDir, "config.xml"));
+            copyFile("/vault/settings.xml", new File(vaultDir, "settings.xml"));
+
+            ContentPackageArchiver contentPackageArchiver = new ContentPackageArchiver();
+            contentPackageArchiver.setIncludeEmptyDirs(true);
+            contentPackageArchiver.addFileSet(createFileSet(workDirectory, ""));
+
+            // find the source directory
+            File jcrSourceDirectory = null;
+            if (builtContentDirectory != null) {
+                getLog().warn("The 'builtContentDirectory' is deprecated. Please use the new 'jcrRootSourceDirectory' instead.");
+                jcrSourceDirectory = builtContentDirectory;
+            } else {
+                for (File dir: jcrRootSourceDirectory) {
+                    if (dir.exists() && dir.isDirectory()) {
+                        jcrSourceDirectory = dir;
+                        break;
+                    }
+                }
+            }
+            if (jcrSourceDirectory != null) {
+                getLog().info("packaging content from " + jcrSourceDirectory.getPath());
+            }
+
+
+            // include content from build only if it exists
+            if (jcrSourceDirectory != null && jcrSourceDirectory.exists()) {
+                // See GRANITE-16348
+                // we want to build a list of all the root directories in the order they were specified in the filter
+                // but ignore the roots that don't point to a directory
+                List<PathFilterSet> filterSets = filters.getFilterSets();
+                if (filterSets.isEmpty()) {
+                    contentPackageArchiver.addFileSet(createFileSet(jcrSourceDirectory, FileUtils.normalize(JCR_ROOT + prefix)));
+                } else {
+                    for (PathFilterSet filterSet : filterSets) {
+                        String relPath = PlatformNameFormat.getPlatformPath(filterSet.getRoot());
+                        String rootPath = FileUtils.normalize(JCR_ROOT + prefix + relPath);
+
+                        // CQ-4204625 skip embedded files, will be added later in the proper way
+                        if (embeddedFiles.containsKey(rootPath)) {
+                            continue;
+                        }
+
+                        // check for full coverage aggregate
+                        File fullCoverage = new File(jcrSourceDirectory, relPath + ".xml");
+                        if (fullCoverage.isFile()) {
+                            rootPath = FileUtils.normalize(JCR_ROOT + prefix + relPath + ".xml");
+                            contentPackageArchiver.addFile(fullCoverage, rootPath);
+                            continue;
+                        }
+
+                        File rootDirectory = new File(jcrSourceDirectory, relPath);
+
+                        // traverse the ancestors until we find a existing directory (see CQ-4204625)
+                        while ((!rootDirectory.exists() || !rootDirectory.isDirectory())
+                                && !jcrSourceDirectory.equals(rootDirectory)) {
+                            rootDirectory = rootDirectory.getParentFile();
+                            relPath = StringUtils.chomp(relPath, "/");
+                        }
+
+                        if (!jcrSourceDirectory.equals(rootDirectory)) {
+                            rootPath = FileUtils.normalize(JCR_ROOT + prefix + relPath);
+                            contentPackageArchiver.addFileSet(createFileSet(rootDirectory, rootPath + "/"));
+                        }
+                    }
+                }
+            }
+
+            for (Map.Entry<String, File> entry : embeddedFiles.entrySet()) {
+                contentPackageArchiver.addFile(entry.getValue(), entry.getKey());
+            }
+
+            //NPR-14102 - Automated check for index definition
+            if (!allowIndexDefinitions) {
+                FileValidator fileValidator = new FileValidator();
+                getLog().info("Scanning files for oak index definitions.");
+                for (ArchiveEntry entry: contentPackageArchiver.getFiles().values()) {
+                    if (entry.getType() == ArchiveEntry.FILE) {
+                        InputStream in = null;
+                        try {
+                            in = entry.getInputStream();
+                            fileValidator.lookupIndexDefinitionInArtifact(in, entry.getName());
+                        } finally {
+                            IOUtils.closeQuietly(in);
+                        }
+                    }
+                }
+                if (fileValidator.isContainingIndexDef) {
+                    getLog().error(fileValidator.getMessageWithPathsOfIndexDef());
+                    throw new MojoExecutionException("Package should not contain index definitions, because 'allowIndexDefinitions=false'.");
+                }
+            }
+
+            MavenArchiver mavenArchiver = new MavenArchiver();
+            mavenArchiver.setArchiver(contentPackageArchiver);
+            mavenArchiver.setOutputFile(finalFile);
+            mavenArchiver.createArchive(null, project, getMavenArchiveConfiguration(vaultProperties));
+
+            // set the file for the project's artifact and ensure the
+            // artifact is correctly handled with the "zip" handler
+            // (workaround for MNG-1682)
+            final Artifact projectArtifact = project.getArtifact();
+            projectArtifact.setFile(finalFile);
+            projectArtifact.setArtifactHandler(artifactHandlerManager.getArtifactHandler(PACKAGE_TYPE));
+
+        } catch (Exception e) {
+            throw new MojoExecutionException(e.toString(), e);
+        }
+    }
+
+    /**
+     * Computes the package filters.
+     *
+     * Requirements:
+     * - backward compatibility: if a filter.xml is copied to vault-work with the resource plugin, then it should still "work" correctly.
+     * - if there are any comments in the original filter source, they should not get lost, if possible
+     * - if there are filters specified in the pom and in a filter source, they should get merged.
+     * - if the prefix property is set, it should be used if no filter is set.
+     * - if both, a inline filter and a implicit filter is present, the build fails.
+     * - re-run the package goal w/o cleaning the target first must work
+     *
+     * @throws IOException if an I/O error occurs
+     * @throws MojoExecutionException if the build fails
+     */
+    private void computePackageFilters(File vaultMetaDir) throws IOException, MojoExecutionException {
+        // backward compatibility: if implicit filter exists, use it. but check for conflicts
+        File filterFile = new File(vaultMetaDir, "filter.xml");
+        if (filterFile.exists() && filterFile.lastModified() != 0) {
+            // if both, a inline filter and a implicit filter is present, the build fails.
+            if (!filters.getFilterSets().isEmpty()) {
+                getLog().error("Refuse to merge inline filters and non-sourced filter.xml. If this is intended, specify the filter.xml via the 'filterSource' property.");
+                throw new MojoExecutionException("conflicting filters.");
+            }
+            // load filters for further processing
+            filters.load(filterFile);
+
+            getLog().warn("The project is using a filter.xml provided via the resource plugin.");
+            getLog().warn("This is deprecated and might no longer be supported in future versions.");
+            getLog().warn("Use the 'filterSource' property to specify the filter or use inline filters.");
+            return;
+        }
+
+        // if last modified of vault-work/META-INF/vault/filter.xml == 0 -> delete it
+        if (filterFile.exists() && filterFile.lastModified() == 0) {
+            try {
+                Files.delete(filterFile.toPath());
+            } catch (IOException e) {
+                getLog().error("Unable to delete previously generated filter.xml. re-run the goals with a clean setup.");
+                throw new MojoExecutionException("Unable to delete file.", e);
+            }
+        }
+
+        // if filterSource exists, read the filters into sourceFilters
+        DefaultWorkspaceFilter sourceFilters = new DefaultWorkspaceFilter();
+        if (filterSource != null && filterSource.exists()) {
+            getLog().info("Loading filter from " + filterSource.getPath());
+            sourceFilters.load(filterSource);
+            if (!filters.getFilterSets().isEmpty()) {
+                getLog().info("Merging inline filters.");
+                sourceFilters.merge(filters);
+            }
+            filters.getFilterSets().clear();
+            filters.getFilterSets().addAll(sourceFilters.getFilterSets());
+
+            // reset source filters for later. this looks a bit complicated but is needed to keep the same
+            // filter order as in previous versions
+            sourceFilters = new DefaultWorkspaceFilter();
+            sourceFilters.load(filterSource);
+            sourceFilters.generateSource();
+        }
+
+        // if the prefix property is set, it should be used if no filter is set
+        if (filters.getFilterSets().isEmpty() && prefix.length() > 0) {
+            addWorkspaceFilter(prefix);
+        }
+
+        // if no filter is defined at all, fail
+        if (filters.getFilterSets().isEmpty()) {
+            if (failOnEmptyFilter) {
+                final String msg = "No workspace filter defined (failOnEmptyFilter=true)";
+                getLog().error(msg);
+                throw new MojoExecutionException(msg);
+            } else {
+                getLog().warn("No workspace filter defined. Package import might have unexpected results.");
+            }
+        }
+
+        // if the source filters and the generated filters are the same, copy the source file to retain the comments
+        if (filterSource != null && sourceFilters.getSourceAsString().equals(filters.getSourceAsString())) {
+            FileUtils.copyFile(filterSource, filterFile);
+        } else {
+            // generate xml and write to filter.xml
+            getLog().info("Generating filter.xml from plugin configuration");
+            FileUtils.fileWrite(filterFile.getAbsolutePath(), filters.getSourceAsString());
+        }
+
+        // update the last modified time of filter.xml to for generated filters
+        if (!filterFile.setLastModified(0)) {
+            getLog().warn("Unable to set last modified of filters file. make sure to clean the project before next run.");
+        }
+    }
+    /**
+     * Computes the dependency string.
+     */
+    private void computeDependencies() throws IOException {
+        if (dependencies.length > 0) {
+            dependenciesString = PackageDependency.toString(Dependency.resolve(project, getLog(), dependencies));
+        }
+        Dependency.resolve(project, getLog(), repositoryStructurePackages);
+    }
+
+    /**
+     * Checks if the filter roots of this package are covered by the dependencies and also checks for colliding roots
+     * in the dependencies.
+     */
+    private void validateDependencies() throws MojoExecutionException {
+        List<String> errors = new DependencyValidator()
+                .addDependencies(dependencies)
+                .addDependencies(repositoryStructurePackages)
+                .setFilters(filters)
+                .validate()
+                .getErrors();
+
+        if (errors.size() > 0) {
+            String msg = String.format("%d error(s) detected during dependency analysis.", errors.size());
+            if (failOnDependencyErrors) {
+                getLog().error(msg);
+                for (String error: errors) {
+                    getLog().error(error);
+                }
+                throw new MojoExecutionException(msg);
+            }
+            getLog().warn(msg);
+            for (String error: errors) {
+                getLog().warn(error);
+            }
+        } else {
+            getLog().info("All dependencies satisfied.");
+        }
+    }
+
+    /**
+     * Computes the import-package definition from the given bundles if not provided by the project.
+     */
+    private void computeImportPackage() throws IOException {
+        TreeMap<String, Attrs> importParams = new TreeMap<String, Attrs>();
+        if (generatedImportPackage.exists()) {
+            String importPackageStr = FileUtils.fileRead(generatedImportPackage);
+            if (importPackageStr.length() > 0) {
+                importParams.putAll(new Parameters(importPackageStr));
+            }
+        }
+
+        // override computed patterns
+        if (importPackage != null) {
+            getLog().debug("merging analyzer-packages with:\n" + importPackage + "\n");
+            for (Map.Entry<String, Attrs> entry : new Parameters(importPackage).entrySet()) {
+                boolean delete = false;
+                String pkg = entry.getKey();
+                if ("-*".equals(pkg)) {
+                    importParams.clear();
+                    continue;
+                }
+                if (pkg.charAt(0) == '-') {
+                    pkg = pkg.substring(1);
+                    delete = true;
+                }
+                if (pkg.endsWith("*")) {
+                    String pkgDot = pkg.substring(0, pkg.length() - 1);
+                    if (!pkgDot.endsWith(".")) {
+                        // matches both, the packages and sub packages
+                        pkg = pkgDot;
+                        pkgDot = pkg + ".";
+                    }
+                    Iterator<Map.Entry<String, Attrs>> iter = importParams.entrySet().iterator();
+                    while (iter.hasNext()) {
+                        Map.Entry<String, Attrs> e = iter.next();
+                        String pkgName = e.getKey();
+                        if (pkgName.equals(pkg) || pkgName.startsWith(pkgDot)) {
+                            if (delete) {
+                                iter.remove();
+                            } else {
+                                e.setValue(entry.getValue());
+                            }
+                        }
+                    }
+                } else {
+                    if (delete) {
+                        importParams.remove(pkg);
+                    } else {
+                        importParams.put(pkg, entry.getValue());
+                    }
+                }
+            }
+        }
+        importPackage = Processor.printClauses(importParams);
+
+        if (!importPackage.isEmpty()) {
+            getLog().info("Merged detected packages from analyzer with 'importPackage':");
+            for (Map.Entry<String, Attrs> e: importParams.entrySet()) {
+                StringBuilder report = new StringBuilder();
+                report.append("  ").append(e.getKey());
+                try {
+                    Processor.printClause(e.getValue(), report);
+                } catch (IOException e1) {
+                    throw new IllegalStateException("Internal error while generating report", e1);
+                }
+                getLog().info(report);
+            }
+            getLog().info("");
+        }
+    }
+
+    private MavenArchiveConfiguration getMavenArchiveConfiguration(Properties vaultProperties) throws IOException {
+        if (archive == null) {
+            archive = new MavenArchiveConfiguration();
+            archive.setManifest(new ManifestConfiguration());
+
+            archive.setAddMavenDescriptor(true);
+            archive.setCompress(true);
+            archive.setIndex(false);
+            archive.getManifest().setAddDefaultSpecificationEntries(false);
+            archive.getManifest().setAddDefaultImplementationEntries(true);
+
+            PackageId id = new PackageId(group, name, version);
+            archive.addManifestEntry(MF_KEY_PACKAGE_TYPE, packageType.name().toLowerCase());
+            archive.addManifestEntry(MF_KEY_PACKAGE_ID, id.toString());
+            archive.addManifestEntry(MF_KEY_PACKAGE_DESC, vaultProperties.getProperty("description", ""));
+            if (dependenciesString != null && dependenciesString.length() > 0) {
+                archive.addManifestEntry(MF_KEY_PACKAGE_DEPENDENCIES, dependenciesString);
+            }
+            // be sure to avoid duplicates
+            Set<String> rts = new TreeSet<String>();
+            for (PathFilterSet p: filters.getFilterSets()) {
+                rts.add(p.getRoot());
+            }
+            String[] roots = rts.toArray(new String[rts.size()]);
+            Arrays.sort(roots);
+            archive.addManifestEntry(MF_KEY_PACKAGE_ROOTS, StringUtils.join(roots, ","));
+
+            if (StringUtils.isNotEmpty(importPackage)) {
+                archive.addManifestEntry(MF_KEY_IMPORT_PACKAGE, StringUtils.deleteWhitespace(importPackage));
+            }
+        }
+
+        return archive;
+    }
+
+    private Properties computeProperties() {
+        final Properties props = new Properties();
+
+        // find the description of the content package (bug #30546)
+        // this is allowed to be overwritten by the properties map (GRANITE-1527)
+        String description = project.getDescription();
+        if (description == null) {
+            description = project.getName();
+            if (description == null) {
+                description = project.getArtifactId();
+            }
+        }
+        props.put("description", description);
+
+        // add all user defined properties
+        // before the rest of the properties to prevent user
+        // overwriting of predefined properties
+        // (see JavaDoc of properties field for list)
+
+        // but make sure, that we don't have null values in there
+        for (Object o : properties.keySet()) {
+            if (properties.get(o) == null) {
+                properties.put(o, "");
+            }
+        }
+
+        props.putAll(properties);
+
+        // package descriptor properties
+        props.put("group", group);
+        props.put("name", name);
+        props.put("version", version);
+
+        // maven artifact identification
+        props.put("groupId", project.getGroupId());
+        props.put("artifactId", project.getArtifactId());
+
+        // dependencies
+        if (dependenciesString != null && dependenciesString.length() > 0) {
+            props.put("dependencies", dependenciesString);
+        }
+
+        // creation stamp
+        if (!props.containsKey("createdBy")) {
+            props.put("createdBy", System.getProperty("user.name"));
+        }
+        props.put("created", DATE_FORMAT.format(new Date()));
+
+        // configurable properties
+        props.put("requiresRoot", String.valueOf(requiresRoot));
+        props.put("allowIndexDefinitions", String.valueOf(allowIndexDefinitions));
+        props.put("packageType", packageType.name().toLowerCase());
+        return props;
+    }
+
+    private void copyFile(String source, File target) throws IOException {
+
+        // nothing to do if the file exists
+        if (target.exists()) {
+            return;
+        }
+
+        target.getParentFile().mkdirs();
+
+        InputStream ins = getClass().getResourceAsStream(source);
+        if (ins != null) {
+            OutputStream out = null;
+            try {
+                out = new FileOutputStream(target);
+                IOUtil.copy(ins, out);
+            } finally {
+                IOUtil.close(ins);
+                IOUtil.close(out);
+            }
+        }
+    }
+
+    private Map<String, File> copyEmbeddeds() throws IOException, MojoFailureException {
+        Map<String, File> fileMap = new HashMap<String, File>();
+        for (Embedded emb : embeddeds) {
+            final List<Artifact> artifacts = emb.getMatchingArtifacts(project);
+            if (artifacts.isEmpty()) {
+                if (failOnMissingEmbed) {
+                    throw new MojoFailureException("Embedded artifact specified " + emb + ", but no matching dependency artifact found. Add the missing dependency or fix the embed definition.");
+                } else {
+                    getLog().warn("No matching artifacts for " + emb);
+                    continue;
+                }
+            }
+            if (emb.getDestFileName() != null && artifacts.size() > 1) {
+                getLog().warn("destFileName defined but several artifacts match for " + emb);
+            }
+
+            String targetPath = emb.getTarget();
+            if (targetPath == null) {
+                targetPath = embeddedTarget;
+                if (targetPath == null) {
+                    final String loc = (prefix.length() == 0)
+                            ? "/apps/"
+                            : prefix;
+                    targetPath = loc + "bundles/install/";
+                    getLog().info("No target path set on " + emb + "; assuming default " + targetPath);
+                }
+            }
+            targetPath = makeAbsolutePath(targetPath);
+
+            targetPath = JCR_ROOT + targetPath;
+            targetPath = FileUtils.normalize(targetPath);
+            if (!targetPath.endsWith("/")) {
+                targetPath += "/";
+            }
+
+            getLog().info("Embedding --- " + emb + " ---");
+            for (final Artifact artifact : artifacts) {
+                final File source = artifact.getFile();
+                String destFileName = emb.getDestFileName();
+
+                // todo: add support for patterns
+                if (destFileName == null) {
+                    destFileName = source.getName();
+                }
+                final String targetPathName = targetPath + destFileName;
+                final String targetNodePathName = targetPathName.substring(JCR_ROOT.length() - 1);
+
+                fileMap.put(targetPathName, source);
+                getLog().info(String.format("Embedding %s (from %s) -> %s", artifact.getId(), source.getAbsolutePath(), targetPathName));
+
+                if (emb.isFilter()) {
+                    addWorkspaceFilter(targetNodePathName);
+                }
+            }
+        }
+        return fileMap;
+    }
+
+    private Map<String, File> copySubPackages() throws IOException {
+        Map<String, File> fileMap = new HashMap<String, File>();
+        for (SubPackage pack : subPackages) {
+            final List<Artifact> artifacts = pack.getMatchingArtifacts(project);
+            if (artifacts.isEmpty()) {
+                getLog().warn("No matching artifacts for " + pack);
+                continue;
+            }
+
+            // get the package path
+            getLog().info("Embedding --- " + pack + " ---");
+            for (Artifact artifact : artifacts) {
+                final File source = artifact.getFile();
+
+                // load properties
+                ZipFile zip = null;
+                InputStream in = null;
+                Properties props = new Properties();
+                try {
+                    zip = new ZipFile(source, ZipFile.OPEN_READ);
+                    ZipEntry e = zip.getEntry("META-INF/vault/properties.xml");
+                    if (e == null) {
+                        getLog().error("Package does not contain properties.xml");
+                        throw new IOException("properties.xml missing");
+                    }
+                    in = zip.getInputStream(e);
+                    props.loadFromXML(in);
+                } finally {
+                    IOUtil.close(in);
+                    if (zip != null) {
+                        zip.close();
+                    }
+                }
+                PackageId pid = new PackageId(
+                        props.getProperty("group"),
+                        props.getProperty("name"),
+                        props.getProperty("version")
+                );
+                final String targetNodePathName = pid.getInstallationPath() + ".zip";
+                final String targetPathName = "jcr_root" + targetNodePathName;
+
+                fileMap.put(targetPathName, source);
+                getLog().info("Embedding " + artifact.getId() + " -> " + targetPathName);
+                if (pack.isFilter()) {
+                    addWorkspaceFilter(targetNodePathName);
+                }
+            }
+        }
+        return fileMap;
+    }
+
+    private void addWorkspaceFilter(final String filterRoot) {
+        filters.add(new PathFilterSet(filterRoot));
+    }
+
+    private String makeAbsolutePath(final String relPath) {
+        final String absPath;
+        if (!relPath.startsWith("/")) {
+            absPath = ((prefix.length() == 0) ? "/" : prefix) + relPath;
+            getLog().info("Relative path resolved to " + absPath);
+        } else {
+            absPath = relPath;
+        }
+
+        return absPath;
+    }
+
+    private void validatePackageType() throws MojoFailureException {
+        if (packageType == null) {
+            // auto detect...
+            boolean hasApps = false;
+            boolean hasOther = false;
+            for (PathFilterSet p: filters.getFilterSets()) {
+                if (p.isCleanUp()) {
+                    continue;
+                }
+                String root = p.getRoot();
+                if ("/apps".equals(root) || root.startsWith("/apps/") || "/libs".equals(root) || root.startsWith("/libs/")) {
+                    hasApps = true;
+                } else {
+                    hasOther = true;
+                }
+            }
+            if (hasApps && !hasOther) {
+                packageType = PackageType.APPLICATION;
+            } else if (hasOther && !hasApps) {
+                packageType = PackageType.CONTENT;
+            } else {
+                packageType = PackageType.MIXED;
+            }
+        }
+    }
+
+}
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Version.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Version.java
new file mode 100644
index 0000000..72b56ac
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Version.java
@@ -0,0 +1,182 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+/**
+ * Implements a package version.
+ */
+public class Version implements Comparable<Version> {
+
+    /**
+     * The empty version
+     */
+    public static final Version EMPTY = new Version("", new String[0]);
+
+    /**
+     * internal string representation
+     */
+    private final String str;
+
+    /**
+     * All segments of this version
+     */
+    private final String[] segments;
+
+    /**
+     * Constructs a new version from the given string.
+     * @param str the version string.
+     * @deprecated use {@link Version#create(String)} instead.
+     */
+    public Version(String str) {
+        this(str, str.split("\\."));
+    }
+
+    /**
+     * Creates a new version from the given string.
+     * @param str the version string.
+     * @return the new version or {@link Version#EMPTY} if {@code str} is an empty string.
+     */
+    public static Version create(String str) {
+        if (str == null || str.length() == 0) {
+            return Version.EMPTY;
+        }else {
+            return new Version(str, str.split("\\."));
+        }
+    }
+
+    /**
+     * Creates a new version from version segments
+     * @param segments version segments
+     * @return the new version or {@link Version#EMPTY} if {@code segments} is empty.
+     */
+    public static Version create(String[] segments) {
+        if (segments == null || segments.length == 0) {
+            return Version.EMPTY;
+        } else {
+            StringBuilder b = new StringBuilder();
+            String delim = "";
+            for (String s:segments) {
+                b.append(delim);
+                b.append(s);
+                delim=".";
+            }
+            return new Version(b.toString(), segments);
+        }
+    }
+
+    /**
+     * Internal constructor
+     * @param str string
+     * @param segments segments
+     */
+    private Version(String str, String[] segments) {
+        if (str == null) {
+            throw new NullPointerException("Version String must not be null.");
+        }
+        this.str = str;
+        this.segments = segments;
+    }
+
+    @Override
+    public int hashCode() {
+        return str.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return this == o ||
+                o instanceof Version && str.equals(((Version) o).str);
+
+    }
+
+    @Override
+    public String toString() {
+        return str;
+    }
+
+    /**
+     * Returns all segments.
+     * @return all segments.
+     */
+    public String[] getNormalizedSegments() {
+        return segments;
+    }
+
+    /**
+     * Compares this version to the given one, segment by segment with a special
+     * "SNAPSHOT" handling.
+     * <p>
+     * Examples:
+     * <pre>
+     * "1" &lt; "2"
+     * "1.0" &lt; "2"
+     * "2.0.1" &lt; "2.1"
+     * "2.1" &lt; "2.1.1"
+     * "2.9" &lt; "2.11"
+     * "2.1" &gt; "2.1-SNAPSHOT"
+     * "2.1" &gt; "2.1-R1234556"
+     * "2.1-R12345" &lt; "2.1-SNAPSHOT"
+     * </pre>
+     *
+     * @param o the other version
+     * @return  a negative integer, zero, or a positive integer as this version
+     *		is less than, equal to, or greater than the specified version.
+     */
+    public int compareTo(Version o) {
+        String[] oSegs = o.getNormalizedSegments();
+        for (int i=0; i< Math.min(segments.length, oSegs.length); i++) {
+            String s1 = segments[i];
+            String s2 = oSegs[i];
+            if (s1.equals(s2)) {
+                continue;
+            }
+            try {
+                int v1 = Integer.parseInt(segments[i]);
+                int v2 = Integer.parseInt(oSegs[i]);
+                if (v1 != v2) {
+                    return v1 - v2;
+                }
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+            String ss1[] = s1.split("-");
+            String ss2[] = s2.split("-");
+            for (int j=0; j< Math.min(ss1.length, ss2.length); j++) {
+                String c1 = ss1[j];
+                String c2 = ss2[j];
+                try {
+                    int v1 = Integer.parseInt(c1);
+                    int v2 = Integer.parseInt(c2);
+                    if (v1 != v2) {
+                        return v1 - v2;
+                    }
+                } catch (NumberFormatException e) {
+                    // ignore
+                }
+                int c = c1.compareTo(c2);
+                if (c!=0) {
+                    return c;
+                }
+            }
+            int c = ss1.length - ss2.length;
+            if (c != 0) {
+                return -c;
+            }
+        }
+        return segments.length - oSegs.length;
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VersionRange.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VersionRange.java
new file mode 100644
index 0000000..cbc81ef
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VersionRange.java
@@ -0,0 +1,221 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+/**
+ * Implements a version range
+ */
+public class VersionRange {
+
+    /**
+     * Infinite (covers all) range.
+     */
+    public static final VersionRange INFINITE = new VersionRange(null, true, null, true);
+
+    /**
+     * lower bound
+     */
+    private final Version low;
+
+    /**
+     * specifies if lower bound is inclusive
+     */
+    private final boolean lowIncl;
+
+    /**
+     * upper bound
+     */
+    private final Version high;
+
+    /**
+     * specifies if upper bound is inclusive
+     */
+    private final boolean highIncl;
+
+    /**
+     * internal string representation
+     */
+    private final String str;
+
+    /**
+     * Creates a new version range.
+     * @param low lower bound or {@code null}
+     * @param lowIncl specifies if lower bound is inclusive
+     * @param high upper bound or {@code null}
+     * @param highIncl specifies if upper bound is inclusive
+     * @throws IllegalArgumentException if bounds are not valid
+     */
+    public VersionRange(Version low, boolean lowIncl, Version high, boolean highIncl) {
+        // check if range is valid
+        if (low != null && high != null) {
+            int comp = low.compareTo(high);
+            if (comp > 0) {
+                throw new IllegalArgumentException("lower bound must be less or equal to upper bound.");
+            } else if (comp == 0) {
+                if (!lowIncl || !highIncl) {
+                    throw new IllegalArgumentException("invalid empty range. upper and lower bound must be inclusive.");
+                }
+            }
+        }
+        this.low = low;
+        this.lowIncl = lowIncl;
+        this.high = high;
+        this.highIncl = highIncl;
+        StringBuilder b = new StringBuilder();
+        if (low == null && high == null) {
+            // infinite range, empty string
+        } else if (high == null) {
+            // no high bound,
+            if (lowIncl) {
+                // special case, just use version
+                b.append(low);
+            } else {
+                b.append('(');
+                b.append(low);
+                b.append(",)");
+            }
+        } else if (low == null) {
+            b.append("[,");
+            b.append(high);
+            b.append(highIncl ? ']' : ')');
+        } else {
+            b.append(lowIncl ? '[' : '(');
+            b.append(low);
+            b.append(',');
+            b.append(high);
+            b.append(highIncl ? ']' : ')');
+        }
+        this.str = b.toString();
+    }
+
+    /**
+     * Creates a new version range that exactly includes the given version.
+     * @param v the version.
+     */
+    public VersionRange(Version v) {
+        this(v, true, v, true);
+    }
+
+    /**
+     * Returns the lower bound
+     * @return the lower bound or {@code null}
+     */
+    public Version getLow() {
+        return low;
+    }
+
+    /**
+     * Returns {@code true} if the lower bound is inclusive
+     * @return {@code true} if the lower bound is inclusive
+     */
+    public boolean isLowInclusive() {
+        return lowIncl;
+    }
+
+    /**
+     * Returns the upper bound
+     * @return the upper bound or {@code null}
+     */
+    public Version getHigh() {
+        return high;
+    }
+
+    /**
+     * Returns {@code true} if the upper bound is inclusive
+     * @return {@code true} if the upper bound is inclusive
+     */
+    public boolean isHighInclusive() {
+        return highIncl;
+    }
+
+    @Override
+    public int hashCode() {
+        return str.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return this == obj ||
+                obj instanceof VersionRange && str.equals(obj.toString());
+    }
+
+    @Override
+    public String toString() {
+        return str;
+    }
+
+    /**
+     * Checks if the given version is in this range.
+     * @param v the version to check
+     * @return {@code true} if the given version is in this range.
+     */
+    public boolean isInRange(Version v) {
+        if (low != null) {
+            int comp = v.compareTo(low);
+            if (comp < 0 || comp == 0 && !lowIncl) {
+                return false;
+            }
+        }
+        if (high != null) {
+            int comp = v.compareTo(high);
+            if (comp > 0 || comp == 0 && !highIncl) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Creates a range from a string
+     * @param str string
+     * @return the version range
+     */
+    public static VersionRange fromString(String str) {
+        int idx = str.indexOf(',');
+        if (idx >= 0) {
+            boolean linc = false;
+            int lm = str.indexOf('(');
+            if (lm < 0) {
+                lm = str.indexOf('[');
+                if (lm < 0) {
+                    throw new IllegalArgumentException("Range must start with '[' or '('");
+                }
+                linc = true;
+            }
+            boolean hinc = false;
+            int hm = str.indexOf(')');
+            if (hm < 0) {
+                hm = str.indexOf(']');
+                if (hm < 0) {
+                    throw new IllegalArgumentException("Range must end with ']' or ')'");
+                }
+                hinc = true;
+            }
+            String low = str.substring(lm + 1, idx).trim();
+            String high = str.substring(idx+1, hm).trim();
+            Version vLow = low.length() == 0 ? null : Version.create(low);
+            Version vHigh = high.length() == 0 ? null : Version.create(high);
+            return new VersionRange(vLow, linc, vHigh, hinc);
+        } else if (str.length() == 0) {
+            // infinite range
+            return new VersionRange(null, false, null, false);
+        } else {
+            // simple range where given version is minimum
+            return new VersionRange(Version.create(str), true, null, false);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/DefaultPathFilter.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/DefaultPathFilter.java
new file mode 100644
index 0000000..d09e04d
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/DefaultPathFilter.java
@@ -0,0 +1,89 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import java.util.regex.Pattern;
+
+/**
+ * The default path filter provides hierarchical filtering.
+ *
+ */
+public class DefaultPathFilter implements PathFilter {
+
+    /**
+     * the internal regex pattern
+     */
+    private Pattern regex;
+
+    /**
+     * Default constructor
+     */
+    public DefaultPathFilter() {
+    }
+
+    /**
+     * Creates a new default path filter
+     * @param pattern the pattern
+     * @see #setPattern
+     */
+    public DefaultPathFilter(String pattern) {
+        setPattern(pattern);
+    }
+
+    /**
+     * Sets the regexp pattern for this filter.
+     * <p>
+     * Examples:
+     * <pre>
+     * | Pattern        | Matches
+     * | /foo           | exactly "/foo"
+     * | /foo.*         | all paths starting with "/foo"
+     * | ^.* /foo[^/]*$ | all files starting with "foo"
+     * | /foo/[^/]*$    | all direct children of /foo
+     * | /foo/.*        | all children of /foo
+     * | /foo(/.*)?     | all children of /foo and foo itself
+     * </pre>
+     *
+     * @param pattern the pattern.
+     */
+    public void setPattern(String pattern) {
+        regex = Pattern.compile(pattern);
+    }
+
+    /**
+     * Returns the pattern
+     * @return the pattern
+     */
+    public String getPattern() {
+        return regex.pattern();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean matches(String path) {
+        return regex.matcher(path).matches();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isAbsolute() {
+        return regex.pattern().startsWith("/");
+    }
+
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/DefaultWorkspaceFilter.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/DefaultWorkspaceFilter.java
new file mode 100644
index 0000000..fa89bc2
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/DefaultWorkspaceFilter.java
@@ -0,0 +1,325 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.filevault.maven.packaging.Filter;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.pull.MXSerializer;
+import org.codehaus.plexus.util.xml.pull.XmlSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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;
+
+
+/**
+ * Holds a list of {@link PathFilterSet}s.
+ *
+ */
+public class DefaultWorkspaceFilter  {
+
+    /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(DefaultWorkspaceFilter.class);
+
+    private final List<PathFilterSet> filterSets = new LinkedList<PathFilterSet>();
+
+    public static final String ATTR_VERSION = "version";
+
+    public static final double SUPPORTED_VERSION = 1.0;
+
+    protected double version = SUPPORTED_VERSION;
+
+    private byte[] source;
+
+    /**
+     * globally ignored paths. they are not persisted, yet
+     */
+    private PathFilter globalIgnored;
+
+    public void add(PathFilterSet set) {
+        filterSets.add(set);
+    }
+
+    public List<PathFilterSet> getFilterSets() {
+        return filterSets;
+    }
+
+    public PathFilterSet getCoveringFilterSet(String path) {
+        if (isGloballyIgnored(path)) {
+            return null;
+        }
+        for (PathFilterSet set: filterSets) {
+            if (set.covers(path)) {
+                return set;
+            }
+        }
+        return null;
+    }
+
+    public boolean contains(String path) {
+        if (isGloballyIgnored(path)) {
+            return false;
+        }
+        for (PathFilterSet set: filterSets) {
+            if (set.contains(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean covers(String path) {
+        if (isGloballyIgnored(path)) {
+            return false;
+        }
+        for (PathFilterSet set: filterSets) {
+            if (set.covers(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean isAncestor(String path) {
+        for (PathFilterSet set: filterSets) {
+            if (set.isAncestor(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean isGloballyIgnored(String path) {
+        return globalIgnored != null && globalIgnored.matches(path);
+    }
+
+    public void addFilter(Filter filter) {
+        add(filter.toPathFilterSet());
+    }
+
+    // added for Maven 2.2.1 compatibility
+    public void setFilter(Filter filter) {
+        add(filter.toPathFilterSet());
+    }
+
+    /**
+     * Loads the workspace filter from the given file
+     * @param file source
+     * @throws IOException if an I/O error occurs
+     */
+    public void load(File file) throws IOException {
+        load(new FileInputStream(file));
+    }
+
+    public InputStream getSource() {
+        if (source == null) {
+            generateSource();
+        }
+        return new ByteArrayInputStream(source);
+    }
+
+    public String getSourceAsString() {
+        if (source == null) {
+            generateSource();
+        }
+        try {
+            return new String(source, "utf-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /**
+     * Loads the workspace filter from the given input source
+     * @param in source
+     * @throws IOException if an I/O error occurs
+     */
+    public void load(InputStream in) throws IOException {
+        try {
+
+            source = IOUtil.toByteArray(in);
+            in = getSource();
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            //factory.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document document = builder.parse(in);
+            Element doc = document.getDocumentElement();
+            if (!"workspaceFilter".equals(doc.getNodeName())) {
+                throw new IOException("<workspaceFilter> expected.");
+            }
+            String v = doc.getAttribute(ATTR_VERSION);
+            if (v == null || "".equals(v)) {
+                v = "1.0";
+            }
+            version = Double.parseDouble(v);
+            if (version > SUPPORTED_VERSION) {
+                throw new IOException("version " + version + " not supported.");
+            }
+            read(doc);
+        } catch (ParserConfigurationException e) {
+            IOException ioe = new IOException("Unable to create configuration XML parser");
+            e.initCause(e);
+            throw ioe;
+        } catch (SAXException e) {
+            IOException ioe = new IOException("Configuration file syntax error.");
+            e.initCause(e);
+            throw ioe;
+        } finally {
+            IOUtil.close(in);
+        }
+
+    }
+
+    private void read(Element elem) throws IOException {
+        NodeList nl = elem.getChildNodes();
+        for (int i=0; i<nl.getLength(); i++) {
+            Node child = nl.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                if (!"filter".equals(child.getNodeName())) {
+                    throw new IOException("<filter> expected.");
+                }
+                PathFilterSet def = readDef((Element) child);
+                filterSets.add(def);
+            }
+        }
+    }
+
+    private PathFilterSet readDef(Element elem) throws IOException {
+        String root = elem.getAttribute("root");
+        PathFilterSet def = new PathFilterSet(root == null || root.length() == 0 ? "/" : root);
+        // check for import mode
+        String mode = elem.getAttribute("mode");
+        if (mode != null && mode.length() > 0) {
+            def.setImportMode(ImportMode.valueOf(mode.toUpperCase()));
+        }
+        // check for type
+        def.setCleanUp("cleanup".equals(elem.getAttribute("type")));
+
+        // check for filters
+        NodeList n1 = elem.getChildNodes();
+        for (int i=0; i<n1.getLength(); i++) {
+            Node child = n1.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                if ("include".equals(child.getNodeName())) {
+                    def.addInclude(readFilter((Element) child));
+                } else if ("exclude".equals(child.getNodeName())) {
+                    def.addExclude(readFilter((Element) child));
+                } else {
+                    throw new IOException("either <include> or <exclude> expected.");
+                }
+            }
+        }
+        return def;
+    }
+
+    private PathFilter readFilter(Element elem) throws IOException {
+        String pattern = elem.getAttribute("pattern");
+        if (pattern == null || "".equals(pattern)) {
+            throw new IOException("Filter pattern must not be empty");
+        }
+        return new DefaultPathFilter(pattern);
+    }
+
+    public void generateSource() {
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+            XmlSerializer ser = new MXSerializer();
+            ser.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", "    ");
+            ser.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n");
+            ser.setOutput(out, "UTF-8");
+            ser.startDocument("UTF-8", null);
+            ser.text("\n");
+            ser.startTag(null, "workspaceFilter");
+            ser.attribute(null, ATTR_VERSION, String.valueOf(version));
+            for (PathFilterSet set: filterSets) {
+
+                ser.startTag(null, "filter");
+                //attrs = new AttributesImpl();
+                //attrs.addAttribute(null, null, "root", "CDATA", set.getRoot());
+                ser.attribute(null, "root", set.getRoot());
+                if (set.isCleanUp()) {
+                    ser.attribute(null, "type", "cleanup");
+                }
+                if (set.getImportMode() != ImportMode.REPLACE) {
+                    //attrs.addAttribute(null, null, "mode", "CDATA", set.getImportMode().name().toLowerCase());
+                    ser.attribute(null, "mode", set.getImportMode().name().toLowerCase());
+                }
+                //ser.startElement(null, null, "filter", attrs);
+                for (PathFilterSet.Entry<PathFilter> entry: set.getEntries()) {
+                    // only handle path filters
+                    PathFilter filter = entry.getFilter();
+                    if (filter instanceof DefaultPathFilter) {
+                        if (entry.isInclude()) {
+                            ser.startTag(null, "include");
+                            ser.attribute(null, "pattern", ((DefaultPathFilter) filter).getPattern());
+                            ser.endTag(null, "include");
+                        } else {
+                            ser.startTag(null, "exclude");
+                            ser.attribute(null, "pattern", ((DefaultPathFilter) filter).getPattern());
+                            ser.endTag(null, "exclude");
+                        }
+                    } else {
+                        throw new IllegalArgumentException("Can only export default path filters, yet.");
+                    }
+                }
+                ser.endTag(null, "filter");
+            }
+            ser.endTag(null, "workspaceFilter");
+            ser.endDocument();
+            source = out.toByteArray();
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public void setGlobalIgnored(PathFilter ignored) {
+        globalIgnored = ignored;
+    }
+
+    public void merge(DefaultWorkspaceFilter source) {
+        for (PathFilterSet fs: source.getFilterSets()) {
+            // check for collision
+            for (PathFilterSet mfs: getFilterSets()) {
+                if (mfs.getRoot().equals(fs.getRoot())) {
+                    throw new IllegalArgumentException("Merging of equal filter roots not allowed for: " + fs.getRoot());
+                }
+            }
+            add(fs);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/Filter.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/Filter.java
new file mode 100644
index 0000000..4c99ad9
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/Filter.java
@@ -0,0 +1,23 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+/**
+ * {@code Filter}...
+ */
+public interface Filter {
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/FilterSet.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/FilterSet.java
new file mode 100644
index 0000000..d8f4b58
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/FilterSet.java
@@ -0,0 +1,314 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * The item filter set holds a set of item filters each attributed as include
+ * or exclude filter. The evaluation of the set allows included items and
+ * rejects excluded items.
+ * <p>
+ * Additionally it contains a "root" path for which the filters are evaluated.
+ * if an item has not the node addressed by the root path as ancestor, it is
+ * always excluded.
+ */
+public abstract class FilterSet<E extends Filter> {
+
+    /**
+     * root path of this definition
+     */
+    private String root;
+
+    /**
+     * root patten to check for inclusion
+     */
+    private String rootPattern;
+
+    /**
+     * filter entries
+     */
+    private List<Entry<E>> entries;
+
+    /**
+     * flag that indicates if set is sealed
+     */
+    private boolean sealed;
+
+    /**
+     * import mode. defaults to {@link ImportMode#REPLACE}.
+     */
+    private ImportMode mode = ImportMode.REPLACE;
+
+    /**
+     * Default constructor. initializes the root path to "/"
+     */
+    public FilterSet() {
+        this("");
+    }
+
+    /**
+     * Creates a new item filter set and sets the respective root path
+     * @param root path
+     */
+    public FilterSet(String root) {
+        setRoot(root);
+    }
+
+    /**
+     * Returns the root path
+     * @return root path
+     */
+    public String getRoot() {
+        return root.equals("") ? "/" : root;
+    }
+
+    /**
+     * Sets the root path
+     * @param path root path
+     */
+    public void setRoot(String path) {
+        if (sealed) {
+            throw new UnsupportedOperationException("FilterSet is sealed.");
+        }
+        if (path.endsWith("/")) {
+            rootPattern = path;
+            root = path.substring(0, path.length() - 1);
+        } else {
+            rootPattern = path + "/";
+            root = path;
+        }
+    }
+
+    /**
+     * Returns the import mode that is specified for this filter set. Defaults to
+     * {@link ImportMode#REPLACE}.
+     *
+     * @return the import mode.
+     */
+    public ImportMode getImportMode() {
+        return mode;
+    }
+
+    /**
+     * Sets the import mode.
+     * @param mode import mode
+     */
+    public void setImportMode(ImportMode mode) {
+        if (sealed) {
+            throw new UnsupportedOperationException("FilterSet is sealed.");
+        }
+        this.mode = mode;
+    }
+
+    /**
+     * Seals this list, i.e. makes it unmodifiable.
+     * @return this list
+     */
+    public FilterSet seal() {
+        if (!sealed) {
+            if (entries == null) {
+                entries = Collections.emptyList();
+            } else {
+                entries = Collections.unmodifiableList(entries);
+            }
+            sealed = true;
+        }
+        return this;
+    }
+
+    /**
+     * Checks if this filter set is sealed.
+     * @return {@code true} if sealed.
+     */
+    public boolean isSealed() {
+        return sealed;
+    }
+
+    /**
+     * Adds (replaces) all entries from the given set to this one.
+     * @param set the set of entries
+     * @return {@code this} suitable for chaining.
+     */
+    public FilterSet addAll(FilterSet<E> set) {
+        if (sealed) {
+            throw new UnsupportedOperationException("FilterSet is sealed.");
+        }
+        if (entries == null) {
+            entries = new LinkedList<Entry<E>>(set.entries);
+        } else {
+            entries.clear();
+            entries.addAll(set.entries);
+        }
+        return this;
+    }
+
+    /**
+     * Adds a new item filter as included entry.
+     * @param filter the filter
+     * @return {@code this} suitable for chaining.
+     */
+    public FilterSet addInclude(E filter) {
+        addEntry(new Entry<E>(filter, true));
+        return this;
+    }
+
+    /**
+     * Adds a new item filter as excluded entry.
+     * @param filter the filter
+     * @return {@code this} suitable for chaining.
+     */
+    public FilterSet addExclude(E filter) {
+        addEntry(new Entry<E>(filter, false));
+        return this;
+    }
+
+    /**
+     * Internally adds a new entry to the list
+     * @param e the entry
+     */
+    private void addEntry(Entry<E> e) {
+        if (sealed) {
+            throw new UnsupportedOperationException("FilterSet is sealed.");
+        }
+        if (entries == null) {
+            entries = new LinkedList<Entry<E>>();
+        }
+        entries.add(e);
+    }
+
+    /**
+     * Returns the list of entries
+     * @return the list of entries
+     */
+    public List<Entry<E>> getEntries() {
+        seal();
+        return entries;
+    }
+
+    /**
+     * Checks if this filter set has any entries defined.
+     * @return {@code true} if empty
+     */
+    public boolean isEmpty() {
+        return entries == null || entries.isEmpty();
+    }
+
+    /**
+     * Checks if the given item is covered by this filter set. I.e. if the node
+     * addressed by the {@code root} path is an ancestor of the given item.
+     *
+     * @param path path of the item
+     * @return {@code true} if this set covers the given item
+     */
+    public boolean covers(String path) {
+        return path.equals(root) || path.startsWith(rootPattern);
+    }
+
+    /**
+     * Checks if the given item is an ancestor of the root node.
+     * @param path path of the item to check
+     * @return {@code true} if the given item is an ancestor
+     */
+    public boolean isAncestor(String path) {
+        return path.equals(root) || root.startsWith(path + "/") || path.equals("/");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode() {
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof FilterSet) {
+            return entries.equals(((FilterSet) obj).entries);
+        }
+        return false;
+    }
+
+    /**
+     * Holds a filter entry
+     */
+    public static class Entry<E extends Filter> {
+
+        /**
+         * The item filter
+         */
+        protected final E filter;
+
+        /**
+         * indicates if this an include filter
+         */
+        protected final boolean include;
+
+        /**
+         * Constructs a new entry
+         * @param filter the filter
+         * @param include the include flag
+         */
+        public Entry(E filter, boolean include) {
+            this.filter = filter;
+            this.include = include;
+        }
+
+        /**
+         * Returns the filter of this entry
+         * @return the filter
+         */
+        public E getFilter() {
+            return filter;
+        }
+
+        /**
+         * Returns the 'include' flag of this entry
+         * @return the flag
+         */
+        public boolean isInclude() {
+            return include;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int hashCode() {
+            return 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof Entry) {
+                return ((Entry) obj).include == include && ((Entry) obj).filter.equals(filter);
+            }
+            return false;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportMode.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportMode.java
new file mode 100644
index 0000000..7b79a74
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportMode.java
@@ -0,0 +1,41 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+/**
+ * {@code ImportMode} is used to define how importing content is applied
+ * to the existing content in the repository.
+ */
+public enum ImportMode {
+
+    /**
+     * Normal behavior. Existing content is replaced completly by the imported
+     * content, i.e. is overridden or deleted accordingly.
+     */
+    REPLACE,
+
+    /**
+     * Existing content is not modified, i.e. only new content is added and
+     * none is deleted or modified.
+     */
+    MERGE,
+
+    /**
+     * Existing content is only updated but never deleted.
+     */
+    UPDATE
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageInfo.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageInfo.java
new file mode 100644
index 0000000..8e2c90f
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageInfo.java
@@ -0,0 +1,139 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.annotation.Nonnull;
+
+import org.apache.commons.lang.StringUtils;
+
+import org.apache.jackrabbit.filevault.maven.packaging.PackageId;
+import org.apache.jackrabbit.filevault.maven.packaging.VaultMojo;
+
+/**
+ * Very simple class that reads basic package info from a file.
+ */
+public class PackageInfo {
+
+    private final PackageId id;
+
+    private final DefaultWorkspaceFilter filter;
+
+    private final PackageType packageType;
+
+    private PackageInfo(PackageId id, DefaultWorkspaceFilter filter, PackageType packageType) {
+        this.id = id;
+        this.filter = filter;
+        this.packageType = packageType;
+    }
+
+    /**
+     * Reads the package file.
+     * @param file the file.
+     * @return {@code true} if the package is valid.
+     * @throws IOException if an error occurrs.
+     */
+    public static PackageInfo read(@Nonnull File file) throws IOException {
+        PackageId id = null;
+        DefaultWorkspaceFilter filter = null;
+        PackageType packageType = PackageType.MIXED;
+
+        ZipFile zip = new ZipFile(file);
+        Enumeration<? extends ZipEntry> entries = zip.entries();
+        while (entries.hasMoreElements() && (id == null || filter == null)) {
+            ZipEntry e = entries.nextElement();
+            if (JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
+                Manifest mf = new Manifest(zip.getInputStream(e));
+                String idStr = mf.getMainAttributes().getValue(VaultMojo.MF_KEY_PACKAGE_ID);
+                if (idStr != null) {
+                    id = PackageId.fromString(idStr);
+                }
+                String roots = mf.getMainAttributes().getValue(VaultMojo.MF_KEY_PACKAGE_ROOTS);
+                filter = new DefaultWorkspaceFilter();
+                if (roots != null) {
+                    for (String root: StringUtils.split(roots, ',')) {
+                        filter.add(new PathFilterSet(root));
+                    }
+                }
+                String type = mf.getMainAttributes().getValue(VaultMojo.MF_KEY_PACKAGE_TYPE);
+                if (type != null) {
+                    packageType = PackageType.valueOf(type.toUpperCase());
+                }
+            } else if (VaultMojo.PROPERTIES_FILE.equalsIgnoreCase(e.getName())) {
+                Properties props = new Properties();
+                props.loadFromXML(zip.getInputStream(e));
+                String version = props.getProperty("version");
+                if (version == null) {
+                    version = "";
+                }
+                String group = props.getProperty("group");
+                String name = props.getProperty("name");
+                if (group != null && name != null) {
+                    id = new PackageId(group, name, version);
+                } else {
+                    // check for legacy packages that only contains a 'path' property
+                    String path = props.getProperty("path");
+                    if (path == null || path.length() == 0) {
+                        path = "/etc/packages/unknown";
+                    }
+                    id = new PackageId(path, version);
+                }
+            } else if (VaultMojo.FILTER_FILE.equalsIgnoreCase(e.getName())) {
+                filter = new DefaultWorkspaceFilter();
+                filter.load(zip.getInputStream(e));
+            }
+        }
+        zip.close();
+        if (id == null || filter == null) {
+            return null;
+        } else {
+            return new PackageInfo(id, filter, packageType);
+        }
+    }
+
+    /**
+     * Returns the package id.
+     * @return the package id.
+     */
+    public PackageId getId() {
+        return id;
+    }
+
+    /**
+     * Returns the workspace filter
+     * @return the filter
+     */
+    public DefaultWorkspaceFilter getFilter() {
+        return filter;
+    }
+
+    /**
+     * Returns the package type.
+     * @return the package type
+     */
+    public PackageType getPackageType() {
+        return packageType;
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageType.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageType.java
new file mode 100644
index 0000000..4ae85cf
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageType.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+/**
+ * Specifies the type of the package. The package type helps to characterize the contents of a package and influences
+ * how the package is used during deployment, installation and removal.
+ */
+public enum PackageType {
+
+    /**
+     * An application package consists purely of application content. It serializes entire subtrees with no
+     * inclusion or exclusion filters. it does not contain any subpackages nor OSGi configuration or bundles.
+     */
+    APPLICATION,
+
+    /**
+     * A content package consists only of content and user defined configuration. It usually serializes entire subtrees
+     * but can contain inclusion or exclusion filters. it does not contain any subpackages nor OSGi configuration or bundles.
+     */
+    CONTENT,
+
+    /**
+     * A container package only contains sub packages and OSGi configuration and bundles. The container package is only used as container for deployment.
+     */
+    CONTAINER,
+
+    /**
+     * Catch all type for a combination of the above.
+     */
+    MIXED
+
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PathFilter.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PathFilter.java
new file mode 100644
index 0000000..2819054
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PathFilter.java
@@ -0,0 +1,81 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+/**
+ * The item filter is used to include or exclude a set of paths.
+ * It is usually part of a {@link PathFilterSet}.
+ *
+ */
+public interface PathFilter extends Filter {
+
+    /**
+     * The "Catch all" item filter.
+     */
+    public static final PathFilter ALL = new PathFilter() {
+
+        /**
+         * Returns always {@code true}
+         */
+        public boolean matches(String path) {
+            return true;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean isAbsolute() {
+            return true;
+        }
+    };
+
+    /**
+     * The "Miss all" item filter.
+     */
+    public static final PathFilter NONE = new PathFilter() {
+
+        /**
+         * Returns always {@code false}
+         */
+        public boolean matches(String path) {
+            return false;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean isAbsolute() {
+            return true;
+        }
+
+    };
+
+    /**
+     * Checks if the given path matches this filters criteria.
+     *
+     * @param path the path to check
+     * @return {@code true} if this filter matches the criteria;
+     *         {@code false} otherwise.
+     */
+    boolean matches(String path);
+
+    /**
+     * Checks if the pattern is absolute, i.e. does not start with a wildcard.
+     * @return {@code true} if pattern is absolute
+     */
+    boolean isAbsolute();
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PathFilterSet.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PathFilterSet.java
new file mode 100644
index 0000000..2e81953
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PathFilterSet.java
@@ -0,0 +1,139 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import java.util.List;
+
+/**
+ * The path filter set holds a set of path filters each attributes as include
+ * or exclude filter. The evaluation of the set allows included paths and
+ * rejects excluded paths.
+ * <p>
+ * Additionally it contains a "root" path for which the filters are evaluated.
+ * if an item has not the node addressed by the root path as ancestor, it is
+ * always excluded.
+ */
+public class PathFilterSet extends FilterSet<PathFilter> {
+
+    /**
+     * The include all item filter set
+     */
+    public static final PathFilterSet INCLUDE_ALL =
+            (PathFilterSet) new PathFilterSet().addInclude(PathFilter.ALL).seal();
+
+    /**
+     * The exclude all item filter set
+     */
+    public static final PathFilterSet EXCLUDE_ALL =
+            (PathFilterSet) new PathFilterSet().addExclude(PathFilter.ALL).seal();
+
+
+    /**
+     * specifies if only relative patters are included in this filter ser
+     */
+    private boolean onlyRelativePatterns;
+
+    private boolean cleanUp;
+
+    /**
+     * Default constructor. initializes the root path to "/"
+     */
+    public PathFilterSet() {
+        super();
+    }
+
+    /**
+     * Creates a new path filter set and sets the respective root path
+     * @param root path
+     */
+    public PathFilterSet(String root) {
+        super(root);
+    }
+
+    /**
+     * Specifies if this filter is a cleanup filter. A cleanup filter has weaker dependency constraints.
+     * @return {@code true} if this is a cleanup filter.
+     */
+    public boolean isCleanUp() {
+        return cleanUp;
+    }
+
+    /**
+     * Marks this filter as cleanup filter if set to {@code true}.
+     * @param cleanUp cleanup attribute.
+     * @return this.
+     */
+    public PathFilterSet setCleanUp(boolean cleanUp) {
+        this.cleanUp = cleanUp;
+        return this;
+    }
+
+    /**
+     * Evaluates the filters if this set does {@link #covers(String) cover} the
+     * given item. otherwise  is returned.
+     * The result of the evaluation is the polarity of the last matched path.
+     * If no filter matches it returns {@code true}
+     * if the first filter is an exclude filter or if no filter is defined;
+     * {@code false} if the first filter is an include filter.
+     *
+     * @param path the path to check
+     * @return {@code true} if this set matches the item
+     */
+    public boolean contains(String path) {
+        if (!covers(path)) {
+            return false;
+        }
+        List<Entry<PathFilter>> entries = getEntries();
+        if (entries.isEmpty()) {
+            return true;
+        } else {
+            boolean result = !entries.get(0).include;
+            for (Entry<PathFilter> entry: entries) {
+                if (entry.filter.matches(path)) {
+                    result = entry.include;
+                }
+            }
+            return result;
+        }
+    }
+
+    @Override
+    public FilterSet seal() {
+        if (!isSealed()) {
+            super.seal();
+            onlyRelativePatterns = true;
+            for (Entry<PathFilter> entry: getEntries()) {
+                if (!entry.include || entry.filter.isAbsolute()) {
+                    onlyRelativePatterns = false;
+                    break;
+                }
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Checks if this path filter set only contains entries that are relative
+     * include patterns, eg: ".* /foo.*". in this case the aggregator will use a
+     * different strategy when providing non matching leave nodes.
+     * @return {@code true} if only contains relative patterns
+     */
+    public boolean hasOnlyRelativePatterns() {
+        seal();
+        return onlyRelativePatterns;
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PlatformNameFormat.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PlatformNameFormat.java
new file mode 100644
index 0000000..f7eb5eb
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PlatformNameFormat.java
@@ -0,0 +1,214 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Implements a repository to platform name formatter. 
+ * 
+ * <p>Illegal characters a
+ * generally escaped using the url escaping format, i.e. replacing the char
+ * by a '%' hex(char) sequence. special treatment is used for the ':' char
+ * since it's used quite often as namespace prefix separator. the
+ * PREFIX ':' NAME sequence is replaced by '_' PREFIX '_' NAME. item names
+ * that would generate the same pattern are escaped with an extra leading '_'.
+ * 
+ * <p>Examples:
+ * 
+ * <pre>
+ * +-------------------+----------------------+----+----+
+ * | repository name   | platform name        | pp | sp |
+ * +-------------------+----------------------+----+----+
+ * | test.jpg          | test.jpg             | -1 | -1 |
+ * | cq:content        | _cq_content          |  2 | -1 |
+ * | cq:test_image.jpg | _cq_test_image.jpg   |  2 |  7 |
+ * | test_image.jpg    | test_image.jpg       | -1 |  4 |
+ * | _testimage.jpg    | _testimage.jpg       | -1 |  0 |
+ * | _test_image.jpg   | __test_image.jpg     | -1 |  0 |
+ * +-------------------+----------------------+----+----+
+ * | cq:test:image.jpg | _cq_test%3aimage.jpg |  2 | -1 |
+ * | _cq_:test.jpg     | __cq_%3atest.jpg     |  4 |  0 |
+ * | _cq:test.jpg      | __cq%3atest.jpg      |  3 |  0 |
+ * | cq_:test.jpg      | cq_%3atest.jpg       |  3 |  2 |
+ * +-------------------+----------------------+----+----+
+ * </pre>
+ * 
+ * note for the 2nd set of examples the cases are very rare and justify the
+ * ugly '%' escaping.
+ *
+ */
+public class PlatformNameFormat {
+
+    /**
+     * Returns the platform name for a given repository name. Unsupported
+     * characters are URL escaped (i.e. %xx).
+     *
+     * Note: Forward slashes '/' are not escaped since they never occur in a
+     * jcr name. so this method can also be used to encode paths.
+     *
+     * @param repositoryName the repository name
+     * @return the (escaped) platform name.
+     */
+    public static String getPlatformName(String repositoryName) {
+        StringBuilder buf = new StringBuilder("_");
+        boolean escapeColon = false;
+        boolean useUnderscore = false;
+        int numUnderscore = 0;
+        for (int i=0; i<repositoryName.length(); i++) {
+            char c = repositoryName.charAt(i);
+            switch (c) {
+                 case':':
+                     if (!escapeColon && i>0) {
+                         // pure prefix
+                         escapeColon = true;
+                         useUnderscore = true;
+                         numUnderscore = 2;
+                         buf.append('_');
+                     } else {
+                         buf.append("%3a");
+                     }
+                     break;
+                 case '_':
+                     if (i==0) {
+                         useUnderscore = true;
+                     }
+                     numUnderscore++;
+                     escapeColon=true;
+                     buf.append(c);
+                     break;
+                 case'\\':
+                 case'<':
+                 case'>':
+                 case'|':
+                 case'\"':
+                 case '/':
+                 case'?':
+                 case'%':
+                     buf.append('%');
+                     buf.append(Character.forDigit(c / 16, 16));
+                     buf.append(Character.forDigit(c % 16, 16));
+                     break;
+                 default:
+                     buf.append(c);
+             }
+        }
+        if (useUnderscore && numUnderscore > 1) {
+            return buf.toString();
+        } else {
+            return buf.substring(1);
+        }
+    }
+
+    /**
+     * Returns the platform path for the given repository one.
+     * @param repoPath the repository path
+     * @return the platform path
+     */
+    public static String getPlatformPath(String repoPath) {
+        String[] elems = StringUtils.split(repoPath, "/");
+        for (int i=0; i<elems.length; i++) {
+            if (elems[i].length() > 0) {
+                elems[i] = getPlatformName(elems[i]);
+            }
+        }
+        return StringUtils.join(elems, "/");
+    }
+
+    /**
+     * Returns the repository name for a given platform name.
+     *
+     * @param platformName the platform name
+     * @return the (unescaped) repository name.
+     */
+    public static String getRepositoryName(String platformName) {
+        StringBuilder buffer = new StringBuilder("_");
+        boolean firstUnderscore = false;
+        for (int i=0; i<platformName.length(); i++) {
+            char c = platformName.charAt(i);
+            if (c == '%') {
+                if (platformName.length() > i+2) {
+                    int a = Character.digit(platformName.charAt(++i), 16);
+                    int b = Character.digit(platformName.charAt(++i), 16);
+                    c = (char) (a * 16 + b);
+                }
+            } else if (c == '_') {
+                if (i==0) {
+                    firstUnderscore = true;
+                    if (platformName.length()>1) {
+                        c = platformName.charAt(++i);
+                        if (c == '_') {
+                            buffer.append('_');
+                            firstUnderscore = false;
+                        } else {
+                            buffer.append(c);
+                        }
+                    }
+                    continue;
+                } else if (firstUnderscore) {
+                    c = ':';
+                    firstUnderscore = false;
+                }
+            }
+            buffer.append(c);
+        }
+        if (firstUnderscore) {
+            // pending underscore
+            return buffer.toString();
+        } else {
+            return buffer.substring(1);
+        }
+    }
+
+    /**
+     * Returns the repository path for the given platform one.
+     * @param path the platform path
+     * @return the repository path
+     */
+    public static String getRepositoryPath(String path) {
+        String[] elems = StringUtils.split(path, "/");
+        for (int i=0; i<elems.length; i++) {
+            if (elems[i].length() > 0) {
+                elems[i] = getRepositoryName(elems[i]);
+            }
+        }
+        return StringUtils.join(elems, "/");
+    }
+
+    /**
+     * Returns the repository path for the given platform one.
+     * @param path the platform path
+     * @param respectDotDir if {@code true}, all ".dir" are removed.
+     * @return the repository path
+     */
+    public static String getRepositoryPath(String path, boolean respectDotDir) {
+        String[] elems = StringUtils.split(path, "/");
+        for (int i=0; i<elems.length; i++) {
+            if (elems[i].length() > 0) {
+                if (respectDotDir && elems[i].endsWith(".dir")) {
+                    elems[i] = getRepositoryName(elems[i].substring(0, elems[i].length() - 4));
+                } else {
+                    elems[i] = getRepositoryName(elems[i]);
+                }
+            }
+        }
+        return StringUtils.join(elems, "/");
+    }
+
+
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/StringFilter.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/StringFilter.java
new file mode 100644
index 0000000..f65aa13
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/StringFilter.java
@@ -0,0 +1,68 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+/**
+ * {@code StringFilter}...
+ */
+public class StringFilter extends DefaultPathFilter {
+
+    private String string;
+
+    public StringFilter(String pattern) {
+        super(pattern);
+    }
+
+    @Override
+    public String getPattern() {
+        if (string == null) {
+            return super.getPattern();
+        } else {
+            return string;
+        }
+    }
+    @Override
+    public void setPattern(String pattern) {
+        if (pattern.startsWith("/")) {
+            pattern = pattern.substring(1);
+            if (pattern.endsWith("/")) {
+                pattern = pattern.substring(0, pattern.length()-1);
+            }
+            super.setPattern(pattern);
+        } else {
+            string = pattern;
+        }
+    }
+
+    @Override
+    public boolean matches(String path) {
+        if (string == null) {
+            return super.matches(path);
+        } else {
+            return string.equals(path);
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (string == null) {
+            return "/" + getPattern() + "/";
+        } else {
+            return getPattern();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/StringFilterSet.java b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/StringFilterSet.java
new file mode 100644
index 0000000..5448e6d
--- /dev/null
+++ b/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/StringFilterSet.java
@@ -0,0 +1,69 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import java.util.List;
+
+/**
+ * {@code StringFilterSet}...
+ */
+public class StringFilterSet extends FilterSet<StringFilter> {
+
+    public void addEntry(String pattern) {
+        if (pattern.startsWith("~")) {
+            addExclude(new StringFilter(pattern.substring(1)));
+        } else {
+            addInclude(new StringFilter(pattern));
+        }
+    }
+
+    public void addEntries(String patterns) {
+        for (String name: patterns.split(",")) {
+            addEntry(name.trim());
+        }
+    }
+
+    public boolean contains(String path) {
+        List<Entry<StringFilter>> entries = getEntries();
+        if (entries.isEmpty()) {
+            return true;
+        } else {
+            boolean result = !entries.get(0).isInclude();
+            for (Entry<StringFilter> entry: entries) {
+                if (entry.getFilter().matches(path)) {
+                    result = entry.isInclude();
+                }
+            }
+            return result;
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        String delim = "";
+        for (Entry<StringFilter> entry: getEntries()) {
+            builder.append(delim);
+            if (!entry.isInclude()) {
+                builder.append("~");
+            }
+            builder.append(entry.getFilter());
+            delim=",";
+        }
+        return builder.toString();
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/trunk/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
new file mode 100644
index 0000000..68ebfdb
--- /dev/null
+++ b/trunk/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
@@ -0,0 +1,30 @@
+<!--
+  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.
+  -->
+<lifecycleMappingMetadata>
+    <pluginExecutions>
+        <pluginExecution>
+            <pluginExecutionFilter>
+                <goals>
+                    <goal>check-signature</goal>
+                </goals>
+            </pluginExecutionFilter>
+            <action>
+                <ignore/>
+            </action>
+        </pluginExecution>
+    </pluginExecutions>
+</lifecycleMappingMetadata>
\ No newline at end of file
diff --git a/trunk/src/main/resources/META-INF/plexus/components.xml b/trunk/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000..5122b87
--- /dev/null
+++ b/trunk/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,63 @@
+<!--
+  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.
+  -->
+<component-set>
+    <components>
+        <component>
+            <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+            <role-hint>content-package</role-hint>
+            <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+            <configuration>
+                <lifecycles>
+                    <lifecycle>
+                        <id>default</id>
+                        <!-- START SNIPPET: bundle-lifecycle -->
+                        <phases>
+                            <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources
+                            </process-resources>
+                            <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
+                            <process-classes>
+                                org.apache.jackrabbit:filevault-package-maven-plugin:check-signature,
+                                org.apache.jackrabbit:filevault-package-maven-plugin:analyze-classes
+                            </process-classes>
+                            <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources
+                            </process-test-resources>
+                            <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
+                            <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
+                            <package>org.apache.jackrabbit:filevault-package-maven-plugin:package</package>
+                            <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+                            <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+                        </phases>
+                        <!-- END SNIPPET: bundle-lifecycle -->
+                    </lifecycle>
+                </lifecycles>
+            </configuration>
+        </component>
+        <component>
+            <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+            <role-hint>content-package</role-hint>
+            <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+            <configuration>
+                <type>content-package</type>
+                <includesDependencies>true</includesDependencies>
+                <language>java</language>
+                <extension>zip</extension>
+                <packaging>content-package</packaging>
+                <addedToClasspath>true</addedToClasspath>
+            </configuration>
+        </component>
+    </components>
+</component-set>
diff --git a/trunk/src/main/resources/vault/config.xml b/trunk/src/main/resources/vault/config.xml
new file mode 100644
index 0000000..59e3a4a
--- /dev/null
+++ b/trunk/src/main/resources/vault/config.xml
@@ -0,0 +1,93 @@
+<!--
+  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.
+  -->
+<vaultfs version="1.1">
+    <!--
+        Defines the content aggregation. The order of the defined aggregates
+        is important for finding the correct aggregator.
+    -->
+    <aggregates>
+        <!--
+            Defines an aggregate that handles nt:file and nt:resource nodes.
+        -->
+        <aggregate type="file" title="File Aggregate"/>
+
+        <!--
+            Defines an aggregate that handles file/folder like nodes. It matches
+            all nt:hierarchyNode nodes that have or define a jcr:content
+            child node and excludes child nodes that are nt:hierarchyNodes.
+        -->
+        <aggregate type="filefolder" title="File/Folder Aggregate"/>
+
+        <!--
+            Defines an aggregate that handles nt:nodeType nodes and serializes
+            them into .cnd notation.
+        -->
+        <aggregate type="nodetype" title="Node Type Aggregate" />
+
+        <!--
+            Defines an aggregate that defines full coverage for certain node
+            types that cannot be covered by the default aggregator.
+        -->
+        <aggregate type="full" title="Full Coverage Aggregate">
+            <matches>
+                <include nodeType="rep:AccessControl" respectSupertype="true" />
+                <include nodeType="cq:Widget" respectSupertype="true" />
+                <include nodeType="cq:WidgetCollection" respectSupertype="true" />
+                <include nodeType="cq:EditConfig" respectSupertype="true" />
+                <include nodeType="cq:WorkflowModel" respectSupertype="true" />
+                <include nodeType="vlt:FullCoverage" respectSupertype="true" />
+                <include nodeType="mix:language" respectSupertype="true" />
+                <include nodeType="sling:OsgiConfig" respectSupertype="true" />
+            </matches>
+        </aggregate>
+
+        <!--
+            Defines an aggregate that handles nt:folder like nodes.
+        -->
+        <aggregate type="generic" title="Folder Aggregate">
+            <matches>
+                <include nodeType="nt:folder" respectSupertype="true" />
+            </matches>
+            <contains>
+                <exclude isNode="true" />
+            </contains>
+        </aggregate>
+
+        <!--
+            Defines the default aggregate
+        -->
+        <aggregate type="generic" title="Default Aggregator" isDefault="true">
+            <contains>
+                <exclude nodeType="nt:hierarchyNode" respectSupertype="true" />
+            </contains>
+            <matches>
+                <!-- all -->
+            </matches>
+        </aggregate>
+
+    </aggregates>
+
+    <!--
+      defines the input handlers
+    -->
+    <handlers>
+        <handler type="folder"/>
+        <handler type="file"/>
+        <handler type="nodetype"/>
+        <handler type="generic"/>
+    </handlers>
+</vaultfs>
\ No newline at end of file
diff --git a/trunk/src/main/resources/vault/settings.xml b/trunk/src/main/resources/vault/settings.xml
new file mode 100644
index 0000000..61c1bea
--- /dev/null
+++ b/trunk/src/main/resources/vault/settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<vault version="1.0">
+  <ignore name=".svn"/>
+  <ignore name=".DS_Store"/>
+</vault>
\ No newline at end of file
diff --git a/trunk/src/site/README.md b/trunk/src/site/README.md
new file mode 100644
index 0000000..806421e
--- /dev/null
+++ b/trunk/src/site/README.md
@@ -0,0 +1,47 @@
+<!--
+   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.
+  -->
+
+FileVault Documentation
+=======================
+The FileVault documentation lives as Markdown files in `src/site/markdown` such
+that it easy to view e.g. from GitHub. Alternatively the Maven site plugin
+can be used to build and deploy a web site as follows:
+
+1. From the reactor build the site with javadoc:
+
+   ````
+   $ mvn site
+   ````
+
+2. Review the site at `site/target/site`
+
+3. Deploy the site to `http://jackrabbit.apache.org/filevault-package-maven-plugin` using:
+
+   ````
+   $ mvn site-deploy
+   ````
+
+4. Finally review the site at `http://jackrabbit.apache.org/filevault-package-maven-plugin/index.html`.
+
+
+Note: To skip the final commit use `-Dscmpublish.skipCheckin=true`. You can then
+review all pending changes in `target/scmpublish-checkout` and follow
+up with `svn commit` manually.
+
+Note: Every committer should be able to deploy the site. No fiddling with
+credentials needed since deployment is done via svn commit to
+`https://svn.apache.org/repos/asf/jackrabbit/site/live/filevault-package-maven-plugin`.
diff --git a/trunk/src/site/markdown/dev.md b/trunk/src/site/markdown/dev.md
new file mode 100644
index 0000000..32b49f7
--- /dev/null
+++ b/trunk/src/site/markdown/dev.md
@@ -0,0 +1,80 @@
+<!--
+   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.
+-->
+Developing
+==========
+
+Latest development
+------------------
+The latest FileVault Package Maven Plugin source code is available via Subversion at
+
+* https://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/trunk
+
+or with ViewVC at
+
+* https://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk
+
+or on GitHub at
+
+* https://github.com/apache/jackrabbit-filevault-package-maven-plugin
+
+
+To checkout the main Jackrabbit source tree, run
+
+    svn checkout https://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/trunk jackrabbit-filevault
+    
+or
+
+    git clone https://github.com/apache/jackrabbit-filevault-package-maven-plugin.git
+
+
+Building FileVault Package Maven Plugin
+------------------
+You can build FileVault Package Maven Plugin using maven:
+
+    cd filevault-package-maven-plugin
+    mvn clean install
+
+You need Maven 3.2.5 (or higher) with Java 7 (or higher) for the build.
+For more instructions, please see the documentation at:
+
+*  http://jackrabbit.apache.org/building-jackrabbit.html
+
+Issue Tracker
+-------------
+Apache Jackrabbit FileVault uses Jira for tracking bug reports and requests for improvements, new features, 
+and other changes.
+
+The issue tracker is available at https://issues.apache.org/jira/browse/JCRVLT and is readable by everyone. 
+A Jira account is needed to create new issues and to comment on existing issues. Use the
+[registration form](https://issues.apache.org/jira/secure/Signup!default.jspa) to request an account if you 
+do not already have one.
+
+See the [Jackrabbit Issue Tracker Page](http://jackrabbit.apache.org/issue-tracker.html) for more information.
+
+
+Mailing Lists
+-------------
+To get involved with the Apache Jackrabbit project, start by having a
+look at our website and joining our mailing lists. For more details about
+Jackrabbit mailing lists as well as links to list archives, please see:
+
+* http://jackrabbit.apache.org/mailing-lists.html
+
+Releasing
+---------
+See the extensive [Release Documentation](howto_release.html) on the steps
+involved to release Jackrabbit FileVault.
diff --git a/trunk/src/site/markdown/howto_release.md b/trunk/src/site/markdown/howto_release.md
new file mode 100644
index 0000000..268c72b
--- /dev/null
+++ b/trunk/src/site/markdown/howto_release.md
@@ -0,0 +1,192 @@
+<!--
+   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.
+-->
+How To Create A Release
+========================================================================================================================
+<!-- line width set to 120 characters. please break lines so that this file also looks good in vi -->
+
+
+Prerequisites for release managers
+----------------------------------
+You need to be a Jackrabbit committer to prepare and perform a release, but anyone is welcome to help test the release
+candidates and comment on the release plans.
+
+You should have a code signing key that is included in the Jackrabbit KEYS file. See [Appendix A](#A) at the end of 
+this page for more details.
+
+You also need to tell Maven your Subversion credentials needed for deploying artifacts to the Nexus server at 
+https://repository.apache.org/. See [Appendix B](#B) for the required settings.
+
+Release management tasks
+------------------------
+1. Make sure that an appropriate version for the release is entered in [Jira][3] and that all the related issues have
+   been resolved.
+   
+2. Create or update a `RELEASE-NOTES.md` file in the root folder of the project to be released. When done, commit the
+   file. See previous release notes for examples of what to include. The release note report in [Jira][3] is a useful
+   source of required information.
+   
+3. Build and deploy the release artifacts with Maven (see below).
+
+    The release is built using the Maven release plugin. See the [Releasing a Maven project][4] guide for more
+    details. Make sure you have added the pgp key information in you maven settings file, especially if you have 
+    more than one key installed locally. See [Appendix B](#B) for the details.
+
+    Releasing the maven artifact works best when operating on the subversion checkout of the project. Using _git svn_
+    does not work.
+    
+    0. (optional, prepare your environment. e.g.: `$ export version=1.0.0`)
+    1. Execute `mvn clean deploy -Papache-release -Dmaven.deploy.skip=true`. This tests if the release would work.
+    1. Execute `mvn release:prepare`. This will update the POM files and tag the release in svn (btw: specifying the 
+        release version on the commandline doesn't update the module poms anymore lately).
+    2. Execute `mvn release:perform -Papache-release`. This will build the tagged release and deploy the artifacts to
+        a new staging repository on _repository.apache.org_. 
+        After the build, login to [https://repository.apache.org/][2] and you should see it there.
+    
+        The non-Maven release artifacts are automatically copied to `/.../target/checkout/target/$version`
+
+4. Close the [staged repository][2] on _repository.apache.org_.
+
+5. Upload the artifacts to https://dist.apache.org/repos/dist/dev/jackrabbit/filevault via SVN
+       
+        svn co https://dist.apache.org/repos/dist/dev/jackrabbit/filevault-package-maven-plugin dist-dev-filevault-plugin
+        cd dist-dev-filevault-plugin
+        cp -r /path/to/jackrabbit/filevault-package-maven-plugin/target/checkout/target/$version $version
+        svn add $version
+        svn commit -m "Apache Jackrabbit Filevault Package Maven Plugin $version release candidate" $version
+       
+6. Start the vote thread, wait **72 hours**. See the `vote.txt` template generated by the Maven build.
+
+7. If the vote fails (easy case first):
+    1. remove the release tag from svn
+
+       ````
+       svn rm https://svn.apache.org/repos/asf/jackrabbit/commons/filevault/tags/jackrabbit-filevault-package-maven-plugin-$version
+       ````
+
+    2. delete the RC from _dist.apache.org_
+    3. and drop the staged repository
+    4. done 
+ 
+8. If the vote is successful, close the vote by publishing the results
+
+9. copy the release candidate from `dev/jackrabbit` to `release/jackrabbit` in 
+   https://dist.apche.org/repos/dist/, and delete any older releases from the same branch 
+   (they're automatically archived):
+
+    ```` 
+    svn move -m "Apache Jackrabbit Filevault $version" \
+        https://dist.apache.org/repos/dist/dev/jackrabbit/filevault-package-maven-plugin/$version \
+        https://dist.apache.org/repos/dist/release/jackrabbit/filevault-package-maven-plugin/$version
+    ````
+
+10. release the [staged repository][2] for synchronization to Maven central.
+
+11. mark the version as released in [Jira][3]:
+    _Jira Project Home_ -> _Project Summary_ -> _Administer Project_. 
+        
+    Under Versions, you'll see all the defined project versions. 
+    From the settings menu, choose *Release* on the version.
+
+12. Close all the issues included in the release: 
+    _Jira Project Home_ -> _Change Log_ -> Choose the released version. 
+        
+    From the issue list you have the option to bulk update all of the included issues. 
+    Just *Transition Issues* from *Resolved* to *Closed* and you are done!
+
+13. Update the Jackrabbit web site to point to the new release.
+
+14. Send the release announcement **once** the web site and download mirrors have been synced.
+
+
+Related Links
+-------------
+* http://www.apache.org/dev/release.html
+* http://www.apache.org/dev/release-signing.html
+* http://wiki.apache.org/incubator/SigningReleases
+* http://www.apache.org/dev/repository-faq.html
+
+  
+<a name="A"></a>
+Appendix A: Create and add your key to the Jackrabbit KEYS file
+---------------------------------------------------------------
+Follow these instructions to generate your code signing key and to add it to the Jackrabbit KEYS file.
+
+1. [Generate a code signing key][0] using your _@apache.org_ address as the email and `CODE SIGNING KEY` as the
+   comment.
+    
+2. The Jackrabbit KEYS file is managed in https://svn.apache.org/repos/asf/jackrabbit/dist/KEYS. To modify the file,
+   first checkout the `dist` directory:
+
+        svn checkout https://svn.apache.org/repos/asf/jackrabbit/dist
+    
+3. See the beginning of the KEYS file for instructions on how to append your key to the file.
+
+4. Once you've committed the changes, update the KEYS file on `people.apache.org`:
+
+        umask 002; svn update /www/www.apache.org/dist/jackrabbit
+    
+5. You are **DONE**, but to see the changes on http://www.apache.org/dist/jackrabbit/KEYS you must wait 2 hours
+
+You should get your key [linked to the Apache web of trust][1]. Once other people have signed your key, you can
+update the KEYS file with the signatures you've received.
+
+
+<a name="B"></a>
+Appendix B: Maven settings
+--------------------------
+
+    <settings>
+    ...
+      <servers>
+        <!-- To deploy a Jackrabbit snapshot -->
+        <server>
+          <id>apache.snapshots.https</id>
+          <username> <!-- YOUR APACHE SVN USERNAME --> </username>
+          <password> <!-- YOUR APACHE SVN PASSWORD --> </password>
+        </server>
+        <!-- To stage a Jackrabbit release -->
+        <server>
+          <id>apache.releases.https</id>
+          <username> <!-- YOUR APACHE SVN USERNAME --> </username>
+          <password> <!-- YOUR APACHE SVN PASSWORD --> </password>
+        </server>
+        ...
+        <profiles>
+            <profile>
+                <id>apache-release</id>
+                <servers>
+                    <server>
+                        <id> <!-- YOUR KEYNAME --> </id>
+                        <passphrase> <!-- CLEAR OR ENCRYPTED TEXT --> </passphrase>
+                    </server>
+                </servers>
+                <properties>
+                    <gpg.keyname> <!-- YOUR KEYNAME --> </gpg.keyname>
+                </properties>
+            </profile>
+          </profile>
+          ...
+        </profiles>
+      </servers>
+    </settings>
+
+<!-- references -->
+[0]: http://www.apache.org/dev/release-signing.html#generate
+[1]: http://www.apache.org/dev/release-signing.html#apache-wot
+[2]: https://repository.apache.org/index.html#stagingRepositories
+[3]: https://issues.apache.org/jira/browse/JCRVLT
+[4]: http://maven.apache.org/developers/release/releasing.html
diff --git a/trunk/src/site/markdown/import_package.md b/trunk/src/site/markdown/import_package.md
new file mode 100644
index 0000000..2e36b55
--- /dev/null
+++ b/trunk/src/site/markdown/import_package.md
@@ -0,0 +1,128 @@
+<!--
+   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.
+-->
+Generating import-package MANIFEST entries
+==========================================
+
+The Filevault content package maven plugin can analyze the classpath of the compiled classes, derived from the content and create an `import-package` MANIFEST entry. Although this is rather something to be expected in the OSGi world, declaring the java packages that the content potentially needs can help detecting deployment errors early.
+
+How it works
+------------
+_(todo: add more detailed explanation)_
+
+The generation of the `import-package` entry is performed in 3 steps:
+
+#### 1. generate classes
+1. JSP or HTL plugin transpile the scripts
+2. Maven compiler plugin compiles the generated java sources
+
+
+#### 2. analyze classes
+The classpath analysis is done in the `analyze-classes` goal:
+
+1. scan the java classes and extract the used java packages
+2. scan the dependencies and extract package version information from the MANIFEST if present
+3. cross reference the packages with the version information from the bundles
+4. write preliminary `import-package` entry to `${vault.generatedImportPackage}` 
+
+
+#### 3. post-process and merge with project properties
+The final step is performed in the `package` goal:
+
+1. read `${vault.generatedImportPackage}`
+2. merge with instructions in `<importPackage>`
+3. add `import-package` entry to `META-INF/MANIFEST.MF`
+
+
+Working with JSPs
+-----------------
+(todo)
+
+Working with HTL
+----------------
+
+Where as the HTL use classes provided through bundles or via java classes in the content are simple to handle, the HTL scripts needs more treatment. similar to the JSPs, the HTL maven plugin can be used to transpile the scripts to java and then the maven compiler will create the classes.
+
+### Note on the analyzed packages
+The transpiled HTL scripts will contain some sightly compiler and runtime references, which are not true dependencies of the scripts. Nevertheless, they are needed to compile the scripts for the validation and will end up in the analyzed packages. by default, the following packages are excluded from the final `import-package`:
+
+```
+org.apache.sling.scripting.sightly.compiler.expression.nodes
+org.apache.sling.scripting.sightly.java.compiler
+org.apache.sling.scripting.sightly.render
+```
+
+_Note: The excludes are present in the default value of the `<importPackage>` property and are lost if it is definedin the project. In this cases they need to be added manually._
+
+### Example configuration for HTL
+
+_note: at the time of writing, the HTL plugin wasn't released yet. version 1.0.15-SNAPSHOT or higher will be required._
+
+```
+<build>
+    <sourceDirectory>src/content/jcr_root</sourceDirectory>
+    <plugins>
+        <plugin>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>filevault-package-maven-plugin</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+            <extensions>true</extensions>
+            <configuration>
+                <filterSource>${basedir}/src/content/META-INF/vault/filter.xml</filterSource>
+            </configuration>
+        </plugin>
+        <plugin>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>htl-maven-plugin</artifactId>
+            <version>1.0.9-SNAPSHOT</version>
+            <executions>
+                <execution>
+                    <id>validate-scripts</id>
+                    <goals>
+                        <goal>validate</goal>
+                    </goals>
+                    <phase>generate-sources</phase>
+                    <configuration>
+                        <sourceDirectory>src/content/jcr_root</sourceDirectory>
+                        <includes>
+                            <include>**/*.html</include>
+                        </includes>
+                        <failOnWarnings>true</failOnWarnings>
+                        <generateJavaClasses>true</generateJavaClasses>
+                    </configuration>
+                </execution>
+            </executions>
+        </plugin>
+    </plugins>
+</build>
+
+<dependencies>
+    <!-- needed for HTL compilation validation -->
+    <dependency>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>org.apache.sling.scripting.sightly.compiler</artifactId>
+        <version>1.0.14</version>
+        <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>org.apache.sling.scripting.sightly.compiler.java</artifactId>
+        <version>1.0.15-SNAPSHOT</version>
+        <scope>provided</scope>
+    </dependency>
+</dependencies>
+```
+
diff --git a/trunk/src/site/markdown/index.md b/trunk/src/site/markdown/index.md
new file mode 100644
index 0000000..a00abc7
--- /dev/null
+++ b/trunk/src/site/markdown/index.md
@@ -0,0 +1,53 @@
+<!--
+   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.
+-->
+Introduction
+============
+
+Welcome to Apache Jackrabbit FileVault Package Maven Plugin.
+
+The Apache Jackrabbit FileVault package maven plugin is an Apache maven plugin that simplifies the creation of
+content package maven artifacts. The content packages can later be used to install content into a JCR repository
+using the Apache Jackrabbit FileVault packaging runtime.
+
+Apache Jackrabbit FileVault is a project of the Apache Software Foundation.
+
+Downloads
+---------
+The latest filevault package plugin sources are available for checkout from [svn]
+(https://svn.apache.org/repos/asf/jackrabbit/commons/filevault-package-maven-plugin/trunk), or you can [fork them]
+(https://github.com/apache/jackrabbit-filevault-package-maven-plugin) on GitHub.
+
+See also our [releases](http://jackrabbit.apache.org/downloads.html) on the Jackrabbit
+download page for slightly more stable versions of the codebase.
+
+Mailing Lists
+-------------
+
+To get involved with the Apache Jackrabbit project, start by having a
+look at our website and joining our mailing lists. For more details about
+Jackrabbit mailing lists as well as links to list archives, please see the [Mailing List](mail-lists.html) section.
+
+
+Latest development
+------------------
+See the [development overview](dev.html) page for more information.
+
+Credits
+-------
+
+See http://jackrabbit.apache.org/jackrabbit-team.html for the list of
+Jackrabbit committers and main contributors.
diff --git a/trunk/src/site/resources/css/site.css b/trunk/src/site/resources/css/site.css
new file mode 100644
index 0000000..849ae1c
--- /dev/null
+++ b/trunk/src/site/resources/css/site.css
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+tt {
+    white-space: nowrap;
+    border: 1px solid #eaeaea;
+    background-color: #f5f5f5;
+}
+pre {
+    font-size: 12px;
+}
+
diff --git a/trunk/src/site/site.xml b/trunk/src/site/site.xml
new file mode 100644
index 0000000..e321873
--- /dev/null
+++ b/trunk/src/site/site.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+  -->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.3.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.3.0 http://maven.apache.org/xsd/decoration-1.3.0.xsd"
+         name="Jackrabbit Filevault Package Maven Plugin">
+    <body>
+        <menu name="Overview">
+            <item name="Introduction" href="index.html"/>
+            <item name="Goals" href="plugin-info.html"/>
+            <item href="dev.html" name="Developing"/>
+        </menu>
+        <menu name="Documentation">
+            <item name="import-package generation" href="import_package.html"/>
+        </menu>
+        <menu name="Project Documentation">
+            <item href="project-summary.html" name="Project Summary"/>
+            <item href="license.html" name="Project License"/>
+            <item href="source-repository.html" name="Source Repository"/>
+            <item href="issue-tracking.html" name="Issue Tracking"/>
+            <item href="mail-lists.html" name="Mailing Lists"/>
+            <item href="dependencies.html" name="Dependencies"/>
+            <item href="plugin-management.html" name="Plugin Management"/>
+            <item href="plugins.html" name="Project Plugins"/>
+            <item href="distribution-management.html" name="Distribution Management"/>
+        </menu>
+        <menu name="Links">
+            <item href="http://jackrabbit.apache.org/filevault/" name="Apache Jackrabbit FileVault"/>
+            <item href="http://jackrabbit.apache.org/" name="Apache Jackrabbit"/>
+        </menu>
+    </body>
+
+    <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+    </skin>
+
+    <custom>
+        <fluidoSkin>
+            <sourceLineNumbersEnabled>true</sourceLineNumbersEnabled>
+            <topBarEnabled>true</topBarEnabled>
+            <sideBarEnabled>true</sideBarEnabled>
+            <gitHub>
+                <projectId>apache/jackrabbit-filevault-package-maven-plugin</projectId>
+                <ribbonOrientation>right</ribbonOrientation>
+            </gitHub>
+            <ohloh>
+                <projectId>jackrabbit-filevault-package-maven-plugin</projectId>
+            </ohloh>
+            <googlePlusOne/>
+        </fluidoSkin>
+    </custom>
+</project>
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/FileValidatorTest.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/FileValidatorTest.java
new file mode 100644
index 0000000..583fcde
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/FileValidatorTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import java.io.InputStream;
+
+import org.apache.jackrabbit.filevault.maven.packaging.FileValidator;
+import org.junit.Test;
+
+public class FileValidatorTest {
+
+    private static final String RESOURCE_DIR = "/oak-index/";
+
+    private InputStream load(String path) {
+        return getClass().getResourceAsStream(RESOURCE_DIR + path);
+    }
+
+    @Test
+    public void test_filter() throws Exception {
+        FileValidator validator = new FileValidator();
+        String path = "META-INF/vault/filter.xml";
+
+        validator.lookupIndexDefinitionInArtifact(load(path), path);
+
+        assertEquals(2, validator.indexPaths.size());
+        assertTrue(validator.indexPaths.contains("/oak:index/ccProfile"));
+        assertTrue(validator.indexPaths.contains("/apps/project/oak:index/indexDef"));
+    }
+
+    @Test
+    public void test_index_at_root() throws Exception {
+        FileValidator validator = new FileValidator();
+        String path = "jcr_root/_oak_index/testindex/.content.xml";
+
+        validator.lookupIndexDefinitionInArtifact(load(path), path);
+
+        assertEquals(1, validator.foundIndexes.size());
+        assertEquals(path, validator.foundIndexes.get("/oak:index/testindex"));
+    }
+
+    @Test
+    public void test_index_at_deep_path() throws Exception {
+        FileValidator validator = new FileValidator();
+        String path = "jcr_root/apps/project/_oak_index/.content.xml";
+
+        validator.lookupIndexDefinitionInArtifact(load(path), path);
+
+        assertEquals(1, validator.foundIndexes.size());
+        assertEquals(path, validator.foundIndexes.get("/apps/project/oak:index/indexDef"));
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/impl/FilterTest.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/impl/FilterTest.java
new file mode 100644
index 0000000..bbd2b01
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/impl/FilterTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import junit.framework.TestCase;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Test the string filter
+ */
+public class FilterTest extends TestCase {
+
+    private static final String[] TEST_STRINGS = {
+            "com.day.cq",
+            "foo-bar",
+            "com.day.cq.impl",
+            "artifact1-test",
+            "artifact2-test"
+    };
+
+    private static final TestSet[] TESTS = new TestSet[]{
+        new TestSet(
+                "Exact",
+                "com.day.cq",
+                new String[]{
+                        "com.day.cq"
+                }),
+            new TestSet(
+                "Exact Multiple",
+                "com.day.cq, com.day.cq.impl",
+                new String[]{
+                        "com.day.cq",
+                        "com.day.cq.impl"
+                }),
+            new TestSet(
+                "Exclude Single",
+                "~com.day.cq",
+                new String[]{
+                        "foo-bar",
+                        "com.day.cq.impl",
+                        "artifact1-test",
+                        "artifact2-test"
+                }),
+            new TestSet(
+                "Exclude Multiple",
+                "~com.day.cq,~foo-bar",
+                new String[]{
+                        "com.day.cq.impl",
+                        "artifact1-test",
+                        "artifact2-test"
+                }),
+            new TestSet(
+                "Exclude Pattern",
+                "~/.*-test/",
+                new String[]{
+                        "com.day.cq",
+                        "foo-bar",
+                        "com.day.cq.impl"
+                }),
+            new TestSet(
+                "Exclude Subpackage",
+                "~/com\\.day\\.cq(.*)?/",
+                new String[]{
+                        "foo-bar",
+                        "artifact1-test",
+                        "artifact2-test"
+                })
+    };
+
+    public void testPatterns() {
+        for (TestSet test: TESTS) {
+            StringFilterSet set = new StringFilterSet();
+            set.addEntries(test.pattern);
+            assertEquals(test.name, test.result, getMatching(set, TEST_STRINGS));
+        }
+    }
+
+    private String[] getMatching(StringFilterSet set, String[] testStrings) {
+        List<String> ret = new LinkedList<String>();
+        for (String name: testStrings) {
+            if (set.contains(name)) {
+                ret.add(name);
+            }
+        }
+        return ret.toArray(new String[ret.size()]);
+    }
+
+    private void assertEquals(String name, String[] expected, String[] test) {
+        assertEquals(name, expected.length, test.length);
+        for (int i=0; i< test.length; i++) {
+            assertEquals(name, expected[i], test[i]);
+        }
+    }
+
+    private static class TestSet {
+        private final String name;
+
+        private final String pattern;
+
+        private final String[] result;
+
+        private TestSet(String name, String pattern, String[] result) {
+            this.name = name;
+            this.pattern = pattern;
+            this.result = result;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageInfoTest.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageInfoTest.java
new file mode 100644
index 0000000..2639516
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/impl/PackageInfoTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.impl;
+
+import java.io.File;
+
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PackageInfo;
+import org.apache.jackrabbit.filevault.maven.packaging.impl.PackageType;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class PackageInfoTest {
+
+    private static final String RESOURCE_DIR = "/test-packages/";
+
+    private File load(String path) {
+        return new File(getClass().getResource(RESOURCE_DIR + path).getFile());
+    }
+
+    @Test
+    public void test_pkg_with_filter_and_manifest() throws Exception {
+        PackageInfo info = PackageInfo.read(load("pkg-with-filter-and-manifest.zip"));
+        assertNotNull("PackageInfo", info);
+        assertEquals("PackageId", "com.day.jcr.vault.unit:vault-plugin-test-pkg:1.0.0-SNAPSHOT", info.getId().toString());
+        assertEquals("filter size", 1, info.getFilter().getFilterSets().size());
+        assertTrue("contains filter", info.getFilter().contains("/libs/granite/replication"));
+        assertEquals("package type", PackageType.APPLICATION, info.getPackageType());
+    }
+
+    @Test
+    public void test_pkg_with_no_manifest() throws Exception {
+        PackageInfo info = PackageInfo.read(load("pkg-with-no-manifest.zip"));
+        assertNotNull("PackageInfo", info);
+        assertEquals("PackageId", "com.day.jcr.vault.unit:vault-plugin-test-pkg:1.0.0-SNAPSHOT", info.getId().toString());
+        assertEquals("filter size", 1, info.getFilter().getFilterSets().size());
+        assertTrue("contains filter", info.getFilter().contains("/libs/granite/replication"));
+        assertEquals("package type", PackageType.MIXED, info.getPackageType());
+    }
+
+    @Test
+    public void test_non_valid_package() throws Exception {
+        PackageInfo info = PackageInfo.read(load("non-valid-package.zip"));
+        assertNull("PackageInfo", info);
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/CheckSignatureIT.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/CheckSignatureIT.java
new file mode 100644
index 0000000..ce5d5a6
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/CheckSignatureIT.java
@@ -0,0 +1,33 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.it;
+
+import org.junit.Test;
+
+public class CheckSignatureIT {
+
+    /**
+     * The check-signature goal ends up in a NPE in the animal-sniffer SignatureChecker, when the animal-sniffer plugin
+     * version is 1.14 in the build, breaking the build:
+     */
+    @Test
+    public void package_builds() throws Exception {
+        new ProjectBuilder()
+                .setTestProjectDir("/check-signature")
+                .build();
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/DefaultProjectIT.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/DefaultProjectIT.java
new file mode 100644
index 0000000..6c93442
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/DefaultProjectIT.java
@@ -0,0 +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.jackrabbit.filevault.maven.packaging.it;
+
+import java.io.IOException;
+
+import org.apache.maven.it.VerificationException;
+import org.junit.Test;
+
+public class DefaultProjectIT {
+
+    private static final String TEST_PROJECT_NAME = "/default-test-projects/";
+
+    private void verify(String projectName) throws VerificationException, IOException {
+        new ProjectBuilder()
+                .setTestProjectDir(TEST_PROJECT_NAME + projectName)
+                .build()
+                .verifyExpectedFiles()
+                .verifyExpectedFilesOrder()
+                .verifyExpectedManifest();
+
+    }
+
+    @Test
+    public void generic_project_package_contains_correct_files() throws Exception {
+        verify("generic");
+    }
+
+    @Test
+    public void generic_with_builtcd_project_package_contains_correct_files() throws Exception {
+        verify("generic-with-builtcd");
+    }
+
+    @Test
+    public void resource_project_package_contains_correct_files() throws Exception {
+        verify("resource");
+    }
+
+    @Test
+    public void unusual_jcr_root_package_contains_correct_files() throws Exception {
+        verify("generic-unusal-jcrroot");
+    }
+
+    @Test
+    public void generic_empty_directories() throws Exception {
+        new ProjectBuilder()
+                .setTestProjectDir(TEST_PROJECT_NAME + "generic-empty-directories")
+                .build()
+                .verifyExpectedFiles();
+    }
+
+    @Test
+    public void resource_empty_directories() throws Exception {
+        new ProjectBuilder()
+                .setTestProjectDir(TEST_PROJECT_NAME + "resource-empty-directories")
+                .build()
+                .verifyExpectedFiles();
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/DependencyCheckIT.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/DependencyCheckIT.java
new file mode 100644
index 0000000..dd8b1be
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/DependencyCheckIT.java
@@ -0,0 +1,62 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.it;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class DependencyCheckIT {
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"fail-missing-deps", true},
+                {"fail-missing-deps-implicit", true},
+                {"fail-no-maven-deps", true},
+                {"fail-no-contains", true},
+                {"fail-no-cover", true},
+                {"no-errors", false},
+                {"repo-structure-pkg", false},
+                {"no-error-cleanup", false},
+                {"no-error-cleanup-filter", false}
+        });
+    }
+
+    private final String projectName;
+
+    private final boolean expectToFail;
+
+    public DependencyCheckIT(String projectName, boolean expectToFail) {
+        this.projectName = projectName;
+        this.expectToFail = expectToFail;
+    }
+
+    @Test
+    public void test_dependency_checks() throws Exception {
+        new ProjectBuilder()
+                .setTestProjectsRoot(new File("target/test-classes/test-projects/validate-deps-projects"))
+                .setTestProjectDir(projectName)
+                .setBuildExpectedToFail(expectToFail)
+                .build();
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/FilterIT.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/FilterIT.java
new file mode 100644
index 0000000..0b17a3f
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/FilterIT.java
@@ -0,0 +1,127 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.it;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.shared.utils.io.FileUtils;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests the behaviour of package filters.
+ */
+public class FilterIT {
+
+    private void verify(String projectName, boolean expectToFail, String ... goals) throws VerificationException, IOException {
+        new ProjectBuilder()
+                .setTestProjectDir("filter-tests/" + projectName)
+                .setTestGoals(goals)
+                .setBuildExpectedToFail(expectToFail)
+                .build()
+                .verifyExpectedFilter();
+    }
+
+    /**
+     * Tests if a pom with no filter definition at all fails.
+     */
+    @Test
+    public void test_no_filter_fails() throws Exception {
+        verify("no-filter-fails", true);
+    }
+
+    /**
+     * Tests if a pom with no filter definition but with a @{code failOnEmptyFilter} set to {@code false} works.
+     */
+    @Test
+    public void test_no_filter_with_prop_ok() throws Exception {
+        verify("no-filter-with-prop-ok", false);
+    }
+
+    /**
+     * Tests if a project with an implicit filter defined in META-INF/vault/filter.xml is correctly built
+     */
+    @Test
+    public void test_implicit_filter() throws Exception {
+        verify("implicit-filter", false);
+    }
+
+    /**
+     * Tests if a project with an inline filter properly generates the filter.xml
+     */
+    @Test
+    public void test_inline_filter() throws Exception {
+        verify("inline-filter", false);
+    }
+
+    /**
+     * Tests if a project with an inline filter and a filter source properly generates the merged filter.xml
+     */
+    @Test
+    public void test_merge_inline_filter() throws Exception {
+        verify("merge-inline-filter", false);
+    }
+
+    /**
+     * Tests if a project with an filter source and no inline filters keeps the filter comments.
+     */
+    @Test
+    public void test_retain_filter_source() throws Exception {
+        verify("retain-filter-source", false);
+    }
+
+    /**
+     * Tests if a project with no filter but a prefix creates the default root
+     */
+    @Test
+    public void test_no_filter_with_prefix() throws Exception {
+        verify("no-filter-with-prefix", false);
+    }
+
+    /**
+     * Tests if a project with an inline filter and an implicit filter correctly uses the inline filters.
+     */
+    @Test
+    public void test_inline_and_implicit_filter_fails() throws Exception {
+        verify("inline-and-implicit-fails", true);
+    }
+
+    /**
+     * Tests if a project with an inline filter executed twice works w/o clean
+     */
+    @Test
+    public void test_inline_filter_twice() throws Exception {
+        // first execute with default goals
+        final File projectDir = new File("target/test-classes/test-projects/filter-tests/inline-filter-twice");
+        FileUtils.copyFile(new File(projectDir, "pom1.xml"), new File(projectDir, "pom.xml"));
+        FileUtils.copyFile(new File(projectDir, "expected-filter1.xml"), new File(projectDir, "expected-filter.xml"));
+        verify("inline-filter-twice", false);
+
+        // copy marker to 'target' to ensure that clean is not executed
+        File marker = new File(projectDir, "target/marker.xml");
+        FileUtils.copyFile(new File(projectDir, "pom1.xml"), marker);
+
+        FileUtils.copyFile(new File(projectDir, "pom2.xml"), new File(projectDir, "pom.xml"));
+        FileUtils.copyFile(new File(projectDir, "expected-filter2.xml"), new File(projectDir, "expected-filter.xml"));
+        verify("inline-filter-twice", false, "package");
+
+        assertTrue("Marker file still exists.", marker.exists());
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ManifestGenerationIT.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ManifestGenerationIT.java
new file mode 100644
index 0000000..7fc28c0
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ManifestGenerationIT.java
@@ -0,0 +1,93 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.it;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.maven.it.VerificationException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ManifestGenerationIT {
+
+    private ProjectBuilder verify(String projectName) throws IOException, VerificationException {
+        return new ProjectBuilder()
+                .setTestProjectDir("manifest-generation/" + projectName)
+                .build()
+                .verifyExpectedManifest();
+    }
+
+    @Test
+    public void simple_manifest_generation() throws Exception {
+        verify("simple");
+    }
+
+    @Test
+    public void bundle_manifest_generation() throws Exception {
+        verify("with-bundles");
+    }
+
+    @Test
+    public void code_manifest_generation() throws Exception {
+        verify("with-code");
+    }
+
+    @Test
+    public void unused_manifest_generation() throws Exception {
+        verify("with-unused-dependencies");
+    }
+
+    /**
+     * Tests if a unused bundle dependency define it a parent pom doesn't show up in the unused bundles report.
+     * see JCRVLT-214
+     */
+    @Test
+    public void unused_parent_manifest_generation() throws Exception {
+        ProjectBuilder builder = verify("with-unused-parent-dependencies");
+
+        // also check if unused parent is not listed
+        List<String> unusedBundles = new LinkedList<String>();
+        boolean recording = false;
+        for (String line: builder.getBuildOutput()) {
+            if (line.contains("------")) {
+                continue;
+            }
+            if (line.contains(" unused bundles")) {
+                recording = true;
+                continue;
+            }
+            if (recording) {
+                final String trimmed = line.trim();
+                if (trimmed.isEmpty()) {
+                    break;
+                }
+                unusedBundles.add(trimmed);
+            }
+        }
+        String[] unused = unusedBundles.toArray(new String[unusedBundles.size()]);
+        Arrays.sort(unused);
+
+        // the project should have at 1 unused bundle but not the one from the parent
+        assertTrue("unused bundles > 0", unused.length > 0);
+        assertEquals("unused bundle", "[org.jsoup:jsoup:jar:1.10.3]", Arrays.toString(unused));
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/PackageTypesIT.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/PackageTypesIT.java
new file mode 100644
index 0000000..c1e9109
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/PackageTypesIT.java
@@ -0,0 +1,82 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.it;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.shared.utils.StringUtils;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class PackageTypesIT {
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"application", false},
+                {"application-sourced", false},
+                {"application-cleanup", false},
+                {"content", false},
+                {"mixed", false},
+                {"container", false},
+                {"invalid", true}});
+    }
+
+    private final String type;
+
+    private final String projectName;
+
+    private final boolean expectToFail;
+
+    public PackageTypesIT(String type, boolean expectToFail) {
+        this.projectName = type;
+        this.type = StringUtils.chomp(type, "-");
+        this.expectToFail = expectToFail;
+    }
+
+    private void verify(File projectDir) throws VerificationException, IOException {
+        new ProjectBuilder()
+                .setTestProjectDir(projectDir)
+                .setProperty("test.packageType", type)
+                .setBuildExpectedToFail(expectToFail)
+                .build()
+                .verifyPackageProperty("packageType", type);
+    }
+
+
+    @Test
+    public void test_package_type() throws Exception {
+        final File projectDir = new File("target/test-classes/test-projects/package-types");
+        verify(projectDir);
+    }
+
+    @Test
+    public void test_package_type_autodetect() throws Exception {
+        // ignore invalid test
+        Assume.assumeTrue(!expectToFail);
+
+        final File projectDir = new File("target/test-classes/test-projects/package-type-auto/" + projectName);
+        verify(projectDir);
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java
new file mode 100644
index 0000000..50c5cf1
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java
@@ -0,0 +1,305 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.it;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.it.Verifier;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.shared.utils.StringUtils;
+import org.apache.maven.shared.utils.io.FileUtils;
+import org.apache.maven.shared.utils.io.IOUtil;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.hamcrest.Matchers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import aQute.bnd.header.Attrs;
+import aQute.bnd.header.Parameters;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Helper class to build and verify a maven project.
+ */
+public class ProjectBuilder {
+
+    /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(ProjectBuilder.class);
+
+    private static final Set<String> IGNORED_MANIFEST_ENTRIES = new HashSet<String>(Arrays.asList("Build-Jdk", "Built-By"));
+
+    static final String TEST_PROJECTS_ROOT = "target/test-classes/test-projects";
+
+    static final String TEST_PACKAGE_DEFAULT_NAME = "target/package-plugin-test-pkg-1.0.0-SNAPSHOT.zip";
+
+    private File testProjectsRoot;
+
+    private File testProjectDir;
+
+    private File testPackageFile;
+
+    private Properties testProperties;
+
+    private String[] testGoals = {"clean", "package"};
+
+    private List<String> pkgZipEntries;
+
+    private File expectedFilesFile;
+
+    private File expectedOrderFile;
+
+    private File expectedManifestFile;
+
+    private File expectedFilterFile;
+
+    private File logTxtFile;
+
+    private boolean buildExpectedToFail;
+
+    public ProjectBuilder() {
+        testProjectsRoot = new File(TEST_PROJECTS_ROOT);
+        testProperties = new Properties();
+
+        testProperties.put("plugin.version", getPluginVersion());
+        testProperties.put("testcontent.directory", new File("target/test-classes/test-content").getAbsolutePath());
+    }
+
+    /**
+     * Retrieves the version of the {@code filevault-package-maven-plugin} of the current project. The version is used in the
+     * test poms so that the cli build uses the current plugin. Usually the version is set via the system property
+     * {@code plugin.version} via the failsafe plugin. If the property is missing the method tries to read it from the
+     * {@code pom.xml} of the project. this is useful when running the tests in an IDE.
+     *
+     * @return the version of the current {@code filevault-package-maven-plugin}
+     * @throws IllegalArgumentException if the version cannot be determined.
+     */
+    private String getPluginVersion() {
+        String pluginVersion  = System.getProperty("plugin.version");
+        if (pluginVersion == null) {
+            try {
+                // try to read from project
+                MavenXpp3Reader reader = new MavenXpp3Reader();
+                Model model = reader.read(new FileReader("pom.xml"));
+                pluginVersion = model.getVersion();
+            } catch (IOException | XmlPullParserException e) {
+                log.error("Unable to read version from pom", e);
+            }
+        }
+        if (pluginVersion == null) {
+            throw new IllegalArgumentException("Unable to detect plugin.version");
+        }
+        return pluginVersion;
+    }
+
+    public ProjectBuilder setTestProjectsRoot(File testProjectsRoot) {
+        if (testProjectDir != null) {
+            throw new IllegalArgumentException("projects root can't be changed after projects dir is set.");
+        }
+        this.testProjectsRoot = testProjectsRoot;
+        return this;
+    }
+
+    public ProjectBuilder setTestProjectDir(File testProjectDir) {
+        this.testProjectDir = testProjectDir;
+        this.testPackageFile = new File(testProjectDir, TEST_PACKAGE_DEFAULT_NAME);
+
+        // if we ever need different files, just create the setters.
+        this.expectedFilesFile = new File(testProjectDir, "expected-files.txt");
+        this.expectedOrderFile = new File(testProjectDir, "expected-file-order.txt");
+        this.expectedManifestFile = new File(testProjectDir, "expected-manifest.txt");
+        this.expectedFilterFile = new File(testProjectDir, "expected-filter.xml");
+        this.logTxtFile = new File(testProjectDir, "log.txt");
+        return this;
+    }
+
+    public ProjectBuilder setTestProjectDir(String relPath) {
+        return setTestProjectDir(new File(testProjectsRoot, relPath));
+    }
+
+    public ProjectBuilder setTestPackageFile(File testPackageFile) {
+        this.testPackageFile = testPackageFile;
+        return this;
+    }
+
+    public File getTestPackageFile() {
+        return testPackageFile;
+    }
+
+    public ProjectBuilder setTestGoals(String ... testGoals) {
+        if (testGoals != null && testGoals.length != 0) {
+            this.testGoals = testGoals;
+        }
+        return this;
+    }
+
+    public ProjectBuilder setBuildExpectedToFail(boolean buildExpectedToFail) {
+        this.buildExpectedToFail = buildExpectedToFail;
+        return this;
+    }
+
+    public ProjectBuilder setProperty(String name, String value) {
+        testProperties.put(name, value);
+        return this;
+    }
+
+    public ProjectBuilder build() throws VerificationException, IOException {
+        Verifier verifier = new Verifier(testProjectDir.getAbsolutePath());
+        verifier.setSystemProperties(testProperties);
+        verifier.setDebug(true);
+        verifier.setAutoclean(false);
+
+        try {
+            verifier.executeGoals(Arrays.asList(testGoals));
+            assertFalse("Build expected to fail ", buildExpectedToFail);
+        } catch (VerificationException e) {
+            if (buildExpectedToFail) {
+                return this;
+            }
+            throw e;
+        } finally {
+            verifier.resetStreams();
+        }
+
+        assertTrue("Project generates package file", testPackageFile.exists());
+
+        // read zip
+        pkgZipEntries = new ArrayList<String>();
+        try (JarFile jar = new JarFile(testPackageFile)) {
+            Enumeration<JarEntry> e = jar.entries();
+            while (e.hasMoreElements()) {
+                pkgZipEntries.add(e.nextElement().getName());
+            }
+        }
+        // ensure that MANIFEST.MF is first entry
+        String first = pkgZipEntries.get(0);
+        if ("META-INF/".equals(first)) {
+            first = pkgZipEntries.get(1);
+        }
+        assertEquals("MANIFEST.MF must be first entry", "META-INF/MANIFEST.MF", first);
+
+        return this;
+    }
+
+    public ProjectBuilder verifyPackageProperty(String key, String value) throws IOException {
+        if (buildExpectedToFail) {
+            return this;
+        }
+        ZipFile zip = new ZipFile(testPackageFile);
+        ZipEntry propertiesFile = zip.getEntry("META-INF/vault/properties.xml");
+        assertThat(propertiesFile, notNullValue());
+
+        Properties properties = new Properties();
+        properties.loadFromXML(zip.getInputStream(propertiesFile));
+
+        assertEquals("Property '" + key + "' has correct value", properties.getProperty(key), value);
+        return this;
+    }
+
+    public ProjectBuilder verifyExpectedManifest() throws IOException {
+        final String expected = FileUtils.fileRead(expectedManifestFile);
+        JarFile jar = new JarFile(testPackageFile);
+        List<String> entries = new ArrayList<String>();
+        for (Map.Entry<Object, Object> e: jar.getManifest().getMainAttributes().entrySet()) {
+            String key = e.getKey().toString();
+            if (IGNORED_MANIFEST_ENTRIES.contains(key)) {
+                continue;
+            }
+            if ("Import-Package".equals(key)) {
+                // split export package so that we have a sorted set
+                Parameters params = new Parameters(e.getValue().toString());
+                for (Map.Entry<String, Attrs> entry : params.entrySet()) {
+                    entries.add(key + ":" + entry.getKey() + ";" + entry.getValue());
+                }
+                continue;
+            }
+            entries.add(e.getKey() + ":" + e.getValue());
+        }
+        Collections.sort(entries);
+        String result = StringUtils.join(entries.iterator(),"\n");
+        assertEquals("Manifest", expected, result);
+        return this;
+    }
+
+    public ProjectBuilder verifyExpectedFiles() throws IOException {
+        // first check that only the expected entries are there in the package (regardless of the order)
+        List<String> expectedEntries = Files.readAllLines(expectedFilesFile.toPath(), StandardCharsets.UTF_8);
+        assertEquals("Package contains the expected entry names",
+                toTidyString(expectedEntries),
+                toTidyString(pkgZipEntries));
+        return this;
+    }
+
+    public ProjectBuilder verifyExpectedFilesOrder() throws IOException {
+        List<String> expectedEntriesInOrder= Files.readAllLines(expectedOrderFile.toPath(), StandardCharsets.UTF_8);
+        assertThat("Order of entries within package", pkgZipEntries, Matchers.containsInRelativeOrder(expectedEntriesInOrder.toArray()));
+        return this;
+    }
+
+    public ProjectBuilder verifyExpectedFilter() throws IOException {
+        if (buildExpectedToFail) {
+            return this;
+        }
+        ZipFile zip = new ZipFile(testPackageFile);
+        ZipEntry entry = zip.getEntry("META-INF/vault/filter.xml");
+        assertNotNull("package has a filter.xml", entry);
+        String result = IOUtil.toString(zip.getInputStream(entry), "utf-8");
+        String expected = FileUtils.fileRead(expectedFilterFile);
+        assertEquals("filter.xml is correct", expected, result);
+        return this;
+    }
+
+    public List<String> getBuildOutput() throws IOException {
+        return Files.readAllLines(logTxtFile.toPath(), StandardCharsets.UTF_8);
+    }
+
+    private String toTidyString(List<String> lines) {
+        String[] copy = lines.toArray(new String[lines.size()]);
+        Arrays.sort(copy);
+        StringBuilder buf = new StringBuilder();
+        for (String line: copy) {
+            buf.append(line).append("\n");
+        }
+        return buf.toString();
+    }
+}
diff --git a/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/PropertyConfigurationIT.java b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/PropertyConfigurationIT.java
new file mode 100644
index 0000000..f1b167d
--- /dev/null
+++ b/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/PropertyConfigurationIT.java
@@ -0,0 +1,34 @@
+/*
+ * 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.jackrabbit.filevault.maven.packaging.it;
+
+import org.junit.Test;
+
+public class PropertyConfigurationIT {
+
+    /**
+     * Tests if the property.xml contains the description from the plugin config and not the project.
+     */
+    @Test
+    public void test_that_description_can_be_overridden_in_properties() throws Exception {
+        new ProjectBuilder()
+                .setTestProjectDir("override-description")
+                .build()
+                .verifyPackageProperty("description", "Description from plugin");
+
+    }
+}
diff --git a/trunk/src/test/resources/oak-index/META-INF/vault/filter.xml b/trunk/src/test/resources/oak-index/META-INF/vault/filter.xml
new file mode 100644
index 0000000..6f12b2d
--- /dev/null
+++ b/trunk/src/test/resources/oak-index/META-INF/vault/filter.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/oak:index/ccProfile" mode="merge"/>
+    <filter root="/apps/project/oak:index/indexDef"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/oak-index/jcr_root/_oak_index/testindex/.content.xml b/trunk/src/test/resources/oak-index/jcr_root/_oak_index/testindex/.content.xml
new file mode 100644
index 0000000..7af54e5
--- /dev/null
+++ b/trunk/src/test/resources/oak-index/jcr_root/_oak_index/testindex/.content.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+
+          jcr:primaryType="{Name}oak:QueryIndexDefinition"
+          name="ccProfile"
+          includedPaths="[/home]"
+          evaluatePathRestrictions="{Boolean}true"
+
+          type="lucene"
+          async="async"
+          compatVersion="{Long}2"
+          indexPath="/oak:index/ccProfile"
+          reindex="{Boolean}true">
+
+    <indexRules
+        jcr:primaryType="{Name}nt:unstructured">
+
+        <!-- profile-cc nodes have no specified node type
+             currently, nt:unstructured is used, but we rather
+             search based on the node name (indexNodeName = true) -->
+        <nt:base
+            jcr:primaryType="{Name}nt:unstructured"
+            indexNodeName="{Boolean}true">
+            <properties
+                jcr:primaryType="{Name}nt:unstructured">
+
+                <!-- email is searched using jcr:like() -->
+                <prop0 name="email"       propertyIndex="{Boolean}true" jcr:primaryType="{Name}nt:unstructured"/>
+
+                <!-- following are full-text searched using jcr:contains() -->
+                <prop1 name="givenName"   analyzed="{Boolean}true"      jcr:primaryType="{Name}nt:unstructured"/>
+                <prop2 name="familyName"  analyzed="{Boolean}true"      jcr:primaryType="{Name}nt:unstructured"/>
+                <prop3 name="displayName" analyzed="{Boolean}true"      jcr:primaryType="{Name}nt:unstructured"/>
+
+            </properties>
+        </nt:base>
+
+    </indexRules>
+
+</jcr:root>
diff --git a/trunk/src/test/resources/oak-index/jcr_root/apps/project/_oak_index/.content.xml b/trunk/src/test/resources/oak-index/jcr_root/apps/project/_oak_index/.content.xml
new file mode 100644
index 0000000..b8480f8
--- /dev/null
+++ b/trunk/src/test/resources/oak-index/jcr_root/apps/project/_oak_index/.content.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+          >
+    <indexDef
+
+          jcr:primaryType="oak:QueryIndexDefinition"
+          name="ccProfile"
+          includedPaths="[/home]"
+          evaluatePathRestrictions="{Boolean}true"
+
+          type="lucene"
+          async="async"
+          compatVersion="{Long}2"
+          indexPath="/oak:index/ccProfile"
+          reindex="{Boolean}true">
+    </indexDef>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-content/test-package.zip b/trunk/src/test/resources/test-content/test-package.zip
new file mode 100644
index 0000000..ba04568
--- /dev/null
+++ b/trunk/src/test/resources/test-content/test-package.zip
Binary files differ
diff --git a/trunk/src/test/resources/test-packages/non-valid-package.zip b/trunk/src/test/resources/test-packages/non-valid-package.zip
new file mode 100644
index 0000000..7ce9cef
--- /dev/null
+++ b/trunk/src/test/resources/test-packages/non-valid-package.zip
Binary files differ
diff --git a/trunk/src/test/resources/test-packages/pkg-with-filter-and-manifest.zip b/trunk/src/test/resources/test-packages/pkg-with-filter-and-manifest.zip
new file mode 100644
index 0000000..a98cd4a
--- /dev/null
+++ b/trunk/src/test/resources/test-packages/pkg-with-filter-and-manifest.zip
Binary files differ
diff --git a/trunk/src/test/resources/test-packages/pkg-with-no-manifest.zip b/trunk/src/test/resources/test-packages/pkg-with-no-manifest.zip
new file mode 100644
index 0000000..44625b6
--- /dev/null
+++ b/trunk/src/test/resources/test-packages/pkg-with-no-manifest.zip
Binary files differ
diff --git a/trunk/src/test/resources/test-projects/check-signature/pom.xml b/trunk/src/test/resources/test-projects/check-signature/pom.xml
new file mode 100644
index 0000000..02f14f2
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/check-signature/pom.xml
@@ -0,0 +1,64 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <!-- content package plugin -->
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnEmptyFilter>false</failOnEmptyFilter>
+                    <signature>
+                        <groupId>org.codehaus.mojo.signature</groupId>
+                        <artifactId>java18</artifactId>
+                        <version>1.0</version>
+                    </signature>
+                    <embeddeds>
+                        <embedded>
+                            <groupId>javax.jcr</groupId>
+                            <artifactId>jcr</artifactId>
+                            <target>/libs/install</target>
+                        </embedded>
+                    </embeddeds>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    
+    <dependencies>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/expected-files.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/expected-files.txt
new file mode 100644
index 0000000..43b7a3b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/expected-files.txt
@@ -0,0 +1,21 @@
+META-INF/
+META-INF/MANIFEST.MF
+META-INF/maven/
+META-INF/maven/org.apache.jackrabbit.filevault/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.properties
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.xml
+META-INF/vault/
+META-INF/vault/config.xml
+META-INF/vault/filter.xml
+META-INF/vault/properties.xml
+META-INF/vault/settings.xml
+jcr_root/
+jcr_root/apps/
+jcr_root/apps/wcm/
+jcr_root/apps/wcm/core/
+jcr_root/apps/wcm/core/.content.xml
+jcr_root/apps/wcm/core/content/
+jcr_root/apps/wcm/core/content/.content.xml
+jcr_root/apps/wcm/core/content/siteadmin.xml
+jcr_root/apps/wcm/core/empty_directory/
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/content/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/content/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/content/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/content/siteadmin.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/content/siteadmin.xml
new file mode 100755
index 0000000..5984d80
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/content/siteadmin.xml
@@ -0,0 +1,764 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:mixinTypes="[cq:Console]"
+    jcr:primaryType="cq:Widget"
+    jcr:title="AEM WCM"
+    sling:redirect="{Boolean}false"
+    sling:resourceType="cq/ui/components/widget"
+    sling:vanityOrder="{Long}500"
+    sling:vanityPath="/siteadmin"
+    consoleDescription="Create and manage multiple websites."
+    consoleTitle="Websites"
+    historyLink="/bin/wcmcommand?cmd=open&amp;path=${resource.path}"
+    historyResourceTypes="[cq:Page]"
+    historyShow="{Boolean}true"
+    historyTitle="Recently used pages"
+    iconClass="siteadmin"
+    id="cq-siteadmin"
+    jsLibs="[cq.wcm.admin]"
+    noSearch="{Boolean}true"
+    tabTitle="Websites"
+    treeAutoExpandMax="100"
+    xtype="siteadmin">
+    <grid jcr:primaryType="nt:unstructured">
+        <assets
+            jcr:primaryType="nt:unstructured"
+            pageSize="15"
+            pageText="Assets {0} - {1} of {2}"
+            pathRegex="\\/content\\/dam(/.*)?"
+            storeProxySuffix=".assets.json"
+            storeReaderFields="[index,title,label,lockedBy,type,width,height,size,inWorkflow,replication,scheduledTasks,numberer,workflows,lastModified,lastModifiedBy,inProgress,ck]">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <thumbnail
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}false"
+                    usePredefined="thumbnail"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}true"
+                    usePredefined="title"
+                    xssProtect="true"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <status
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="status"
+                    xtype="gridcolumn"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="workflow"
+                    xtype="gridcolumn"/>
+                <width
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="width"
+                    xtype="gridcolumn"/>
+                <height
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="height"
+                    xtype="gridcolumn"/>
+                <size
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="size"
+                    xtype="gridcolumn"/>
+            </columns>
+        </assets>
+    </grid>
+    <actions jcr:primaryType="nt:unstructured">
+        <create
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-create"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-create-icon"
+            split="{Boolean}true"
+            text="New...">
+            <menu jcr:primaryType="nt:unstructured">
+                <createPage
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-page"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createPage"
+                    iconCls="cq-siteadmin-create-page-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Page..."/>
+                <createSite
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-site"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createSite"
+                    iconCls="cq-siteadmin-create-site-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Site..."/>
+                <createLiveCopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-livecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLiveCopy"
+                    iconCls="cq-siteadmin-create-livecopy-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Live Copy..."/>
+                <createLaunch
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-launch"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLaunch"
+                    iconCls="cq-siteadmin-create-launch-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Launch..."/>
+                <separator0
+                    jcr:primaryType="nt:unstructured"
+                    value="-"
+                    xtype="separator"/>
+                <createFile
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-file"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.uploadFiles"
+                    iconCls="cq-siteadmin-create-file-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New File..."/>
+                <createFolder
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-folder"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createFolder"
+                    iconCls="cq-siteadmin-create-folder-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Folder..."/>
+            </menu>
+        </create>
+        <open
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-open"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openPages"
+            iconCls="cq-siteadmin-open-icon"
+            isDefaultAction="{Boolean}true"
+            privileges="[read]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Open"/>
+        <separator0
+            jcr:primaryType="nt:unstructured"
+            value="-"
+            xtype="separator"/>
+        <copy
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-copy"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.copyPages"
+            target="CQ.wcm.SiteAdmin.getAnyTarget"
+            text="Copy"/>
+        <paste
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-paste"
+            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canPaste,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            forceCheck="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.pastePages"
+            privileges="[create]"
+            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+            text="Paste"/>
+        <delete
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-delete"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.deletePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getAllTargets"
+            text="Delete"/>
+        <separator1
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <move
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-move"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.movePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getSingleTarget"
+            text="Move..."/>
+        <separator2
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <activate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-activate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-activate-icon"
+            split="{Boolean}true"
+            text="Activate">
+            <menu jcr:primaryType="nt:unstructured">
+                <activateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.activatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Activate"/>
+                <activateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Activate Later..."/>
+            </menu>
+        </activate>
+        <deactivate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-deactivate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-deactivate-icon"
+            split="{Boolean}true"
+            text="Deactivate">
+            <menu jcr:primaryType="nt:unstructured">
+                <deactivateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.deactivatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Deactivate"/>
+                <deactivateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Deactivate Later..."/>
+            </menu>
+        </deactivate>
+        <separator3
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <lock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-lock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.lockPage"
+            iconCls="cq-siteadmin-lock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Lock"/>
+        <unlock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-unlock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.unlockPage"
+            iconCls="cq-siteadmin-unlock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Unlock"/>
+        <workflow
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-workflow"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.notLocked]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.startWorkflow"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Workflow..."/>
+        <separator5
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <rollout
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-rollout"
+            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.rolloutPage"
+            iconCls="cq-siteadmin-properties-icon"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Roll-out..."/>
+        <separator6
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <properties
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-properties"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openProperties"
+            iconCls="cq-siteadmin-properties-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Properties..."/>
+        <tools
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-tools"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-tools-icon"
+            text="Tools">
+            <menu jcr:primaryType="nt:unstructured">
+                <langcopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-languagecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                    iconCls="cq-siteadmin-languagecopy-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="Language Copy..."/>
+                <findReplace
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                    iconCls="cq-siteadmin-findreplace-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Find &amp; Replace..."/>
+                <restore
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-restore"
+                    iconCls="cq-siteadmin-restore-icon"
+                    text="Restore">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <version
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-version"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreVersion"
+                            iconCls="cq-siteadmin-restore-version-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Version...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a page"
+                                title="Restore Version"/>
+                        </version>
+                        <tree
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-tree"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreTree"
+                            iconCls="cq-siteadmin-restore-tree-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Tree...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a tree"
+                                title="Restore Tree"/>
+                        </tree>
+                    </menu>
+                </restore>
+                <references
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-damadmin-references"
+                    conditions="[CQ.wcm.SiteAdmin.noFolder]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.showReferences"
+                    iconCls="cq-siteadmin-references-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="References..."/>
+                <download
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.download"
+                    iconCls="cq-siteadmin-download-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Download"/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getAnyTarget"
+                    text="Roll-out..."/>
+            </menu>
+        </tools>
+    </actions>
+    <tags jcr:primaryType="nt:unstructured">
+        <emulateIE8
+            jcr:primaryType="nt:unstructured"
+            content="IE=8"
+            http-equiv="X-UA-Compatible"
+            tagName="meta"/>
+        <icon1
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="shortcut icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+        <icon2
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+    </tags>
+    <tabs jcr:primaryType="cq:WidgetCollection">
+        <searchpanel
+            jcr:primaryType="cq:Widget"
+            facetURL="/libs/wcm/core/content/search/searchpanel/facets.overlay.infinity.json"
+            xtype="siteadminsearchpanel">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="title"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <template
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="template"
+                    xtype="gridcolumn"/>
+            </columns>
+            <actions jcr:primaryType="nt:unstructured">
+                <open
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-open"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openPages"
+                    iconCls="cq-siteadmin-open-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Open"/>
+                <delete
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-delete"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.deletePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Delete"/>
+                <separator1
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <move
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-move"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.movePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Move..."/>
+                <separator2
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <activate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-activate-icon"
+                    split="{Boolean}true"
+                    text="Activate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <activateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.activatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Activate"/>
+                        <activateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Activate Later..."/>
+                    </menu>
+                </activate>
+                <deactivate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-deactivate-icon"
+                    split="{Boolean}true"
+                    text="Deactivate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <deactivateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.deactivatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Deactivate"/>
+                        <deactivateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Deactivate Later..."/>
+                    </menu>
+                </deactivate>
+                <lock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-lock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.lockPage"
+                    iconCls="cq-siteadmin-lock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Lock"/>
+                <unlock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-unlock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.unlockPage"
+                    iconCls="cq-siteadmin-unlock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Unlock"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-workflow"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.startWorkflow"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Workflow..."/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Roll-out..."/>
+                <separator5
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+                <properties
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-properties"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noAsset]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openProperties"
+                    iconCls="cq-siteadmin-properties-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Properties..."/>
+                <tools
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-tools"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-tools-icon"
+                    text="Tools">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <langcopy
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-languagecopy"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                            handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                            iconCls="cq-siteadmin-languagecopy-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Language Copy..."/>
+                        <findReplace
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                            iconCls="cq-siteadmin-findreplace-icon"
+                            privileges="[update]"
+                            target="CQ.wcm.SiteAdmin.getSingleTarget"
+                            text="Find &amp; Replace..."/>
+                        <restore
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore"
+                            iconCls="cq-siteadmin-restore-icon"
+                            text="Restore">
+                            <menu jcr:primaryType="nt:unstructured">
+                                <version
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-version"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreVersion"
+                                    iconCls="cq-siteadmin-restore-version-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Version...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a page"
+                                        title="Restore Version"/>
+                                </version>
+                                <tree
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-tree"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreTree"
+                                    iconCls="cq-siteadmin-restore-tree-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Tree...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a tree"
+                                        title="Restore Tree"/>
+                                </tree>
+                            </menu>
+                        </restore>
+                        <references
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-damadmin-references"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.showReferences"
+                            iconCls="cq-siteadmin-references-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="References..."/>
+                        <download
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.download"
+                            iconCls="cq-siteadmin-download-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="Download"/>
+                        <rollout
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-rollout"
+                            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                            handler="CQ.wcm.SiteAdmin.rolloutPage"
+                            iconCls="cq-siteadmin-properties-icon"
+                            target="CQ.wcm.SiteAdmin.getAnyTarget"
+                            text="Roll-out..."/>
+                    </menu>
+                </tools>
+                <separator3
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <separator4
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+            </actions>
+        </searchpanel>
+    </tabs>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/empty_directory/.dummy b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/empty_directory/.dummy
new file mode 100644
index 0000000..68325fa
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/jcr_root/apps/wcm/core/empty_directory/.dummy
@@ -0,0 +1 @@
+# dummy
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/pom.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/pom.xml
new file mode 100755
index 0000000..ee57ed4
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-empty-directories/pom.xml
@@ -0,0 +1,48 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <excludes>**/.dummy</excludes>
+                    <filters>
+                        <filter>
+                            <root>/apps/wcm/core</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-file-order.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-file-order.txt
new file mode 100644
index 0000000..9628762
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-file-order.txt
@@ -0,0 +1,6 @@
+META-INF/MANIFEST.MF
+META-INF/vault/
+jcr_root/apps/wcm/core/content/
+jcr_root/_rep_policy.xml
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/cloudservices/ooyala/
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-files.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-files.txt
new file mode 100644
index 0000000..0b99b6b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-files.txt
@@ -0,0 +1,34 @@
+META-INF/
+META-INF/MANIFEST.MF
+META-INF/vault/
+META-INF/vault/config.xml
+META-INF/vault/filter.xml
+META-INF/vault/properties.xml
+META-INF/vault/settings.xml
+jcr_root/
+jcr_root/apps/
+jcr_root/apps/wcm/
+jcr_root/apps/wcm/core/
+jcr_root/apps/wcm/core/content/
+jcr_root/apps/wcm/core/content/.content.xml
+jcr_root/apps/wcm/core/content/siteadmin.xml
+jcr_root/_rep_policy.xml
+jcr_root/etc/
+jcr_root/etc/designs/
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/
+jcr_root/etc/designs/some-thirdparty-libs/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
+jcr_root/etc/cloudservices/
+jcr_root/etc/cloudservices/ooyala/
+jcr_root/etc/cloudservices/ooyala/.content.xml
+jcr_root/etc/cloudservices/.content.xml
+jcr_root/apps/wcm/.content.xml
+jcr_root/apps/wcm/core/.content.xml
+META-INF/maven/
+META-INF/maven/org.apache.jackrabbit.filevault/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.xml
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.properties
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-manifest.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-manifest.txt
new file mode 100644
index 0000000..566ba64
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/expected-manifest.txt
@@ -0,0 +1,10 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:Packaging test
+Content-Package-Id:org.apache.jackrabbit.filevault:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/apps/some-thirdparty-libs,/apps/wcm/core/content,/etc/cloudservices/ooyala,/etc/designs/some-thirdparty-libs,/etc/packages/apache/consulting,/rep:policy
+Content-Package-Type:mixed
+Created-By:Apache Maven
+Implementation-Title:Packaging test
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/filter.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/filter.xml
new file mode 100644
index 0000000..1e1ec0d
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/filter.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<workspaceFilter version="1.0">
+    <filter root="/apps/wcm/core/content"/>
+    <filter root="/rep:policy" mode="merge"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/_rep_policy.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/_rep_policy.xml
new file mode 100644
index 0000000..d83757c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/_rep_policy.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
+          jcr:primaryType="rep:ACL">
+    <allow
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-repo-reader-service"
+            rep:privileges="{Name}[jcr:read]"/>
+    <allow0
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-process-service"
+            rep:privileges="{Name}[jcr:read,rep:write,jcr:versionManagement,jcr:lockManagement,crx:replicate]"/>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/.gitignore b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/.gitignore
new file mode 100644
index 0000000..c57d302
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/.gitignore
@@ -0,0 +1 @@
+# deliberately empty as this is only to check that this will not end up in the generated package
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/content/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/content/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/content/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/content/siteadmin.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/content/siteadmin.xml
new file mode 100755
index 0000000..5984d80
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/apps/wcm/core/content/siteadmin.xml
@@ -0,0 +1,764 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:mixinTypes="[cq:Console]"
+    jcr:primaryType="cq:Widget"
+    jcr:title="AEM WCM"
+    sling:redirect="{Boolean}false"
+    sling:resourceType="cq/ui/components/widget"
+    sling:vanityOrder="{Long}500"
+    sling:vanityPath="/siteadmin"
+    consoleDescription="Create and manage multiple websites."
+    consoleTitle="Websites"
+    historyLink="/bin/wcmcommand?cmd=open&amp;path=${resource.path}"
+    historyResourceTypes="[cq:Page]"
+    historyShow="{Boolean}true"
+    historyTitle="Recently used pages"
+    iconClass="siteadmin"
+    id="cq-siteadmin"
+    jsLibs="[cq.wcm.admin]"
+    noSearch="{Boolean}true"
+    tabTitle="Websites"
+    treeAutoExpandMax="100"
+    xtype="siteadmin">
+    <grid jcr:primaryType="nt:unstructured">
+        <assets
+            jcr:primaryType="nt:unstructured"
+            pageSize="15"
+            pageText="Assets {0} - {1} of {2}"
+            pathRegex="\\/content\\/dam(/.*)?"
+            storeProxySuffix=".assets.json"
+            storeReaderFields="[index,title,label,lockedBy,type,width,height,size,inWorkflow,replication,scheduledTasks,numberer,workflows,lastModified,lastModifiedBy,inProgress,ck]">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <thumbnail
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}false"
+                    usePredefined="thumbnail"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}true"
+                    usePredefined="title"
+                    xssProtect="true"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <status
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="status"
+                    xtype="gridcolumn"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="workflow"
+                    xtype="gridcolumn"/>
+                <width
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="width"
+                    xtype="gridcolumn"/>
+                <height
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="height"
+                    xtype="gridcolumn"/>
+                <size
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="size"
+                    xtype="gridcolumn"/>
+            </columns>
+        </assets>
+    </grid>
+    <actions jcr:primaryType="nt:unstructured">
+        <create
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-create"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-create-icon"
+            split="{Boolean}true"
+            text="New...">
+            <menu jcr:primaryType="nt:unstructured">
+                <createPage
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-page"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createPage"
+                    iconCls="cq-siteadmin-create-page-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Page..."/>
+                <createSite
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-site"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createSite"
+                    iconCls="cq-siteadmin-create-site-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Site..."/>
+                <createLiveCopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-livecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLiveCopy"
+                    iconCls="cq-siteadmin-create-livecopy-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Live Copy..."/>
+                <createLaunch
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-launch"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLaunch"
+                    iconCls="cq-siteadmin-create-launch-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Launch..."/>
+                <separator0
+                    jcr:primaryType="nt:unstructured"
+                    value="-"
+                    xtype="separator"/>
+                <createFile
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-file"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.uploadFiles"
+                    iconCls="cq-siteadmin-create-file-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New File..."/>
+                <createFolder
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-folder"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createFolder"
+                    iconCls="cq-siteadmin-create-folder-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Folder..."/>
+            </menu>
+        </create>
+        <open
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-open"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openPages"
+            iconCls="cq-siteadmin-open-icon"
+            isDefaultAction="{Boolean}true"
+            privileges="[read]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Open"/>
+        <separator0
+            jcr:primaryType="nt:unstructured"
+            value="-"
+            xtype="separator"/>
+        <copy
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-copy"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.copyPages"
+            target="CQ.wcm.SiteAdmin.getAnyTarget"
+            text="Copy"/>
+        <paste
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-paste"
+            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canPaste,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            forceCheck="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.pastePages"
+            privileges="[create]"
+            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+            text="Paste"/>
+        <delete
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-delete"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.deletePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getAllTargets"
+            text="Delete"/>
+        <separator1
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <move
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-move"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.movePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getSingleTarget"
+            text="Move..."/>
+        <separator2
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <activate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-activate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-activate-icon"
+            split="{Boolean}true"
+            text="Activate">
+            <menu jcr:primaryType="nt:unstructured">
+                <activateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.activatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Activate"/>
+                <activateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Activate Later..."/>
+            </menu>
+        </activate>
+        <deactivate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-deactivate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-deactivate-icon"
+            split="{Boolean}true"
+            text="Deactivate">
+            <menu jcr:primaryType="nt:unstructured">
+                <deactivateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.deactivatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Deactivate"/>
+                <deactivateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Deactivate Later..."/>
+            </menu>
+        </deactivate>
+        <separator3
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <lock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-lock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.lockPage"
+            iconCls="cq-siteadmin-lock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Lock"/>
+        <unlock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-unlock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.unlockPage"
+            iconCls="cq-siteadmin-unlock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Unlock"/>
+        <workflow
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-workflow"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.notLocked]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.startWorkflow"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Workflow..."/>
+        <separator5
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <rollout
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-rollout"
+            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.rolloutPage"
+            iconCls="cq-siteadmin-properties-icon"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Roll-out..."/>
+        <separator6
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <properties
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-properties"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openProperties"
+            iconCls="cq-siteadmin-properties-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Properties..."/>
+        <tools
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-tools"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-tools-icon"
+            text="Tools">
+            <menu jcr:primaryType="nt:unstructured">
+                <langcopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-languagecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                    iconCls="cq-siteadmin-languagecopy-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="Language Copy..."/>
+                <findReplace
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                    iconCls="cq-siteadmin-findreplace-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Find &amp; Replace..."/>
+                <restore
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-restore"
+                    iconCls="cq-siteadmin-restore-icon"
+                    text="Restore">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <version
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-version"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreVersion"
+                            iconCls="cq-siteadmin-restore-version-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Version...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a page"
+                                title="Restore Version"/>
+                        </version>
+                        <tree
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-tree"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreTree"
+                            iconCls="cq-siteadmin-restore-tree-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Tree...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a tree"
+                                title="Restore Tree"/>
+                        </tree>
+                    </menu>
+                </restore>
+                <references
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-damadmin-references"
+                    conditions="[CQ.wcm.SiteAdmin.noFolder]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.showReferences"
+                    iconCls="cq-siteadmin-references-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="References..."/>
+                <download
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.download"
+                    iconCls="cq-siteadmin-download-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Download"/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getAnyTarget"
+                    text="Roll-out..."/>
+            </menu>
+        </tools>
+    </actions>
+    <tags jcr:primaryType="nt:unstructured">
+        <emulateIE8
+            jcr:primaryType="nt:unstructured"
+            content="IE=8"
+            http-equiv="X-UA-Compatible"
+            tagName="meta"/>
+        <icon1
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="shortcut icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+        <icon2
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+    </tags>
+    <tabs jcr:primaryType="cq:WidgetCollection">
+        <searchpanel
+            jcr:primaryType="cq:Widget"
+            facetURL="/libs/wcm/core/content/search/searchpanel/facets.overlay.infinity.json"
+            xtype="siteadminsearchpanel">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="title"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <template
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="template"
+                    xtype="gridcolumn"/>
+            </columns>
+            <actions jcr:primaryType="nt:unstructured">
+                <open
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-open"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openPages"
+                    iconCls="cq-siteadmin-open-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Open"/>
+                <delete
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-delete"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.deletePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Delete"/>
+                <separator1
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <move
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-move"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.movePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Move..."/>
+                <separator2
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <activate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-activate-icon"
+                    split="{Boolean}true"
+                    text="Activate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <activateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.activatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Activate"/>
+                        <activateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Activate Later..."/>
+                    </menu>
+                </activate>
+                <deactivate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-deactivate-icon"
+                    split="{Boolean}true"
+                    text="Deactivate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <deactivateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.deactivatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Deactivate"/>
+                        <deactivateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Deactivate Later..."/>
+                    </menu>
+                </deactivate>
+                <lock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-lock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.lockPage"
+                    iconCls="cq-siteadmin-lock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Lock"/>
+                <unlock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-unlock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.unlockPage"
+                    iconCls="cq-siteadmin-unlock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Unlock"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-workflow"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.startWorkflow"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Workflow..."/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Roll-out..."/>
+                <separator5
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+                <properties
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-properties"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noAsset]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openProperties"
+                    iconCls="cq-siteadmin-properties-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Properties..."/>
+                <tools
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-tools"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-tools-icon"
+                    text="Tools">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <langcopy
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-languagecopy"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                            handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                            iconCls="cq-siteadmin-languagecopy-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Language Copy..."/>
+                        <findReplace
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                            iconCls="cq-siteadmin-findreplace-icon"
+                            privileges="[update]"
+                            target="CQ.wcm.SiteAdmin.getSingleTarget"
+                            text="Find &amp; Replace..."/>
+                        <restore
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore"
+                            iconCls="cq-siteadmin-restore-icon"
+                            text="Restore">
+                            <menu jcr:primaryType="nt:unstructured">
+                                <version
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-version"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreVersion"
+                                    iconCls="cq-siteadmin-restore-version-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Version...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a page"
+                                        title="Restore Version"/>
+                                </version>
+                                <tree
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-tree"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreTree"
+                                    iconCls="cq-siteadmin-restore-tree-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Tree...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a tree"
+                                        title="Restore Tree"/>
+                                </tree>
+                            </menu>
+                        </restore>
+                        <references
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-damadmin-references"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.showReferences"
+                            iconCls="cq-siteadmin-references-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="References..."/>
+                        <download
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.download"
+                            iconCls="cq-siteadmin-download-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="Download"/>
+                        <rollout
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-rollout"
+                            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                            handler="CQ.wcm.SiteAdmin.rolloutPage"
+                            iconCls="cq-siteadmin-properties-icon"
+                            target="CQ.wcm.SiteAdmin.getAnyTarget"
+                            text="Roll-out..."/>
+                    </menu>
+                </tools>
+                <separator3
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <separator4
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+            </actions>
+        </searchpanel>
+    </tabs>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/.gitignore b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/.gitignore
new file mode 100644
index 0000000..9f2dd3b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/.gitignore
@@ -0,0 +1 @@
+!.*
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/.vltignore b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/.vltignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/.vltignore
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/cloudservices/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/cloudservices/.content.xml
new file mode 100755
index 0000000..296876f
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/cloudservices/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="sling:Folder"/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/cloudservices/ooyala/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/cloudservices/ooyala/.content.xml
new file mode 100755
index 0000000..c51676c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/cloudservices/ooyala/.content.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="nt:unstructured"
+          url="http://ooyala.com"
+          apiKey="someKey"
+/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/.content.xml
new file mode 100755
index 0000000..0931778
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/.content.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
+          xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+          jcr:primaryType="cq:Page">
+    <jcr:content
+            cq:doctype="html_5"
+            cq:template="/libs/wcm/core/templates/designpage"
+            jcr:primaryType="cq:PageContent"
+            jcr:title="some-thridparty-libs"
+            sling:resourceType="wcm/core/components/designer" />
+
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
new file mode 100755
index 0000000..936074a
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="cq:ClientLibraryFolder"
+          categories="[thirdparty.common]" />
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/foo_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/pom.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/pom.xml
new file mode 100755
index 0000000..e5d3499
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-unusal-jcrroot/pom.xml
@@ -0,0 +1,58 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <filterSource>${project.basedir}/filter.xml</filterSource>
+                    <jcrRootSourceDirectory>${project.basedir}/foo_root</jcrRootSourceDirectory>
+                    <filters>
+                        <filter>
+                            <root>/etc/designs/some-thirdparty-libs</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/cloudservices/ooyala</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/packages/apache/consulting</root>
+                        </filter>
+                        <filter>
+                            <root>/apps/some-thirdparty-libs</root>
+                        </filter>
+                    </filters>
+                    <embeddedTarget>/apps/some-thirdparty-libs/install</embeddedTarget>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-file-order.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-file-order.txt
new file mode 100644
index 0000000..9628762
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-file-order.txt
@@ -0,0 +1,6 @@
+META-INF/MANIFEST.MF
+META-INF/vault/
+jcr_root/apps/wcm/core/content/
+jcr_root/_rep_policy.xml
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/cloudservices/ooyala/
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-files.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-files.txt
new file mode 100644
index 0000000..0b99b6b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-files.txt
@@ -0,0 +1,34 @@
+META-INF/
+META-INF/MANIFEST.MF
+META-INF/vault/
+META-INF/vault/config.xml
+META-INF/vault/filter.xml
+META-INF/vault/properties.xml
+META-INF/vault/settings.xml
+jcr_root/
+jcr_root/apps/
+jcr_root/apps/wcm/
+jcr_root/apps/wcm/core/
+jcr_root/apps/wcm/core/content/
+jcr_root/apps/wcm/core/content/.content.xml
+jcr_root/apps/wcm/core/content/siteadmin.xml
+jcr_root/_rep_policy.xml
+jcr_root/etc/
+jcr_root/etc/designs/
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/
+jcr_root/etc/designs/some-thirdparty-libs/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
+jcr_root/etc/cloudservices/
+jcr_root/etc/cloudservices/ooyala/
+jcr_root/etc/cloudservices/ooyala/.content.xml
+jcr_root/etc/cloudservices/.content.xml
+jcr_root/apps/wcm/.content.xml
+jcr_root/apps/wcm/core/.content.xml
+META-INF/maven/
+META-INF/maven/org.apache.jackrabbit.filevault/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.xml
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.properties
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-manifest.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-manifest.txt
new file mode 100644
index 0000000..566ba64
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/expected-manifest.txt
@@ -0,0 +1,10 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:Packaging test
+Content-Package-Id:org.apache.jackrabbit.filevault:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/apps/some-thirdparty-libs,/apps/wcm/core/content,/etc/cloudservices/ooyala,/etc/designs/some-thirdparty-libs,/etc/packages/apache/consulting,/rep:policy
+Content-Package-Type:mixed
+Created-By:Apache Maven
+Implementation-Title:Packaging test
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/filter.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/filter.xml
new file mode 100644
index 0000000..1e1ec0d
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/filter.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<workspaceFilter version="1.0">
+    <filter root="/apps/wcm/core/content"/>
+    <filter root="/rep:policy" mode="merge"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/_rep_policy.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/_rep_policy.xml
new file mode 100644
index 0000000..d83757c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/_rep_policy.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
+          jcr:primaryType="rep:ACL">
+    <allow
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-repo-reader-service"
+            rep:privileges="{Name}[jcr:read]"/>
+    <allow0
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-process-service"
+            rep:privileges="{Name}[jcr:read,rep:write,jcr:versionManagement,jcr:lockManagement,crx:replicate]"/>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/.gitignore b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/.gitignore
new file mode 100644
index 0000000..c57d302
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/.gitignore
@@ -0,0 +1 @@
+# deliberately empty as this is only to check that this will not end up in the generated package
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/content/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/content/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/content/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/content/siteadmin.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/content/siteadmin.xml
new file mode 100755
index 0000000..5984d80
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/apps/wcm/core/content/siteadmin.xml
@@ -0,0 +1,764 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:mixinTypes="[cq:Console]"
+    jcr:primaryType="cq:Widget"
+    jcr:title="AEM WCM"
+    sling:redirect="{Boolean}false"
+    sling:resourceType="cq/ui/components/widget"
+    sling:vanityOrder="{Long}500"
+    sling:vanityPath="/siteadmin"
+    consoleDescription="Create and manage multiple websites."
+    consoleTitle="Websites"
+    historyLink="/bin/wcmcommand?cmd=open&amp;path=${resource.path}"
+    historyResourceTypes="[cq:Page]"
+    historyShow="{Boolean}true"
+    historyTitle="Recently used pages"
+    iconClass="siteadmin"
+    id="cq-siteadmin"
+    jsLibs="[cq.wcm.admin]"
+    noSearch="{Boolean}true"
+    tabTitle="Websites"
+    treeAutoExpandMax="100"
+    xtype="siteadmin">
+    <grid jcr:primaryType="nt:unstructured">
+        <assets
+            jcr:primaryType="nt:unstructured"
+            pageSize="15"
+            pageText="Assets {0} - {1} of {2}"
+            pathRegex="\\/content\\/dam(/.*)?"
+            storeProxySuffix=".assets.json"
+            storeReaderFields="[index,title,label,lockedBy,type,width,height,size,inWorkflow,replication,scheduledTasks,numberer,workflows,lastModified,lastModifiedBy,inProgress,ck]">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <thumbnail
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}false"
+                    usePredefined="thumbnail"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}true"
+                    usePredefined="title"
+                    xssProtect="true"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <status
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="status"
+                    xtype="gridcolumn"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="workflow"
+                    xtype="gridcolumn"/>
+                <width
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="width"
+                    xtype="gridcolumn"/>
+                <height
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="height"
+                    xtype="gridcolumn"/>
+                <size
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="size"
+                    xtype="gridcolumn"/>
+            </columns>
+        </assets>
+    </grid>
+    <actions jcr:primaryType="nt:unstructured">
+        <create
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-create"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-create-icon"
+            split="{Boolean}true"
+            text="New...">
+            <menu jcr:primaryType="nt:unstructured">
+                <createPage
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-page"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createPage"
+                    iconCls="cq-siteadmin-create-page-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Page..."/>
+                <createSite
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-site"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createSite"
+                    iconCls="cq-siteadmin-create-site-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Site..."/>
+                <createLiveCopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-livecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLiveCopy"
+                    iconCls="cq-siteadmin-create-livecopy-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Live Copy..."/>
+                <createLaunch
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-launch"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLaunch"
+                    iconCls="cq-siteadmin-create-launch-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Launch..."/>
+                <separator0
+                    jcr:primaryType="nt:unstructured"
+                    value="-"
+                    xtype="separator"/>
+                <createFile
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-file"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.uploadFiles"
+                    iconCls="cq-siteadmin-create-file-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New File..."/>
+                <createFolder
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-folder"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createFolder"
+                    iconCls="cq-siteadmin-create-folder-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Folder..."/>
+            </menu>
+        </create>
+        <open
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-open"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openPages"
+            iconCls="cq-siteadmin-open-icon"
+            isDefaultAction="{Boolean}true"
+            privileges="[read]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Open"/>
+        <separator0
+            jcr:primaryType="nt:unstructured"
+            value="-"
+            xtype="separator"/>
+        <copy
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-copy"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.copyPages"
+            target="CQ.wcm.SiteAdmin.getAnyTarget"
+            text="Copy"/>
+        <paste
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-paste"
+            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canPaste,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            forceCheck="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.pastePages"
+            privileges="[create]"
+            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+            text="Paste"/>
+        <delete
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-delete"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.deletePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getAllTargets"
+            text="Delete"/>
+        <separator1
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <move
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-move"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.movePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getSingleTarget"
+            text="Move..."/>
+        <separator2
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <activate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-activate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-activate-icon"
+            split="{Boolean}true"
+            text="Activate">
+            <menu jcr:primaryType="nt:unstructured">
+                <activateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.activatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Activate"/>
+                <activateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Activate Later..."/>
+            </menu>
+        </activate>
+        <deactivate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-deactivate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-deactivate-icon"
+            split="{Boolean}true"
+            text="Deactivate">
+            <menu jcr:primaryType="nt:unstructured">
+                <deactivateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.deactivatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Deactivate"/>
+                <deactivateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Deactivate Later..."/>
+            </menu>
+        </deactivate>
+        <separator3
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <lock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-lock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.lockPage"
+            iconCls="cq-siteadmin-lock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Lock"/>
+        <unlock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-unlock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.unlockPage"
+            iconCls="cq-siteadmin-unlock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Unlock"/>
+        <workflow
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-workflow"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.notLocked]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.startWorkflow"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Workflow..."/>
+        <separator5
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <rollout
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-rollout"
+            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.rolloutPage"
+            iconCls="cq-siteadmin-properties-icon"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Roll-out..."/>
+        <separator6
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <properties
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-properties"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openProperties"
+            iconCls="cq-siteadmin-properties-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Properties..."/>
+        <tools
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-tools"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-tools-icon"
+            text="Tools">
+            <menu jcr:primaryType="nt:unstructured">
+                <langcopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-languagecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                    iconCls="cq-siteadmin-languagecopy-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="Language Copy..."/>
+                <findReplace
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                    iconCls="cq-siteadmin-findreplace-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Find &amp; Replace..."/>
+                <restore
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-restore"
+                    iconCls="cq-siteadmin-restore-icon"
+                    text="Restore">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <version
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-version"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreVersion"
+                            iconCls="cq-siteadmin-restore-version-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Version...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a page"
+                                title="Restore Version"/>
+                        </version>
+                        <tree
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-tree"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreTree"
+                            iconCls="cq-siteadmin-restore-tree-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Tree...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a tree"
+                                title="Restore Tree"/>
+                        </tree>
+                    </menu>
+                </restore>
+                <references
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-damadmin-references"
+                    conditions="[CQ.wcm.SiteAdmin.noFolder]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.showReferences"
+                    iconCls="cq-siteadmin-references-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="References..."/>
+                <download
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.download"
+                    iconCls="cq-siteadmin-download-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Download"/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getAnyTarget"
+                    text="Roll-out..."/>
+            </menu>
+        </tools>
+    </actions>
+    <tags jcr:primaryType="nt:unstructured">
+        <emulateIE8
+            jcr:primaryType="nt:unstructured"
+            content="IE=8"
+            http-equiv="X-UA-Compatible"
+            tagName="meta"/>
+        <icon1
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="shortcut icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+        <icon2
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+    </tags>
+    <tabs jcr:primaryType="cq:WidgetCollection">
+        <searchpanel
+            jcr:primaryType="cq:Widget"
+            facetURL="/libs/wcm/core/content/search/searchpanel/facets.overlay.infinity.json"
+            xtype="siteadminsearchpanel">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="title"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <template
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="template"
+                    xtype="gridcolumn"/>
+            </columns>
+            <actions jcr:primaryType="nt:unstructured">
+                <open
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-open"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openPages"
+                    iconCls="cq-siteadmin-open-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Open"/>
+                <delete
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-delete"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.deletePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Delete"/>
+                <separator1
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <move
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-move"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.movePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Move..."/>
+                <separator2
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <activate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-activate-icon"
+                    split="{Boolean}true"
+                    text="Activate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <activateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.activatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Activate"/>
+                        <activateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Activate Later..."/>
+                    </menu>
+                </activate>
+                <deactivate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-deactivate-icon"
+                    split="{Boolean}true"
+                    text="Deactivate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <deactivateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.deactivatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Deactivate"/>
+                        <deactivateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Deactivate Later..."/>
+                    </menu>
+                </deactivate>
+                <lock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-lock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.lockPage"
+                    iconCls="cq-siteadmin-lock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Lock"/>
+                <unlock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-unlock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.unlockPage"
+                    iconCls="cq-siteadmin-unlock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Unlock"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-workflow"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.startWorkflow"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Workflow..."/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Roll-out..."/>
+                <separator5
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+                <properties
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-properties"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noAsset]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openProperties"
+                    iconCls="cq-siteadmin-properties-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Properties..."/>
+                <tools
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-tools"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-tools-icon"
+                    text="Tools">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <langcopy
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-languagecopy"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                            handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                            iconCls="cq-siteadmin-languagecopy-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Language Copy..."/>
+                        <findReplace
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                            iconCls="cq-siteadmin-findreplace-icon"
+                            privileges="[update]"
+                            target="CQ.wcm.SiteAdmin.getSingleTarget"
+                            text="Find &amp; Replace..."/>
+                        <restore
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore"
+                            iconCls="cq-siteadmin-restore-icon"
+                            text="Restore">
+                            <menu jcr:primaryType="nt:unstructured">
+                                <version
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-version"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreVersion"
+                                    iconCls="cq-siteadmin-restore-version-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Version...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a page"
+                                        title="Restore Version"/>
+                                </version>
+                                <tree
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-tree"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreTree"
+                                    iconCls="cq-siteadmin-restore-tree-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Tree...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a tree"
+                                        title="Restore Tree"/>
+                                </tree>
+                            </menu>
+                        </restore>
+                        <references
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-damadmin-references"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.showReferences"
+                            iconCls="cq-siteadmin-references-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="References..."/>
+                        <download
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.download"
+                            iconCls="cq-siteadmin-download-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="Download"/>
+                        <rollout
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-rollout"
+                            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                            handler="CQ.wcm.SiteAdmin.rolloutPage"
+                            iconCls="cq-siteadmin-properties-icon"
+                            target="CQ.wcm.SiteAdmin.getAnyTarget"
+                            text="Roll-out..."/>
+                    </menu>
+                </tools>
+                <separator3
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <separator4
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+            </actions>
+        </searchpanel>
+    </tabs>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/.gitignore b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/.gitignore
new file mode 100644
index 0000000..9f2dd3b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/.gitignore
@@ -0,0 +1 @@
+!.*
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/.vltignore b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/.vltignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/.vltignore
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/cloudservices/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/cloudservices/.content.xml
new file mode 100755
index 0000000..296876f
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/cloudservices/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="sling:Folder"/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/cloudservices/ooyala/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/cloudservices/ooyala/.content.xml
new file mode 100755
index 0000000..c51676c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/cloudservices/ooyala/.content.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="nt:unstructured"
+          url="http://ooyala.com"
+          apiKey="someKey"
+/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/.content.xml
new file mode 100755
index 0000000..0931778
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/.content.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
+          xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+          jcr:primaryType="cq:Page">
+    <jcr:content
+            cq:doctype="html_5"
+            cq:template="/libs/wcm/core/templates/designpage"
+            jcr:primaryType="cq:PageContent"
+            jcr:title="some-thridparty-libs"
+            sling:resourceType="wcm/core/components/designer" />
+
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
new file mode 100755
index 0000000..936074a
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="cq:ClientLibraryFolder"
+          categories="[thirdparty.common]" />
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/pom.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/pom.xml
new file mode 100755
index 0000000..81aec54
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic-with-builtcd/pom.xml
@@ -0,0 +1,58 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <builtContentDirectory>${project.basedir}/jcr_root</builtContentDirectory>
+                    <filterSource>${project.basedir}/filter.xml</filterSource>
+                    <filters>
+                        <filter>
+                            <root>/etc/designs/some-thirdparty-libs</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/cloudservices/ooyala</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/packages/apache/consulting</root>
+                        </filter>
+                        <filter>
+                            <root>/apps/some-thirdparty-libs</root>
+                        </filter>
+                    </filters>
+                    <embeddedTarget>/apps/some-thirdparty-libs/install</embeddedTarget>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-file-order.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-file-order.txt
new file mode 100644
index 0000000..9628762
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-file-order.txt
@@ -0,0 +1,6 @@
+META-INF/MANIFEST.MF
+META-INF/vault/
+jcr_root/apps/wcm/core/content/
+jcr_root/_rep_policy.xml
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/cloudservices/ooyala/
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-files.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-files.txt
new file mode 100644
index 0000000..0d7e71c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-files.txt
@@ -0,0 +1,39 @@
+META-INF/
+META-INF/MANIFEST.MF
+META-INF/vault/
+META-INF/vault/config.xml
+META-INF/vault/filter.xml
+META-INF/vault/properties.xml
+META-INF/vault/settings.xml
+jcr_root/
+jcr_root/apps/
+jcr_root/apps/install/
+jcr_root/apps/install/org.apache.jackrabbit.vault-3.1.40.jar
+jcr_root/apps/wcm/
+jcr_root/apps/wcm/core/
+jcr_root/apps/wcm/core/content/
+jcr_root/apps/wcm/core/content/.content.xml
+jcr_root/apps/wcm/core/content/siteadmin.xml
+jcr_root/_rep_policy.xml
+jcr_root/etc/
+jcr_root/etc/designs/
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/
+jcr_root/etc/designs/some-thirdparty-libs/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
+jcr_root/etc/cloudservices/
+jcr_root/etc/cloudservices/ooyala/
+jcr_root/etc/cloudservices/ooyala/.content.xml
+jcr_root/etc/cloudservices/.content.xml
+jcr_root/apps/wcm/.content.xml
+jcr_root/apps/wcm/core/.content.xml
+jcr_root/libs/
+jcr_root/libs/install/
+jcr_root/libs/install/jcr-2.0.jar
+META-INF/maven/
+META-INF/maven/org.apache.jackrabbit.filevault/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.xml
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.properties
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-manifest.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-manifest.txt
new file mode 100644
index 0000000..566ba64
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/expected-manifest.txt
@@ -0,0 +1,10 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:Packaging test
+Content-Package-Id:org.apache.jackrabbit.filevault:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/apps/some-thirdparty-libs,/apps/wcm/core/content,/etc/cloudservices/ooyala,/etc/designs/some-thirdparty-libs,/etc/packages/apache/consulting,/rep:policy
+Content-Package-Type:mixed
+Created-By:Apache Maven
+Implementation-Title:Packaging test
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/filter.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/filter.xml
new file mode 100644
index 0000000..1e1ec0d
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/filter.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<workspaceFilter version="1.0">
+    <filter root="/apps/wcm/core/content"/>
+    <filter root="/rep:policy" mode="merge"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/_rep_policy.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/_rep_policy.xml
new file mode 100644
index 0000000..d83757c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/_rep_policy.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
+          jcr:primaryType="rep:ACL">
+    <allow
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-repo-reader-service"
+            rep:privileges="{Name}[jcr:read]"/>
+    <allow0
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-process-service"
+            rep:privileges="{Name}[jcr:read,rep:write,jcr:versionManagement,jcr:lockManagement,crx:replicate]"/>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/.gitignore b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/.gitignore
new file mode 100644
index 0000000..c57d302
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/.gitignore
@@ -0,0 +1 @@
+# deliberately empty as this is only to check that this will not end up in the generated package
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/content/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/content/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/content/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/content/siteadmin.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/content/siteadmin.xml
new file mode 100755
index 0000000..5984d80
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/apps/wcm/core/content/siteadmin.xml
@@ -0,0 +1,764 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:mixinTypes="[cq:Console]"
+    jcr:primaryType="cq:Widget"
+    jcr:title="AEM WCM"
+    sling:redirect="{Boolean}false"
+    sling:resourceType="cq/ui/components/widget"
+    sling:vanityOrder="{Long}500"
+    sling:vanityPath="/siteadmin"
+    consoleDescription="Create and manage multiple websites."
+    consoleTitle="Websites"
+    historyLink="/bin/wcmcommand?cmd=open&amp;path=${resource.path}"
+    historyResourceTypes="[cq:Page]"
+    historyShow="{Boolean}true"
+    historyTitle="Recently used pages"
+    iconClass="siteadmin"
+    id="cq-siteadmin"
+    jsLibs="[cq.wcm.admin]"
+    noSearch="{Boolean}true"
+    tabTitle="Websites"
+    treeAutoExpandMax="100"
+    xtype="siteadmin">
+    <grid jcr:primaryType="nt:unstructured">
+        <assets
+            jcr:primaryType="nt:unstructured"
+            pageSize="15"
+            pageText="Assets {0} - {1} of {2}"
+            pathRegex="\\/content\\/dam(/.*)?"
+            storeProxySuffix=".assets.json"
+            storeReaderFields="[index,title,label,lockedBy,type,width,height,size,inWorkflow,replication,scheduledTasks,numberer,workflows,lastModified,lastModifiedBy,inProgress,ck]">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <thumbnail
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}false"
+                    usePredefined="thumbnail"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}true"
+                    usePredefined="title"
+                    xssProtect="true"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <status
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="status"
+                    xtype="gridcolumn"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="workflow"
+                    xtype="gridcolumn"/>
+                <width
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="width"
+                    xtype="gridcolumn"/>
+                <height
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="height"
+                    xtype="gridcolumn"/>
+                <size
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="size"
+                    xtype="gridcolumn"/>
+            </columns>
+        </assets>
+    </grid>
+    <actions jcr:primaryType="nt:unstructured">
+        <create
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-create"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-create-icon"
+            split="{Boolean}true"
+            text="New...">
+            <menu jcr:primaryType="nt:unstructured">
+                <createPage
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-page"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createPage"
+                    iconCls="cq-siteadmin-create-page-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Page..."/>
+                <createSite
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-site"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createSite"
+                    iconCls="cq-siteadmin-create-site-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Site..."/>
+                <createLiveCopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-livecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLiveCopy"
+                    iconCls="cq-siteadmin-create-livecopy-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Live Copy..."/>
+                <createLaunch
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-launch"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLaunch"
+                    iconCls="cq-siteadmin-create-launch-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Launch..."/>
+                <separator0
+                    jcr:primaryType="nt:unstructured"
+                    value="-"
+                    xtype="separator"/>
+                <createFile
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-file"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.uploadFiles"
+                    iconCls="cq-siteadmin-create-file-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New File..."/>
+                <createFolder
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-folder"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createFolder"
+                    iconCls="cq-siteadmin-create-folder-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Folder..."/>
+            </menu>
+        </create>
+        <open
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-open"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openPages"
+            iconCls="cq-siteadmin-open-icon"
+            isDefaultAction="{Boolean}true"
+            privileges="[read]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Open"/>
+        <separator0
+            jcr:primaryType="nt:unstructured"
+            value="-"
+            xtype="separator"/>
+        <copy
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-copy"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.copyPages"
+            target="CQ.wcm.SiteAdmin.getAnyTarget"
+            text="Copy"/>
+        <paste
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-paste"
+            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canPaste,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            forceCheck="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.pastePages"
+            privileges="[create]"
+            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+            text="Paste"/>
+        <delete
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-delete"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.deletePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getAllTargets"
+            text="Delete"/>
+        <separator1
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <move
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-move"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.movePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getSingleTarget"
+            text="Move..."/>
+        <separator2
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <activate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-activate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-activate-icon"
+            split="{Boolean}true"
+            text="Activate">
+            <menu jcr:primaryType="nt:unstructured">
+                <activateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.activatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Activate"/>
+                <activateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Activate Later..."/>
+            </menu>
+        </activate>
+        <deactivate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-deactivate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-deactivate-icon"
+            split="{Boolean}true"
+            text="Deactivate">
+            <menu jcr:primaryType="nt:unstructured">
+                <deactivateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.deactivatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Deactivate"/>
+                <deactivateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Deactivate Later..."/>
+            </menu>
+        </deactivate>
+        <separator3
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <lock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-lock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.lockPage"
+            iconCls="cq-siteadmin-lock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Lock"/>
+        <unlock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-unlock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.unlockPage"
+            iconCls="cq-siteadmin-unlock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Unlock"/>
+        <workflow
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-workflow"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.notLocked]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.startWorkflow"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Workflow..."/>
+        <separator5
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <rollout
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-rollout"
+            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.rolloutPage"
+            iconCls="cq-siteadmin-properties-icon"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Roll-out..."/>
+        <separator6
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <properties
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-properties"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openProperties"
+            iconCls="cq-siteadmin-properties-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Properties..."/>
+        <tools
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-tools"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-tools-icon"
+            text="Tools">
+            <menu jcr:primaryType="nt:unstructured">
+                <langcopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-languagecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                    iconCls="cq-siteadmin-languagecopy-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="Language Copy..."/>
+                <findReplace
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                    iconCls="cq-siteadmin-findreplace-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Find &amp; Replace..."/>
+                <restore
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-restore"
+                    iconCls="cq-siteadmin-restore-icon"
+                    text="Restore">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <version
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-version"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreVersion"
+                            iconCls="cq-siteadmin-restore-version-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Version...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a page"
+                                title="Restore Version"/>
+                        </version>
+                        <tree
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-tree"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreTree"
+                            iconCls="cq-siteadmin-restore-tree-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Tree...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a tree"
+                                title="Restore Tree"/>
+                        </tree>
+                    </menu>
+                </restore>
+                <references
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-damadmin-references"
+                    conditions="[CQ.wcm.SiteAdmin.noFolder]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.showReferences"
+                    iconCls="cq-siteadmin-references-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="References..."/>
+                <download
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.download"
+                    iconCls="cq-siteadmin-download-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Download"/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getAnyTarget"
+                    text="Roll-out..."/>
+            </menu>
+        </tools>
+    </actions>
+    <tags jcr:primaryType="nt:unstructured">
+        <emulateIE8
+            jcr:primaryType="nt:unstructured"
+            content="IE=8"
+            http-equiv="X-UA-Compatible"
+            tagName="meta"/>
+        <icon1
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="shortcut icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+        <icon2
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+    </tags>
+    <tabs jcr:primaryType="cq:WidgetCollection">
+        <searchpanel
+            jcr:primaryType="cq:Widget"
+            facetURL="/libs/wcm/core/content/search/searchpanel/facets.overlay.infinity.json"
+            xtype="siteadminsearchpanel">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="title"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <template
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="template"
+                    xtype="gridcolumn"/>
+            </columns>
+            <actions jcr:primaryType="nt:unstructured">
+                <open
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-open"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openPages"
+                    iconCls="cq-siteadmin-open-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Open"/>
+                <delete
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-delete"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.deletePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Delete"/>
+                <separator1
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <move
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-move"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.movePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Move..."/>
+                <separator2
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <activate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-activate-icon"
+                    split="{Boolean}true"
+                    text="Activate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <activateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.activatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Activate"/>
+                        <activateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Activate Later..."/>
+                    </menu>
+                </activate>
+                <deactivate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-deactivate-icon"
+                    split="{Boolean}true"
+                    text="Deactivate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <deactivateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.deactivatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Deactivate"/>
+                        <deactivateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Deactivate Later..."/>
+                    </menu>
+                </deactivate>
+                <lock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-lock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.lockPage"
+                    iconCls="cq-siteadmin-lock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Lock"/>
+                <unlock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-unlock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.unlockPage"
+                    iconCls="cq-siteadmin-unlock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Unlock"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-workflow"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.startWorkflow"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Workflow..."/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Roll-out..."/>
+                <separator5
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+                <properties
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-properties"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noAsset]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openProperties"
+                    iconCls="cq-siteadmin-properties-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Properties..."/>
+                <tools
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-tools"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-tools-icon"
+                    text="Tools">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <langcopy
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-languagecopy"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                            handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                            iconCls="cq-siteadmin-languagecopy-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Language Copy..."/>
+                        <findReplace
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                            iconCls="cq-siteadmin-findreplace-icon"
+                            privileges="[update]"
+                            target="CQ.wcm.SiteAdmin.getSingleTarget"
+                            text="Find &amp; Replace..."/>
+                        <restore
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore"
+                            iconCls="cq-siteadmin-restore-icon"
+                            text="Restore">
+                            <menu jcr:primaryType="nt:unstructured">
+                                <version
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-version"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreVersion"
+                                    iconCls="cq-siteadmin-restore-version-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Version...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a page"
+                                        title="Restore Version"/>
+                                </version>
+                                <tree
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-tree"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreTree"
+                                    iconCls="cq-siteadmin-restore-tree-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Tree...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a tree"
+                                        title="Restore Tree"/>
+                                </tree>
+                            </menu>
+                        </restore>
+                        <references
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-damadmin-references"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.showReferences"
+                            iconCls="cq-siteadmin-references-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="References..."/>
+                        <download
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.download"
+                            iconCls="cq-siteadmin-download-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="Download"/>
+                        <rollout
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-rollout"
+                            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                            handler="CQ.wcm.SiteAdmin.rolloutPage"
+                            iconCls="cq-siteadmin-properties-icon"
+                            target="CQ.wcm.SiteAdmin.getAnyTarget"
+                            text="Roll-out..."/>
+                    </menu>
+                </tools>
+                <separator3
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <separator4
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+            </actions>
+        </searchpanel>
+    </tabs>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/.gitignore b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/.gitignore
new file mode 100644
index 0000000..9f2dd3b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/.gitignore
@@ -0,0 +1 @@
+!.*
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/.vltignore b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/.vltignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/.vltignore
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/cloudservices/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/cloudservices/.content.xml
new file mode 100755
index 0000000..296876f
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/cloudservices/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="sling:Folder"/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/cloudservices/ooyala/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/cloudservices/ooyala/.content.xml
new file mode 100755
index 0000000..c51676c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/cloudservices/ooyala/.content.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="nt:unstructured"
+          url="http://ooyala.com"
+          apiKey="someKey"
+/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/.content.xml
new file mode 100755
index 0000000..0931778
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/.content.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
+          xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+          jcr:primaryType="cq:Page">
+    <jcr:content
+            cq:doctype="html_5"
+            cq:template="/libs/wcm/core/templates/designpage"
+            jcr:primaryType="cq:PageContent"
+            jcr:title="some-thridparty-libs"
+            sling:resourceType="wcm/core/components/designer" />
+
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
new file mode 100755
index 0000000..936074a
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="cq:ClientLibraryFolder"
+          categories="[thirdparty.common]" />
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/generic/pom.xml b/trunk/src/test/resources/test-projects/default-test-projects/generic/pom.xml
new file mode 100755
index 0000000..2907623
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/generic/pom.xml
@@ -0,0 +1,83 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <filterSource>${project.basedir}/filter.xml</filterSource>
+                    <filters>
+                        <filter>
+                            <root>/etc/designs/some-thirdparty-libs</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/cloudservices/ooyala</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/packages/apache/consulting</root>
+                        </filter>
+                        <filter>
+                            <root>/apps/some-thirdparty-libs</root>
+                        </filter>
+                    </filters>
+
+                    <embeddeds>
+                        <embedded>
+                            <groupId>javax.jcr</groupId>
+                            <artifactId>jcr</artifactId>
+                            <target>/libs/install</target>
+                        </embedded>
+                        <embedded>
+                            <groupId>org.apache.jackrabbit.vault</groupId>
+                            <artifactId>org.apache.jackrabbit.vault</artifactId>
+                        </embedded>
+                    </embeddeds>
+                    <embeddedTarget>/apps/install</embeddedTarget>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit.vault</groupId>
+            <artifactId>org.apache.jackrabbit.vault</artifactId>
+            <version>3.1.40</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/expected-files.txt b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/expected-files.txt
new file mode 100644
index 0000000..43b7a3b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/expected-files.txt
@@ -0,0 +1,21 @@
+META-INF/
+META-INF/MANIFEST.MF
+META-INF/maven/
+META-INF/maven/org.apache.jackrabbit.filevault/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.properties
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.xml
+META-INF/vault/
+META-INF/vault/config.xml
+META-INF/vault/filter.xml
+META-INF/vault/properties.xml
+META-INF/vault/settings.xml
+jcr_root/
+jcr_root/apps/
+jcr_root/apps/wcm/
+jcr_root/apps/wcm/core/
+jcr_root/apps/wcm/core/.content.xml
+jcr_root/apps/wcm/core/content/
+jcr_root/apps/wcm/core/content/.content.xml
+jcr_root/apps/wcm/core/content/siteadmin.xml
+jcr_root/apps/wcm/core/empty_directory/
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/content/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/content/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/content/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/content/siteadmin.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/content/siteadmin.xml
new file mode 100755
index 0000000..5984d80
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/content/siteadmin.xml
@@ -0,0 +1,764 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:mixinTypes="[cq:Console]"
+    jcr:primaryType="cq:Widget"
+    jcr:title="AEM WCM"
+    sling:redirect="{Boolean}false"
+    sling:resourceType="cq/ui/components/widget"
+    sling:vanityOrder="{Long}500"
+    sling:vanityPath="/siteadmin"
+    consoleDescription="Create and manage multiple websites."
+    consoleTitle="Websites"
+    historyLink="/bin/wcmcommand?cmd=open&amp;path=${resource.path}"
+    historyResourceTypes="[cq:Page]"
+    historyShow="{Boolean}true"
+    historyTitle="Recently used pages"
+    iconClass="siteadmin"
+    id="cq-siteadmin"
+    jsLibs="[cq.wcm.admin]"
+    noSearch="{Boolean}true"
+    tabTitle="Websites"
+    treeAutoExpandMax="100"
+    xtype="siteadmin">
+    <grid jcr:primaryType="nt:unstructured">
+        <assets
+            jcr:primaryType="nt:unstructured"
+            pageSize="15"
+            pageText="Assets {0} - {1} of {2}"
+            pathRegex="\\/content\\/dam(/.*)?"
+            storeProxySuffix=".assets.json"
+            storeReaderFields="[index,title,label,lockedBy,type,width,height,size,inWorkflow,replication,scheduledTasks,numberer,workflows,lastModified,lastModifiedBy,inProgress,ck]">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <thumbnail
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}false"
+                    usePredefined="thumbnail"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}true"
+                    usePredefined="title"
+                    xssProtect="true"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <status
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="status"
+                    xtype="gridcolumn"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="workflow"
+                    xtype="gridcolumn"/>
+                <width
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="width"
+                    xtype="gridcolumn"/>
+                <height
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="height"
+                    xtype="gridcolumn"/>
+                <size
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="size"
+                    xtype="gridcolumn"/>
+            </columns>
+        </assets>
+    </grid>
+    <actions jcr:primaryType="nt:unstructured">
+        <create
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-create"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-create-icon"
+            split="{Boolean}true"
+            text="New...">
+            <menu jcr:primaryType="nt:unstructured">
+                <createPage
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-page"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createPage"
+                    iconCls="cq-siteadmin-create-page-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Page..."/>
+                <createSite
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-site"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createSite"
+                    iconCls="cq-siteadmin-create-site-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Site..."/>
+                <createLiveCopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-livecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLiveCopy"
+                    iconCls="cq-siteadmin-create-livecopy-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Live Copy..."/>
+                <createLaunch
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-launch"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLaunch"
+                    iconCls="cq-siteadmin-create-launch-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Launch..."/>
+                <separator0
+                    jcr:primaryType="nt:unstructured"
+                    value="-"
+                    xtype="separator"/>
+                <createFile
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-file"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.uploadFiles"
+                    iconCls="cq-siteadmin-create-file-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New File..."/>
+                <createFolder
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-folder"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createFolder"
+                    iconCls="cq-siteadmin-create-folder-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Folder..."/>
+            </menu>
+        </create>
+        <open
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-open"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openPages"
+            iconCls="cq-siteadmin-open-icon"
+            isDefaultAction="{Boolean}true"
+            privileges="[read]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Open"/>
+        <separator0
+            jcr:primaryType="nt:unstructured"
+            value="-"
+            xtype="separator"/>
+        <copy
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-copy"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.copyPages"
+            target="CQ.wcm.SiteAdmin.getAnyTarget"
+            text="Copy"/>
+        <paste
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-paste"
+            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canPaste,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            forceCheck="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.pastePages"
+            privileges="[create]"
+            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+            text="Paste"/>
+        <delete
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-delete"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.deletePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getAllTargets"
+            text="Delete"/>
+        <separator1
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <move
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-move"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.movePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getSingleTarget"
+            text="Move..."/>
+        <separator2
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <activate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-activate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-activate-icon"
+            split="{Boolean}true"
+            text="Activate">
+            <menu jcr:primaryType="nt:unstructured">
+                <activateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.activatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Activate"/>
+                <activateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Activate Later..."/>
+            </menu>
+        </activate>
+        <deactivate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-deactivate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-deactivate-icon"
+            split="{Boolean}true"
+            text="Deactivate">
+            <menu jcr:primaryType="nt:unstructured">
+                <deactivateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.deactivatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Deactivate"/>
+                <deactivateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Deactivate Later..."/>
+            </menu>
+        </deactivate>
+        <separator3
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <lock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-lock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.lockPage"
+            iconCls="cq-siteadmin-lock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Lock"/>
+        <unlock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-unlock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.unlockPage"
+            iconCls="cq-siteadmin-unlock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Unlock"/>
+        <workflow
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-workflow"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.notLocked]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.startWorkflow"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Workflow..."/>
+        <separator5
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <rollout
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-rollout"
+            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.rolloutPage"
+            iconCls="cq-siteadmin-properties-icon"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Roll-out..."/>
+        <separator6
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <properties
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-properties"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openProperties"
+            iconCls="cq-siteadmin-properties-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Properties..."/>
+        <tools
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-tools"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-tools-icon"
+            text="Tools">
+            <menu jcr:primaryType="nt:unstructured">
+                <langcopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-languagecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                    iconCls="cq-siteadmin-languagecopy-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="Language Copy..."/>
+                <findReplace
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                    iconCls="cq-siteadmin-findreplace-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Find &amp; Replace..."/>
+                <restore
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-restore"
+                    iconCls="cq-siteadmin-restore-icon"
+                    text="Restore">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <version
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-version"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreVersion"
+                            iconCls="cq-siteadmin-restore-version-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Version...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a page"
+                                title="Restore Version"/>
+                        </version>
+                        <tree
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-tree"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreTree"
+                            iconCls="cq-siteadmin-restore-tree-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Tree...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a tree"
+                                title="Restore Tree"/>
+                        </tree>
+                    </menu>
+                </restore>
+                <references
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-damadmin-references"
+                    conditions="[CQ.wcm.SiteAdmin.noFolder]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.showReferences"
+                    iconCls="cq-siteadmin-references-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="References..."/>
+                <download
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.download"
+                    iconCls="cq-siteadmin-download-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Download"/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getAnyTarget"
+                    text="Roll-out..."/>
+            </menu>
+        </tools>
+    </actions>
+    <tags jcr:primaryType="nt:unstructured">
+        <emulateIE8
+            jcr:primaryType="nt:unstructured"
+            content="IE=8"
+            http-equiv="X-UA-Compatible"
+            tagName="meta"/>
+        <icon1
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="shortcut icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+        <icon2
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+    </tags>
+    <tabs jcr:primaryType="cq:WidgetCollection">
+        <searchpanel
+            jcr:primaryType="cq:Widget"
+            facetURL="/libs/wcm/core/content/search/searchpanel/facets.overlay.infinity.json"
+            xtype="siteadminsearchpanel">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="title"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <template
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="template"
+                    xtype="gridcolumn"/>
+            </columns>
+            <actions jcr:primaryType="nt:unstructured">
+                <open
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-open"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openPages"
+                    iconCls="cq-siteadmin-open-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Open"/>
+                <delete
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-delete"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.deletePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Delete"/>
+                <separator1
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <move
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-move"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.movePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Move..."/>
+                <separator2
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <activate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-activate-icon"
+                    split="{Boolean}true"
+                    text="Activate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <activateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.activatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Activate"/>
+                        <activateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Activate Later..."/>
+                    </menu>
+                </activate>
+                <deactivate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-deactivate-icon"
+                    split="{Boolean}true"
+                    text="Deactivate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <deactivateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.deactivatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Deactivate"/>
+                        <deactivateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Deactivate Later..."/>
+                    </menu>
+                </deactivate>
+                <lock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-lock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.lockPage"
+                    iconCls="cq-siteadmin-lock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Lock"/>
+                <unlock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-unlock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.unlockPage"
+                    iconCls="cq-siteadmin-unlock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Unlock"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-workflow"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.startWorkflow"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Workflow..."/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Roll-out..."/>
+                <separator5
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+                <properties
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-properties"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noAsset]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openProperties"
+                    iconCls="cq-siteadmin-properties-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Properties..."/>
+                <tools
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-tools"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-tools-icon"
+                    text="Tools">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <langcopy
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-languagecopy"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                            handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                            iconCls="cq-siteadmin-languagecopy-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Language Copy..."/>
+                        <findReplace
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                            iconCls="cq-siteadmin-findreplace-icon"
+                            privileges="[update]"
+                            target="CQ.wcm.SiteAdmin.getSingleTarget"
+                            text="Find &amp; Replace..."/>
+                        <restore
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore"
+                            iconCls="cq-siteadmin-restore-icon"
+                            text="Restore">
+                            <menu jcr:primaryType="nt:unstructured">
+                                <version
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-version"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreVersion"
+                                    iconCls="cq-siteadmin-restore-version-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Version...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a page"
+                                        title="Restore Version"/>
+                                </version>
+                                <tree
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-tree"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreTree"
+                                    iconCls="cq-siteadmin-restore-tree-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Tree...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a tree"
+                                        title="Restore Tree"/>
+                                </tree>
+                            </menu>
+                        </restore>
+                        <references
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-damadmin-references"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.showReferences"
+                            iconCls="cq-siteadmin-references-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="References..."/>
+                        <download
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.download"
+                            iconCls="cq-siteadmin-download-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="Download"/>
+                        <rollout
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-rollout"
+                            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                            handler="CQ.wcm.SiteAdmin.rolloutPage"
+                            iconCls="cq-siteadmin-properties-icon"
+                            target="CQ.wcm.SiteAdmin.getAnyTarget"
+                            text="Roll-out..."/>
+                    </menu>
+                </tools>
+                <separator3
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <separator4
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+            </actions>
+        </searchpanel>
+    </tabs>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/empty_directory/dummy.txt b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/empty_directory/dummy.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/jcr_root/apps/wcm/core/empty_directory/dummy.txt
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/pom.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/pom.xml
new file mode 100755
index 0000000..1695224
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource-empty-directories/pom.xml
@@ -0,0 +1,67 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+       <resources>
+            <resource>
+                <directory>jcr_root</directory>
+                <excludes>
+                    <exclude>**/.vlt</exclude>
+                    <exclude>**/.vltignore</exclude>
+                    <exclude>**/.gitignore</exclude>
+                    <exclude>**/.DS_Store</exclude>
+                    <exclude>**/dummy.txt</exclude>
+                </excludes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <includeEmptyDirs>true</includeEmptyDirs>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <jcrRootSourceDirectory>${project.build.outputDirectory}</jcrRootSourceDirectory>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/apps/wcm/core</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-file-order.txt b/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-file-order.txt
new file mode 100644
index 0000000..9628762
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-file-order.txt
@@ -0,0 +1,6 @@
+META-INF/MANIFEST.MF
+META-INF/vault/
+jcr_root/apps/wcm/core/content/
+jcr_root/_rep_policy.xml
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/cloudservices/ooyala/
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-files.txt b/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-files.txt
new file mode 100644
index 0000000..0b99b6b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-files.txt
@@ -0,0 +1,34 @@
+META-INF/
+META-INF/MANIFEST.MF
+META-INF/vault/
+META-INF/vault/config.xml
+META-INF/vault/filter.xml
+META-INF/vault/properties.xml
+META-INF/vault/settings.xml
+jcr_root/
+jcr_root/apps/
+jcr_root/apps/wcm/
+jcr_root/apps/wcm/core/
+jcr_root/apps/wcm/core/content/
+jcr_root/apps/wcm/core/content/.content.xml
+jcr_root/apps/wcm/core/content/siteadmin.xml
+jcr_root/_rep_policy.xml
+jcr_root/etc/
+jcr_root/etc/designs/
+jcr_root/etc/designs/some-thirdparty-libs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/
+jcr_root/etc/designs/some-thirdparty-libs/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
+jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
+jcr_root/etc/cloudservices/
+jcr_root/etc/cloudservices/ooyala/
+jcr_root/etc/cloudservices/ooyala/.content.xml
+jcr_root/etc/cloudservices/.content.xml
+jcr_root/apps/wcm/.content.xml
+jcr_root/apps/wcm/core/.content.xml
+META-INF/maven/
+META-INF/maven/org.apache.jackrabbit.filevault/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.xml
+META-INF/maven/org.apache.jackrabbit.filevault/package-plugin-test-pkg/pom.properties
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-manifest.txt b/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-manifest.txt
new file mode 100644
index 0000000..566ba64
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/expected-manifest.txt
@@ -0,0 +1,10 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:Packaging test
+Content-Package-Id:org.apache.jackrabbit.filevault:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/apps/some-thirdparty-libs,/apps/wcm/core/content,/etc/cloudservices/ooyala,/etc/designs/some-thirdparty-libs,/etc/packages/apache/consulting,/rep:policy
+Content-Package-Type:mixed
+Created-By:Apache Maven
+Implementation-Title:Packaging test
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/filter.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/filter.xml
new file mode 100644
index 0000000..1e1ec0d
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/filter.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<workspaceFilter version="1.0">
+    <filter root="/apps/wcm/core/content"/>
+    <filter root="/rep:policy" mode="merge"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/_rep_policy.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/_rep_policy.xml
new file mode 100644
index 0000000..d83757c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/_rep_policy.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
+          jcr:primaryType="rep:ACL">
+    <allow
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-repo-reader-service"
+            rep:privileges="{Name}[jcr:read]"/>
+    <allow0
+            jcr:primaryType="rep:GrantACE"
+            rep:principalName="workflow-process-service"
+            rep:privileges="{Name}[jcr:read,rep:write,jcr:versionManagement,jcr:lockManagement,crx:replicate]"/>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/.gitignore b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/.gitignore
new file mode 100644
index 0000000..c57d302
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/.gitignore
@@ -0,0 +1 @@
+# deliberately empty as this is only to check that this will not end up in the generated package
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/content/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/content/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/content/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/content/siteadmin.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/content/siteadmin.xml
new file mode 100755
index 0000000..5984d80
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/apps/wcm/core/content/siteadmin.xml
@@ -0,0 +1,764 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:mixinTypes="[cq:Console]"
+    jcr:primaryType="cq:Widget"
+    jcr:title="AEM WCM"
+    sling:redirect="{Boolean}false"
+    sling:resourceType="cq/ui/components/widget"
+    sling:vanityOrder="{Long}500"
+    sling:vanityPath="/siteadmin"
+    consoleDescription="Create and manage multiple websites."
+    consoleTitle="Websites"
+    historyLink="/bin/wcmcommand?cmd=open&amp;path=${resource.path}"
+    historyResourceTypes="[cq:Page]"
+    historyShow="{Boolean}true"
+    historyTitle="Recently used pages"
+    iconClass="siteadmin"
+    id="cq-siteadmin"
+    jsLibs="[cq.wcm.admin]"
+    noSearch="{Boolean}true"
+    tabTitle="Websites"
+    treeAutoExpandMax="100"
+    xtype="siteadmin">
+    <grid jcr:primaryType="nt:unstructured">
+        <assets
+            jcr:primaryType="nt:unstructured"
+            pageSize="15"
+            pageText="Assets {0} - {1} of {2}"
+            pathRegex="\\/content\\/dam(/.*)?"
+            storeProxySuffix=".assets.json"
+            storeReaderFields="[index,title,label,lockedBy,type,width,height,size,inWorkflow,replication,scheduledTasks,numberer,workflows,lastModified,lastModifiedBy,inProgress,ck]">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <thumbnail
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}false"
+                    usePredefined="thumbnail"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    hidden="{Boolean}true"
+                    usePredefined="title"
+                    xssProtect="true"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <status
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="status"
+                    xtype="gridcolumn"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="workflow"
+                    xtype="gridcolumn"/>
+                <width
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="width"
+                    xtype="gridcolumn"/>
+                <height
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="height"
+                    xtype="gridcolumn"/>
+                <size
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="size"
+                    xtype="gridcolumn"/>
+            </columns>
+        </assets>
+    </grid>
+    <actions jcr:primaryType="nt:unstructured">
+        <create
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-create"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-create-icon"
+            split="{Boolean}true"
+            text="New...">
+            <menu jcr:primaryType="nt:unstructured">
+                <createPage
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-page"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createPage"
+                    iconCls="cq-siteadmin-create-page-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Page..."/>
+                <createSite
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-site"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createSite"
+                    iconCls="cq-siteadmin-create-site-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Site..."/>
+                <createLiveCopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-livecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLiveCopy"
+                    iconCls="cq-siteadmin-create-livecopy-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Live Copy..."/>
+                <createLaunch
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-launch"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createLaunch"
+                    iconCls="cq-siteadmin-create-launch-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Launch..."/>
+                <separator0
+                    jcr:primaryType="nt:unstructured"
+                    value="-"
+                    xtype="separator"/>
+                <createFile
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-file"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.uploadFiles"
+                    iconCls="cq-siteadmin-create-file-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New File..."/>
+                <createFolder
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-create-folder"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canDoFolderOp]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.createFolder"
+                    iconCls="cq-siteadmin-create-folder-icon"
+                    privileges="[create]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="New Folder..."/>
+            </menu>
+        </create>
+        <open
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-open"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openPages"
+            iconCls="cq-siteadmin-open-icon"
+            isDefaultAction="{Boolean}true"
+            privileges="[read]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Open"/>
+        <separator0
+            jcr:primaryType="nt:unstructured"
+            value="-"
+            xtype="separator"/>
+        <copy
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-copy"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.copyPages"
+            target="CQ.wcm.SiteAdmin.getAnyTarget"
+            text="Copy"/>
+        <paste
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-paste"
+            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.canPaste,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            forceCheck="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.pastePages"
+            privileges="[create]"
+            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+            text="Paste"/>
+        <delete
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-delete"
+            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.deletePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getAllTargets"
+            text="Delete"/>
+        <separator1
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <move
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-move"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.movePage"
+            privileges="[delete]"
+            target="CQ.wcm.SiteAdmin.getSingleTarget"
+            text="Move..."/>
+        <separator2
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            value="-"
+            xtype="separator"/>
+        <activate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-activate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-activate-icon"
+            split="{Boolean}true"
+            text="Activate">
+            <menu jcr:primaryType="nt:unstructured">
+                <activateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.activatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Activate"/>
+                <activateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Activate Later..."/>
+            </menu>
+        </activate>
+        <deactivate
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-deactivate"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-deactivate-icon"
+            split="{Boolean}true"
+            text="Deactivate">
+            <menu jcr:primaryType="nt:unstructured">
+                <deactivateNow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-now"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar,contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.deactivatePage"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Deactivate"/>
+                <deactivateLater
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate-later"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.pgatour.canCopyPasteMoveDeleteDeactivatePage]"
+                    context="[toolbar]"
+                    handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                    privileges="[replicate]"
+                    target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                    text="Deactivate Later..."/>
+            </menu>
+        </deactivate>
+        <separator3
+            jcr:primaryType="nt:unstructured"
+            context="[toolbar,contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <lock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-lock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.lockPage"
+            iconCls="cq-siteadmin-lock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Lock"/>
+        <unlock
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-unlock"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+            context="[_contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.unlockPage"
+            iconCls="cq-siteadmin-unlock-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Unlock"/>
+        <workflow
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-workflow"
+            conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.notLocked]"
+            context="[toolbar,contextmenu]"
+            disabled="{Boolean}true"
+            handler="CQ.wcm.SiteAdmin.startWorkflow"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Workflow..."/>
+        <separator5
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <rollout
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-rollout"
+            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.rolloutPage"
+            iconCls="cq-siteadmin-properties-icon"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Roll-out..."/>
+        <separator6
+            jcr:primaryType="nt:unstructured"
+            context="[contextmenu]"
+            listInGridContextMenu="{Boolean}true"
+            value="-"
+            xtype="separator"/>
+        <properties
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-properties"
+            conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+            context="[contextmenu]"
+            handler="CQ.wcm.SiteAdmin.openProperties"
+            iconCls="cq-siteadmin-properties-icon"
+            privileges="[update]"
+            target="CQ.wcm.SiteAdmin.getTargetFromList"
+            text="Properties..."/>
+        <tools
+            jcr:primaryType="nt:unstructured"
+            cls="cq-siteadmin-tools"
+            context="[toolbar]"
+            iconCls="cq-siteadmin-tools-icon"
+            text="Tools">
+            <menu jcr:primaryType="nt:unstructured">
+                <langcopy
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-languagecopy"
+                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                    handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                    iconCls="cq-siteadmin-languagecopy-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                    text="Language Copy..."/>
+                <findReplace
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                    iconCls="cq-siteadmin-findreplace-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Find &amp; Replace..."/>
+                <restore
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-restore"
+                    iconCls="cq-siteadmin-restore-icon"
+                    text="Restore">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <version
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-version"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreVersion"
+                            iconCls="cq-siteadmin-restore-version-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Version...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a page"
+                                title="Restore Version"/>
+                        </version>
+                        <tree
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore-tree"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noFolder,CQ.wcm.SiteAdmin.noAsset]"
+                            handler="CQ.wcm.SiteAdmin.restoreTree"
+                            iconCls="cq-siteadmin-restore-tree-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Restore Tree...">
+                            <tooltip
+                                jcr:primaryType="nt:unstructured"
+                                autoHide="{Boolean}true"
+                                text="Restore an older version of a tree"
+                                title="Restore Tree"/>
+                        </tree>
+                    </menu>
+                </restore>
+                <references
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-damadmin-references"
+                    conditions="[CQ.wcm.SiteAdmin.noFolder]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.showReferences"
+                    iconCls="cq-siteadmin-references-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="References..."/>
+                <download
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-findreplace"
+                    conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.download"
+                    iconCls="cq-siteadmin-download-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Download"/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getAnyTarget"
+                    text="Roll-out..."/>
+            </menu>
+        </tools>
+    </actions>
+    <tags jcr:primaryType="nt:unstructured">
+        <emulateIE8
+            jcr:primaryType="nt:unstructured"
+            content="IE=8"
+            http-equiv="X-UA-Compatible"
+            tagName="meta"/>
+        <icon1
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="shortcut icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+        <icon2
+            jcr:primaryType="nt:unstructured"
+            href="/libs/wcm/core/content/siteadmin.ico"
+            rel="icon"
+            tagName="link"
+            type="image/vnd.microsoft.icon"/>
+    </tags>
+    <tabs jcr:primaryType="cq:WidgetCollection">
+        <searchpanel
+            jcr:primaryType="cq:Widget"
+            facetURL="/libs/wcm/core/content/search/searchpanel/facets.overlay.infinity.json"
+            xtype="siteadminsearchpanel">
+            <columns jcr:primaryType="cq:WidgetCollection">
+                <numberer
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="numberer"
+                    xtype="gridcolumn"/>
+                <title
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="title"
+                    xtype="gridcolumn"/>
+                <name
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="name"
+                    xtype="gridcolumn"/>
+                <published
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="published"
+                    xtype="gridcolumn"/>
+                <modified
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="modified"
+                    xtype="gridcolumn"/>
+                <template
+                    jcr:primaryType="nt:unstructured"
+                    usePredefined="template"
+                    xtype="gridcolumn"/>
+            </columns>
+            <actions jcr:primaryType="nt:unstructured">
+                <open
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-open"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openPages"
+                    iconCls="cq-siteadmin-open-icon"
+                    isDefaultAction="{Boolean}true"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Open"/>
+                <delete
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-delete"
+                    conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.canDeleteReplicatedPage]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.deletePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getAllTargets"
+                    text="Delete"/>
+                <separator1
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <move
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-move"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.movePage"
+                    privileges="[delete]"
+                    target="CQ.wcm.SiteAdmin.getSingleTarget"
+                    text="Move..."/>
+                <separator2
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <activate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-activate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-activate-icon"
+                    split="{Boolean}true"
+                    text="Activate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <activateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.activatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Activate"/>
+                        <activateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-activate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForActivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Activate Later..."/>
+                    </menu>
+                </activate>
+                <deactivate
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-deactivate"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-deactivate-icon"
+                    split="{Boolean}true"
+                    text="Deactivate">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <deactivateNow
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-now"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar,contextmenu]"
+                            handler="CQ.wcm.SiteAdmin.deactivatePage"
+                            isDefaultAction="{Boolean}true"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getAllTargets"
+                            text="Deactivate"/>
+                        <deactivateLater
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-deactivate-later"
+                            conditions="[CQ.wcm.SiteAdmin.hasAnySelection,CQ.wcm.SiteAdmin.notLocked]"
+                            context="[toolbar]"
+                            handler="CQ.wcm.SiteAdmin.scheduleForDeactivation"
+                            privileges="[replicate]"
+                            target="CQ.wcm.SiteAdmin.getMultipleTargetsFromList"
+                            text="Deactivate Later..."/>
+                    </menu>
+                </deactivate>
+                <lock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-lock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.lockPage"
+                    iconCls="cq-siteadmin-lock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Lock"/>
+                <unlock
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-unlock"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection]"
+                    context="[_contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.unlockPage"
+                    iconCls="cq-siteadmin-unlock-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Unlock"/>
+                <workflow
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-workflow"
+                    conditions="[CQ.wcm.SiteAdmin.hasListSelection,CQ.wcm.SiteAdmin.notLocked]"
+                    context="[toolbar,contextmenu]"
+                    disabled="{Boolean}true"
+                    handler="CQ.wcm.SiteAdmin.startWorkflow"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Workflow..."/>
+                <rollout
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-rollout"
+                    conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.rolloutPage"
+                    iconCls="cq-siteadmin-properties-icon"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Roll-out..."/>
+                <separator5
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+                <properties
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-properties"
+                    conditions="[CQ.wcm.SiteAdmin.hasSingleListSelection,CQ.wcm.SiteAdmin.noAsset]"
+                    context="[contextmenu]"
+                    handler="CQ.wcm.SiteAdmin.openProperties"
+                    iconCls="cq-siteadmin-properties-icon"
+                    privileges="[update]"
+                    target="CQ.wcm.SiteAdmin.getTargetFromList"
+                    text="Properties..."/>
+                <tools
+                    jcr:primaryType="nt:unstructured"
+                    cls="cq-siteadmin-tools"
+                    context="[toolbar]"
+                    iconCls="cq-siteadmin-tools-icon"
+                    text="Tools">
+                    <menu jcr:primaryType="nt:unstructured">
+                        <langcopy
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-languagecopy"
+                            conditions="[CQ.wcm.SiteAdmin.hasTreeSelection]"
+                            handler="CQ.wcm.SiteAdmin.openLanguageCopy"
+                            iconCls="cq-siteadmin-languagecopy-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                            text="Language Copy..."/>
+                        <findReplace
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.hasSingleSelection,CQ.wcm.SiteAdmin.notLocked]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.openFindReplaceDialog"
+                            iconCls="cq-siteadmin-findreplace-icon"
+                            privileges="[update]"
+                            target="CQ.wcm.SiteAdmin.getSingleTarget"
+                            text="Find &amp; Replace..."/>
+                        <restore
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-restore"
+                            iconCls="cq-siteadmin-restore-icon"
+                            text="Restore">
+                            <menu jcr:primaryType="nt:unstructured">
+                                <version
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-version"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreVersion"
+                                    iconCls="cq-siteadmin-restore-version-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Version...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a page"
+                                        title="Restore Version"/>
+                                </version>
+                                <tree
+                                    jcr:primaryType="nt:unstructured"
+                                    cls="cq-siteadmin-restore-tree"
+                                    conditions="[CQ.wcm.SiteAdmin.hasTreeSelection,CQ.wcm.SiteAdmin.notLocked,CQ.wcm.SiteAdmin.noAsset]"
+                                    handler="CQ.wcm.SiteAdmin.restoreTree"
+                                    iconCls="cq-siteadmin-restore-tree-icon"
+                                    target="CQ.wcm.SiteAdmin.getTargetFromTree"
+                                    text="Restore Tree...">
+                                    <tooltip
+                                        jcr:primaryType="nt:unstructured"
+                                        autoHide="{Boolean}true"
+                                        text="Restore an older version of a tree"
+                                        title="Restore Tree"/>
+                                </tree>
+                            </menu>
+                        </restore>
+                        <references
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-damadmin-references"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.showReferences"
+                            iconCls="cq-siteadmin-references-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="References..."/>
+                        <download
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-findreplace"
+                            conditions="[CQ.wcm.SiteAdmin.isAsset]"
+                            disabled="{Boolean}true"
+                            handler="CQ.wcm.SiteAdmin.download"
+                            iconCls="cq-siteadmin-download-icon"
+                            target="CQ.wcm.SiteAdmin.getTargetFromList"
+                            text="Download"/>
+                        <rollout
+                            jcr:primaryType="nt:unstructured"
+                            cls="cq-siteadmin-rollout"
+                            conditions="[CQ.wcm.SiteAdmin.isLiveCopySource]"
+                            handler="CQ.wcm.SiteAdmin.rolloutPage"
+                            iconCls="cq-siteadmin-properties-icon"
+                            target="CQ.wcm.SiteAdmin.getAnyTarget"
+                            text="Roll-out..."/>
+                    </menu>
+                </tools>
+                <separator3
+                    jcr:primaryType="nt:unstructured"
+                    context="[toolbar,contextmenu]"
+                    value="-"
+                    xtype="separator"/>
+                <separator4
+                    jcr:primaryType="nt:unstructured"
+                    context="[contextmenu]"
+                    listInGridContextMenu="{Boolean}true"
+                    value="-"
+                    xtype="separator"/>
+            </actions>
+        </searchpanel>
+    </tabs>
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/cloudservices/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/cloudservices/.content.xml
new file mode 100755
index 0000000..296876f
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/cloudservices/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="sling:Folder"/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/cloudservices/ooyala/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/cloudservices/ooyala/.content.xml
new file mode 100755
index 0000000..c51676c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/cloudservices/ooyala/.content.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="nt:unstructured"
+          url="http://ooyala.com"
+          apiKey="someKey"
+/>
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/.content.xml
new file mode 100755
index 0000000..0931778
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/.content.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
+          xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+          jcr:primaryType="cq:Page">
+    <jcr:content
+            cq:doctype="html_5"
+            cq:template="/libs/wcm/core/templates/designpage"
+            jcr:primaryType="cq:PageContent"
+            jcr:title="some-thridparty-libs"
+            sling:resourceType="wcm/core/components/designer" />
+
+</jcr:root>
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
new file mode 100755
index 0000000..936074a
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/.content.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+          jcr:primaryType="cq:ClientLibraryFolder"
+          categories="[thirdparty.common]" />
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/jcr_root/etc/designs/some-thirdparty-libs/clientlibs/thirdparty-common/js.txt
diff --git a/trunk/src/test/resources/test-projects/default-test-projects/resource/pom.xml b/trunk/src/test/resources/test-projects/default-test-projects/resource/pom.xml
new file mode 100755
index 0000000..a79e926
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/default-test-projects/resource/pom.xml
@@ -0,0 +1,68 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>jcr_root</directory>
+                <excludes>
+                    <exclude>**/.vlt</exclude>
+                    <exclude>**/.vltignore</exclude>
+                    <exclude>**/.DS_Store</exclude>
+                </excludes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <filterSource>${project.basedir}/filter.xml</filterSource>
+                    <filters>
+                        <filter>
+                            <root>/etc/designs/some-thirdparty-libs</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/cloudservices/ooyala</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/packages/apache/consulting</root>
+                        </filter>
+                        <filter>
+                            <root>/apps/some-thirdparty-libs</root>
+                        </filter>
+                    </filters>
+                    <embeddedTarget>/apps/some-thirdparty-libs/install</embeddedTarget>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/META-INF/vault/filter.xml b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/META-INF/vault/filter.xml
new file mode 100644
index 0000000..3248a00
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/META-INF/vault/filter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/test"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/expected-filter.xml b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/expected-filter.xml
new file mode 100644
index 0000000..3248a00
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/expected-filter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/test"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/jcr_root/aps/.content.xml b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/jcr_root/aps/.content.xml
new file mode 100755
index 0000000..dcf03f8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/jcr_root/aps/.content.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+    jcr:primaryType="sling:Folder"/>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/pom.xml
new file mode 100644
index 0000000..460831b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/implicit-filter/pom.xml
@@ -0,0 +1,52 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines an implicit filter in META-INF/vault</description>
+    <build>
+        <resources>
+            <resource>
+                <directory>${basedir}/META-INF</directory>
+                <targetPath>${project.build.directory}/vault-work/META-INF</targetPath>
+            </resource>
+            <resource>
+                <directory>${basedir}/jcr_root</directory>
+                <targetPath>.</targetPath>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/META-INF/vault/filter.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/META-INF/vault/filter.xml
new file mode 100644
index 0000000..3248a00
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/META-INF/vault/filter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/test"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/expected-filter.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/expected-filter.xml
new file mode 100644
index 0000000..67a829e
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/expected-filter.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workspaceFilter version="1.0">
+    <filter root="/libs/foo" type="cleanup" />
+    <filter root="/libs/bar" mode="merge">
+        <include pattern="/libs/bar/a" />
+        <include pattern="/libs/bar/b/.*" />
+        <exclude pattern="/libs/bar/foo(/.*)?" />
+    </filter>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/pom.xml
new file mode 100644
index 0000000..01d4daa
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-and-implicit-fails/pom.xml
@@ -0,0 +1,70 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines an implicit filter in META-INF/vault and inline filters.</description>
+    <build>
+        <resources>
+            <resource>
+                <directory>${basedir}/META-INF</directory>
+                <targetPath>${project.build.directory}/vault-work/META-INF</targetPath>
+            </resource>
+            <resource>
+                <directory>${basedir}/jcr_root</directory>
+                <targetPath>.</targetPath>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo</root>
+                            <type>cleanup</type>
+                        </filter>
+                        <filter>
+                            <root>/libs/bar</root>
+                            <mode>merge</mode>
+                            <includes>
+                                <include>/libs/bar/a</include>
+                                <include>/libs/bar/b/.*</include>
+                            </includes>
+                            <excludes>
+                                <exclude>/libs/bar/foo(/.*)?</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/expected-filter1.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/expected-filter1.xml
new file mode 100644
index 0000000..67a829e
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/expected-filter1.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workspaceFilter version="1.0">
+    <filter root="/libs/foo" type="cleanup" />
+    <filter root="/libs/bar" mode="merge">
+        <include pattern="/libs/bar/a" />
+        <include pattern="/libs/bar/b/.*" />
+        <exclude pattern="/libs/bar/foo(/.*)?" />
+    </filter>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/expected-filter2.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/expected-filter2.xml
new file mode 100644
index 0000000..94596d6
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/expected-filter2.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workspaceFilter version="1.0">
+    <filter root="/libs/bar" mode="merge">
+        <include pattern="/libs/bar/a" />
+        <include pattern="/libs/bar/b/.*" />
+        <exclude pattern="/libs/bar/foo(/.*)?" />
+        <exclude pattern="/libs/bar/foo2(/.*)?" />
+    </filter>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/pom1.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/pom1.xml
new file mode 100644
index 0000000..99c390b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/pom1.xml
@@ -0,0 +1,59 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines some inline filters.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo</root>
+                            <type>cleanup</type>
+                        </filter>
+                        <filter>
+                            <root>/libs/bar</root>
+                            <mode>merge</mode>
+                            <includes>
+                                <include>/libs/bar/a</include>
+                                <include>/libs/bar/b/.*</include>
+                            </includes>
+                            <excludes>
+                                <exclude>/libs/bar/foo(/.*)?</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/pom2.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/pom2.xml
new file mode 100644
index 0000000..98a172c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-filter-twice/pom2.xml
@@ -0,0 +1,56 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines some inline filters.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/bar</root>
+                            <mode>merge</mode>
+                            <includes>
+                                <include>/libs/bar/a</include>
+                                <include>/libs/bar/b/.*</include>
+                            </includes>
+                            <excludes>
+                                <exclude>/libs/bar/foo(/.*)?</exclude>
+                                <exclude>/libs/bar/foo2(/.*)?</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-filter/expected-filter.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-filter/expected-filter.xml
new file mode 100644
index 0000000..67a829e
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-filter/expected-filter.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workspaceFilter version="1.0">
+    <filter root="/libs/foo" type="cleanup" />
+    <filter root="/libs/bar" mode="merge">
+        <include pattern="/libs/bar/a" />
+        <include pattern="/libs/bar/b/.*" />
+        <exclude pattern="/libs/bar/foo(/.*)?" />
+    </filter>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/inline-filter/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/inline-filter/pom.xml
new file mode 100644
index 0000000..99c390b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/inline-filter/pom.xml
@@ -0,0 +1,59 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines some inline filters.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo</root>
+                            <type>cleanup</type>
+                        </filter>
+                        <filter>
+                            <root>/libs/bar</root>
+                            <mode>merge</mode>
+                            <includes>
+                                <include>/libs/bar/a</include>
+                                <include>/libs/bar/b/.*</include>
+                            </includes>
+                            <excludes>
+                                <exclude>/libs/bar/foo(/.*)?</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/expected-filter.xml b/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/expected-filter.xml
new file mode 100644
index 0000000..f1cbf9e
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/expected-filter.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workspaceFilter version="1.0">
+    <filter root="/apps/test" />
+    <filter root="/libs/foo" type="cleanup" />
+    <filter root="/libs/bar" mode="merge">
+        <include pattern="/libs/bar/a" />
+        <include pattern="/libs/bar/b/.*" />
+        <exclude pattern="/libs/bar/foo(/.*)?" />
+    </filter>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/filter.xml b/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/filter.xml
new file mode 100644
index 0000000..3248a00
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/filter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/test"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/pom.xml
new file mode 100644
index 0000000..3b7d3eb
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/merge-inline-filter/pom.xml
@@ -0,0 +1,60 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines some inline filters and a filter source.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filterSource>filter.xml</filterSource>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo</root>
+                            <type>cleanup</type>
+                        </filter>
+                        <filter>
+                            <root>/libs/bar</root>
+                            <mode>merge</mode>
+                            <includes>
+                                <include>/libs/bar/a</include>
+                                <include>/libs/bar/b/.*</include>
+                            </includes>
+                            <excludes>
+                                <exclude>/libs/bar/foo(/.*)?</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/no-filter-fails/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/no-filter-fails/pom.xml
new file mode 100644
index 0000000..e2b8ec5
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/no-filter-fails/pom.xml
@@ -0,0 +1,41 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that does not define a filter and fails building.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prefix/expected-filter.xml b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prefix/expected-filter.xml
new file mode 100644
index 0000000..ad2fcec
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prefix/expected-filter.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workspaceFilter version="1.0">
+    <filter root="/chroot" />
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prefix/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prefix/pom.xml
new file mode 100644
index 0000000..be910b8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prefix/pom.xml
@@ -0,0 +1,43 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines no filter but only a prefix.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <prefix>/chroot</prefix>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prop-ok/expected-filter.xml b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prop-ok/expected-filter.xml
new file mode 100644
index 0000000..b2bfa0d
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prop-ok/expected-filter.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workspaceFilter version="1.0" />
diff --git a/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prop-ok/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prop-ok/pom.xml
new file mode 100644
index 0000000..bd32dfb
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/no-filter-with-prop-ok/pom.xml
@@ -0,0 +1,42 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that does not define a filter but ignores missing filters.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnEmptyFilter>false</failOnEmptyFilter>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/expected-filter.xml b/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/expected-filter.xml
new file mode 100644
index 0000000..f6fba28
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/expected-filter.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <!-- this is a comment -->
+    <filter root="/apps/test"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/filter.xml b/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/filter.xml
new file mode 100644
index 0000000..f6fba28
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/filter.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <!-- this is a comment -->
+    <filter root="/apps/test"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/pom.xml b/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/pom.xml
new file mode 100644
index 0000000..c83a082
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/filter-tests/retain-filter-source/pom.xml
@@ -0,0 +1,43 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Test project that defines a filter source.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filterSource>filter.xml</filterSource>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/simple/expected-manifest.txt b/trunk/src/test/resources/test-projects/manifest-generation/simple/expected-manifest.txt
new file mode 100644
index 0000000..552fbab
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/simple/expected-manifest.txt
@@ -0,0 +1,13 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Dependencies:apache/jackrabbit:test.content.package:0.1,apache/jackrabbit:test.content.package:1.0.4
+Content-Package-Description:This is an Example Project to verify that manifest generation is correct.
+Content-Package-Id:my/test/group:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/apps/test,/apps/test2
+Content-Package-Type:application
+Created-By:Apache Maven
+Implementation-Title:Example Default Project
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Import-Package:com.apache.components;version="[5.5.0,6)"
+Import-Package:javax.jcr;version="[2.0.0,3)"
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/simple/pom.xml b/trunk/src/test/resources/test-projects/manifest-generation/simple/pom.xml
new file mode 100644
index 0000000..7f8e03f
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/simple/pom.xml
@@ -0,0 +1,74 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Example Default Project</name>
+    <description>This is an Example Project to verify that manifest generation is correct.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <group>my/test/group</group>
+                    <importPackage>
+                        -*, <!-- provide our own list -->
+                        com.apache.components;version="[5.5.0,6)",
+                        javax.jcr;version="[2.0.0,3)"
+                    </importPackage>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <dependencies>
+                        <dependency>
+                            <groupId>com.apache.jackrabbit.filevault</groupId>
+                            <artifactId>test.content.package</artifactId>
+                            <version>[0.1,)</version>
+                        </dependency>
+                        <dependency>
+                            <!-- maven dependency reference, should generate [0.8.600,) version range -->
+                            <groupId>com.apache.jackrabbit.filevault</groupId>
+                            <artifactId>test.content.package</artifactId>
+                        </dependency>
+                    </dependencies>
+                    <filters>
+                        <filter>
+                            <root>/apps/test</root>
+                        </filter>
+                        <filter>
+                            <root>/apps/test2</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>com.apache.jackrabbit.filevault</groupId>
+            <artifactId>test.content.package</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${testcontent.directory}/test-package.zip</systemPath>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-bundles/expected-manifest.txt b/trunk/src/test/resources/test-projects/manifest-generation/with-bundles/expected-manifest.txt
new file mode 100644
index 0000000..5739ae3
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-bundles/expected-manifest.txt
@@ -0,0 +1,44 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:This is an Example Project to verify that manifest generation is correct.
+Content-Package-Id:my/test/group:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/apps/test
+Content-Package-Type:application
+Created-By:Apache Maven
+Implementation-Title:Example Default Project
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Import-Package:javax.jcr.lock;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.nodetype;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.observation;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.query.qom;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.query;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.retention;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.security;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.util;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr.version;version="[1.0.0,3.0.0)"
+Import-Package:javax.jcr;version="[1.0.0,3.0.0)"
+Import-Package:org.apache.foo;
+Import-Package:org.apache.jackrabbit.vault.fs.api;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.fs.config;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.fs.filter;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.fs.io;version="[2.5.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.fs.spi;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.fs;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.packaging.events;version="[1.0.0,2.0.0)"
+Import-Package:org.apache.jackrabbit.vault.packaging;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.util.xml.serialize;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.util.xml.xerces.dom;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.util.xml.xerces.util;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.util.xml.xerces.xni.parser;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.util.xml.xerces.xni;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.util.xml;version="[2.4.0,3.0.0)"
+Import-Package:org.apache.jackrabbit.vault.util;version="[2.4.0,3.0.0)"
+Import-Package:org.osgi.framework;version="[1.7.0,2.0.0)"
+Import-Package:org.osgi.resource;version="[1.0.0,2.0.0)"
+Import-Package:org.osgi.service.condpermadmin;version="[1.1.1,2.0.0)"
+Import-Package:org.osgi.service.packageadmin;version="[1.2.0,2.0.0)"
+Import-Package:org.osgi.service.permissionadmin;version="[1.2.0,2.0.0)"
+Import-Package:org.osgi.service.startlevel;version="[1.1.0,2.0.0)"
+Import-Package:org.osgi.service.url;version="[1.0.0,2.0.0)"
+Import-Package:org.osgi.util.tracker;version="[1.5.1,2.0.0)"
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-bundles/pom.xml b/trunk/src/test/resources/test-projects/manifest-generation/with-bundles/pom.xml
new file mode 100644
index 0000000..3467e64
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-bundles/pom.xml
@@ -0,0 +1,78 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Example Default Project</name>
+    <description>This is an Example Project to verify that manifest generation is correct.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <group>my/test/group</group>
+                    <importUnusedPackages>true</importUnusedPackages>
+                    <importPackage>
+                        -aQute*, <!-- example of removing a package -->
+                        -org.osgi.framework.*, <!-- should keep the org.osgi.framework but remove subpackages-->
+                        javax.jcr*;version="[1.0.0,3.0.0)", <!-- example of altering existing packages -->
+                        org.apache.foo  <!-- example of adding a new package -->
+                    </importPackage>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/apps/test</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit.vault</groupId>
+            <artifactId>org.apache.jackrabbit.vault</artifactId>
+            <version>3.1.40</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <!-- unused dependency -->
+            <groupId>biz.aQute</groupId>
+            <artifactId>bndlib</artifactId>
+            <version>1.43.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>5.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-code/expected-manifest.txt b/trunk/src/test/resources/test-projects/manifest-generation/with-code/expected-manifest.txt
new file mode 100644
index 0000000..eb92a9a
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-code/expected-manifest.txt
@@ -0,0 +1,13 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:This is an Example Project to verify that manifest generation is correct.
+Content-Package-Id:my/test/group:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/libs/apache
+Content-Package-Type:application
+Created-By:Apache Maven
+Implementation-Title:Example Default Project
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Import-Package:javax.servlet;
+Import-Package:org.apache.jackrabbit.api.query;
+Import-Package:org.apache.sling.api.resource;version="[2.5.0,3.0.0)"
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-code/jcr_root/libs/apache/IncludeUseObject.java b/trunk/src/test/resources/test-projects/manifest-generation/with-code/jcr_root/libs/apache/IncludeUseObject.java
new file mode 100644
index 0000000..2c917a9
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-code/jcr_root/libs/apache/IncludeUseObject.java
@@ -0,0 +1,58 @@
+/*
+ * 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 libs.apache;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import org.apache.jackrabbit.api.query.JackrabbitQueryResult;
+import org.apache.sling.api.resource.Resource;
+
+public class IncludeUseObject {
+
+    private static final String RESOURCE = "includeResource";
+    private static final String RESOURCE_TYPE = "includeResourceType";
+    private static final String OPTIONS = "includeOptions";
+    private static final String SCRIPT = "includeScript";
+
+
+    protected void activate() {
+        // only for testing reference to oaj.api.query package
+        String testOnly = JackrabbitQueryResult.class.getName();
+        // only for testing reference to oas.api.resource package
+        String resource = Resource.class.getName();
+    }
+
+    /**
+     * Include the provided resource, using the provided resource type and options.
+     *
+     * @return Output from including the resource
+     */
+    public String includeResource() throws ServletException, IOException {
+        return "";
+    }
+
+    /**
+     * Include the provided script, using the provided options.
+     *
+     * @return Output from including the script
+     */
+    public String includeScript() throws ServletException, IOException {
+        return "";
+    }
+}
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-code/pom.xml b/trunk/src/test/resources/test-projects/manifest-generation/with-code/pom.xml
new file mode 100644
index 0000000..77a37d3
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-code/pom.xml
@@ -0,0 +1,74 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Example Default Project</name>
+    <description>This is an Example Project to verify that manifest generation is correct.</description>
+    <build>
+        <sourceDirectory>${project.basedir}/jcr_root</sourceDirectory>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <group>my/test/group</group>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/apache</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.7.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-api</artifactId>
+            <version>2.7.5</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <!-- unused dependency -->
+            <groupId>biz.aQute</groupId>
+            <artifactId>bndlib</artifactId>
+            <version>1.43.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-unused-dependencies/expected-manifest.txt b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-dependencies/expected-manifest.txt
new file mode 100644
index 0000000..d7527d7
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-dependencies/expected-manifest.txt
@@ -0,0 +1,10 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:This is an Example Project to verify that manifest generation is correct.
+Content-Package-Id:my/test/group:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/apps/test
+Content-Package-Type:application
+Created-By:Apache Maven
+Implementation-Title:Example Default Project
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-unused-dependencies/pom.xml b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-dependencies/pom.xml
new file mode 100644
index 0000000..ac33c3d
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-dependencies/pom.xml
@@ -0,0 +1,70 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Example Default Project</name>
+    <description>This is an Example Project to verify that manifest generation is correct.</description>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <group>my/test/group</group>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/apps/test</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit.vault</groupId>
+            <artifactId>org.apache.jackrabbit.vault</artifactId>
+            <version>3.1.40</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>biz.aQute</groupId>
+            <artifactId>bndlib</artifactId>
+            <version>1.43.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>5.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/expected-manifest.txt b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/expected-manifest.txt
new file mode 100644
index 0000000..eb92a9a
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/expected-manifest.txt
@@ -0,0 +1,13 @@
+Archiver-Version:Plexus Archiver
+Content-Package-Description:This is an Example Project to verify that manifest generation is correct.
+Content-Package-Id:my/test/group:package-plugin-test-pkg:1.0.0-SNAPSHOT
+Content-Package-Roots:/libs/apache
+Content-Package-Type:application
+Created-By:Apache Maven
+Implementation-Title:Example Default Project
+Implementation-Vendor-Id:org.apache.jackrabbit.filevault
+Implementation-Version:1.0.0-SNAPSHOT
+Import-Package:javax.servlet;
+Import-Package:org.apache.jackrabbit.api.query;
+Import-Package:org.apache.sling.api.resource;version="[2.5.0,3.0.0)"
+Manifest-Version:1.0
\ No newline at end of file
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/jcr_root/libs/apache/IncludeUseObject.java b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/jcr_root/libs/apache/IncludeUseObject.java
new file mode 100644
index 0000000..2c917a9
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/jcr_root/libs/apache/IncludeUseObject.java
@@ -0,0 +1,58 @@
+/*
+ * 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 libs.apache;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import org.apache.jackrabbit.api.query.JackrabbitQueryResult;
+import org.apache.sling.api.resource.Resource;
+
+public class IncludeUseObject {
+
+    private static final String RESOURCE = "includeResource";
+    private static final String RESOURCE_TYPE = "includeResourceType";
+    private static final String OPTIONS = "includeOptions";
+    private static final String SCRIPT = "includeScript";
+
+
+    protected void activate() {
+        // only for testing reference to oaj.api.query package
+        String testOnly = JackrabbitQueryResult.class.getName();
+        // only for testing reference to oas.api.resource package
+        String resource = Resource.class.getName();
+    }
+
+    /**
+     * Include the provided resource, using the provided resource type and options.
+     *
+     * @return Output from including the resource
+     */
+    public String includeResource() throws ServletException, IOException {
+        return "";
+    }
+
+    /**
+     * Include the provided script, using the provided options.
+     *
+     * @return Output from including the script
+     */
+    public String includeScript() throws ServletException, IOException {
+        return "";
+    }
+}
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/parent/pom.xml b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/parent/pom.xml
new file mode 100644
index 0000000..99d8cf8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/parent/pom.xml
@@ -0,0 +1,46 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>Example Parent Project</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.7.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <!-- unused dependency from parent should not show up in report -->
+            <groupId>biz.aQute</groupId>
+            <artifactId>bndlib</artifactId>
+            <version>1.43.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/pom.xml b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/pom.xml
new file mode 100644
index 0000000..3b7a784
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/manifest-generation/with-unused-parent-dependencies/pom.xml
@@ -0,0 +1,72 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.jackrabbit.filevault</groupId>
+        <artifactId>package-plugin-test-pkg-parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>parent</relativePath>
+    </parent>
+
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Example Default Project</name>
+    <description>This is an Example Project to verify that manifest generation is correct.</description>
+    <build>
+        <sourceDirectory>${project.basedir}/jcr_root</sourceDirectory>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <group>my/test/group</group>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <excludedLibraries>
+                        biz.aQute:bndlib
+                    </excludedLibraries>
+                    <filters>
+                        <filter>
+                            <root>/libs/apache</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-api</artifactId>
+            <version>2.7.5</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <!-- unused dependency -->
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.10.3</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/override-description/pom.xml b/trunk/src/test/resources/test-projects/override-description/pom.xml
new file mode 100644
index 0000000..8f1c531
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/override-description/pom.xml
@@ -0,0 +1,47 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+
+    <description>Description from project</description>
+    <build>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnEmptyFilter>false</failOnEmptyFilter>
+                    <properties>
+                        <description>Description from plugin</description>
+                        <empty></empty>
+                    </properties>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/package-type-auto/application-cleanup/pom.xml b/trunk/src/test/resources/test-projects/package-type-auto/application-cleanup/pom.xml
new file mode 100644
index 0000000..77fce6c
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-type-auto/application-cleanup/pom.xml
@@ -0,0 +1,45 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/apps/test</root>
+                        </filter>
+                        <filter>
+                            <root>/etc/clientlibs/cleanup</root>
+                            <type>cleanup</type>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/package-type-auto/application-sourced/filter.xml b/trunk/src/test/resources/test-projects/package-type-auto/application-sourced/filter.xml
new file mode 100644
index 0000000..d53e2ed
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-type-auto/application-sourced/filter.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<workspaceFilter version="1.0">
+    <filter root="/libs/granite/replication"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/package-type-auto/application-sourced/pom.xml b/trunk/src/test/resources/test-projects/package-type-auto/application-sourced/pom.xml
new file mode 100644
index 0000000..64956bc
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-type-auto/application-sourced/pom.xml
@@ -0,0 +1,37 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filterSource>${project.basedir}/filter.xml</filterSource>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/package-type-auto/application/pom.xml b/trunk/src/test/resources/test-projects/package-type-auto/application/pom.xml
new file mode 100644
index 0000000..4849b80
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-type-auto/application/pom.xml
@@ -0,0 +1,41 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>false</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/apps/test</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/package-type-auto/container/pom.xml b/trunk/src/test/resources/test-projects/package-type-auto/container/pom.xml
new file mode 100644
index 0000000..7b262e8
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-type-auto/container/pom.xml
@@ -0,0 +1,38 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <!-- TODO: implement auto detection -->
+                    <failOnEmptyFilter>false</failOnEmptyFilter>
+                    <packageType>container</packageType>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/package-type-auto/content/pom.xml b/trunk/src/test/resources/test-projects/package-type-auto/content/pom.xml
new file mode 100644
index 0000000..a56d532
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-type-auto/content/pom.xml
@@ -0,0 +1,40 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <filters>
+                        <filter>
+                            <root>/content/geometrixx</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/package-type-auto/mixed/pom.xml b/trunk/src/test/resources/test-projects/package-type-auto/mixed/pom.xml
new file mode 100644
index 0000000..8ec1980
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-type-auto/mixed/pom.xml
@@ -0,0 +1,43 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <filters>
+                        <filter>
+                            <root>/libs/geometrixx</root>
+                        </filter>
+                        <filter>
+                            <root>/content/geometrixx</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/package-types/pom.xml b/trunk/src/test/resources/test-projects/package-types/pom.xml
new file mode 100644
index 0000000..b293ef7
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/package-types/pom.xml
@@ -0,0 +1,37 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <packageType>${test.packageType}</packageType>
+                    <failOnEmptyFilter>false</failOnEmptyFilter>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps-implicit/META-INF/vault/filter.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps-implicit/META-INF/vault/filter.xml
new file mode 100644
index 0000000..3248a00
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps-implicit/META-INF/vault/filter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<workspaceFilter version="1.0">
+    <filter root="/apps/test"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps-implicit/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps-implicit/pom.xml
new file mode 100755
index 0000000..160e10b
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps-implicit/pom.xml
@@ -0,0 +1,48 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${basedir}/META-INF</directory>
+                <targetPath>${project.build.directory}/vault-work/META-INF</targetPath>
+            </resource>
+            <resource>
+                <directory>${basedir}/jcr_root</directory>
+                <targetPath>.</targetPath>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps/pom.xml
new file mode 100755
index 0000000..8ed4e13
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-missing-deps/pom.xml
@@ -0,0 +1,43 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo</root>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-contains/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-contains/pom.xml
new file mode 100755
index 0000000..243bbcf
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-contains/pom.xml
@@ -0,0 +1,59 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo/bar/components/foo</root>
+                        </filter>
+                    </filters>
+                    <dependencies>
+                        <dependency>
+                            <groupId>com.apache.jackrabbit.filevault</groupId>
+                            <artifactId>test.content.package</artifactId>
+                        </dependency>
+                    </dependencies>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>com.apache.jackrabbit.filevault</groupId>
+            <artifactId>test.content.package</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${testcontent.directory}/test-package.zip</systemPath>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-cover/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-cover/pom.xml
new file mode 100755
index 0000000..c119599
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-cover/pom.xml
@@ -0,0 +1,59 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/super/project</root>
+                        </filter>
+                    </filters>
+                    <dependencies>
+                        <dependency>
+                            <groupId>com.apache.jackrabbit.filevault</groupId>
+                            <artifactId>test.content.package</artifactId>
+                        </dependency>
+                    </dependencies>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>com.apache.jackrabbit.filevault</groupId>
+            <artifactId>test.content.package</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${testcontent.directory}/test-package.zip</systemPath>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-maven-deps/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-maven-deps/pom.xml
new file mode 100755
index 0000000..9670f5f
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/fail-no-maven-deps/pom.xml
@@ -0,0 +1,49 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo</root>
+                        </filter>
+                    </filters>
+                    <dependencies>
+                        <dependency>
+                            <group>org/apache</group>
+                            <name>jackrabbit.content</name>
+                        </dependency>
+                    </dependencies>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup-filter/filter.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup-filter/filter.xml
new file mode 100644
index 0000000..544b3dd
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup-filter/filter.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<workspaceFilter version="1.0">
+    <filter type="cleanup" root="/libs/foo"/>
+</workspaceFilter>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup-filter/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup-filter/pom.xml
new file mode 100755
index 0000000..da78718
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup-filter/pom.xml
@@ -0,0 +1,39 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filterSource>${project.basedir}/filter.xml</filterSource>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup/pom.xml
new file mode 100755
index 0000000..49f0048
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/no-error-cleanup/pom.xml
@@ -0,0 +1,44 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/libs/foo</root>
+                            <type>cleanup</type>
+                        </filter>
+                    </filters>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/no-errors/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/no-errors/pom.xml
new file mode 100755
index 0000000..38824d2
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/no-errors/pom.xml
@@ -0,0 +1,62 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/var/foo/bar/components</root>
+                        </filter>
+                        <filter>
+                            <root>/tmp/foo</root>
+                        </filter>
+                    </filters>
+                    <dependencies>
+                        <dependency>
+                            <groupId>com.apache.jackrabbit.filevault</groupId>
+                            <artifactId>test.content.package</artifactId>
+                        </dependency>
+                    </dependencies>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>com.apache.jackrabbit.filevault</groupId>
+            <artifactId>test.content.package</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${testcontent.directory}/test-package.zip</systemPath>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/trunk/src/test/resources/test-projects/validate-deps-projects/repo-structure-pkg/pom.xml b/trunk/src/test/resources/test-projects/validate-deps-projects/repo-structure-pkg/pom.xml
new file mode 100755
index 0000000..735579a
--- /dev/null
+++ b/trunk/src/test/resources/test-projects/validate-deps-projects/repo-structure-pkg/pom.xml
@@ -0,0 +1,62 @@
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>${plugin.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnDependencyErrors>true</failOnDependencyErrors>
+                    <filters>
+                        <filter>
+                            <root>/var/foo/bar/components</root>
+                        </filter>
+                        <filter>
+                            <root>/tmp/foo</root>
+                        </filter>
+                    </filters>
+                    <repositoryStructurePackages>
+                        <repositoryStructurePackage>
+                            <groupId>com.apache.jackrabbit.filevault</groupId>
+                            <artifactId>test.content.package</artifactId>
+                        </repositoryStructurePackage>
+                    </repositoryStructurePackages>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>com.apache.jackrabbit.filevault</groupId>
+            <artifactId>test.content.package</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${testcontent.directory}/test-package.zip</systemPath>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+</project>