Merge remote-tracking branch 'origin/feature/329198'
diff --git a/org.eclipse.virgo.ide.feature/feature.xml b/org.eclipse.virgo.ide.feature/feature.xml
index 6144eba..bca7023 100644
--- a/org.eclipse.virgo.ide.feature/feature.xml
+++ b/org.eclipse.virgo.ide.feature/feature.xml
@@ -72,6 +72,13 @@
          install-size="0"
          version="0.0.0"
          unpack="false"/>
+         
+   <plugin
+         id="org.eclipse.virgo.ide.pde.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>         
 
    <plugin
          id="org.eclipse.virgo.ide.jdt.core"
diff --git a/org.eclipse.virgo.ide.pde.core/.classpath b/org.eclipse.virgo.ide.pde.core/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.virgo.ide.pde.core/.options b/org.eclipse.virgo.ide.pde.core/.options
new file mode 100644
index 0000000..0eb83ad
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.options
@@ -0,0 +1 @@
+org.eclipse.virgo.ide.pde.core/debug=false
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.pde.core/.project b/org.eclipse.virgo.ide.pde.core/.project
new file mode 100644
index 0000000..b193575
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.virgo.ide.pde.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..4321bd9
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,371 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=80
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=1
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=1
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=150
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..6c98016
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,118 @@
+cleanup.add_default_serial_version_id=false
+cleanup.add_generated_serial_version_id=true
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=true
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=true
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=false
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=true
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=true
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=true
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=true
+cleanup.use_this_for_non_static_field_access=true
+cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Virgo Web Server - Code Clean Up
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Virgo Web Server - Code Formatter
+formatter_settings_version=12
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.ltk.core.refactoring.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000..5e7f2bd
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,3 @@
+#Tue Aug 18 22:42:26 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..d8c6d26
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Mon Jun 25 03:02:37 GMT 2007
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.pde.core.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..455d78f
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,19 @@
+#Thu Mar 05 23:16:15 CET 2009
+eclipse.preferences.version=1
+resolve.requirebundle=false
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=2
+compilers.p.missing-bundle-classpath-entries=1
+compilers.p.missing-packages=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.use-project=true
diff --git a/org.eclipse.virgo.ide.pde.core/META-INF/MANIFEST.MF b/org.eclipse.virgo.ide.pde.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2d8da20
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.virgo.ide.pde.core;singleton:=true
+Bundle-Version: 1.0.1.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.debug.core,
+ org.eclipse.jdt.core,
+ org.eclipse.pde.core,
+ org.eclipse.wst.common.project.facet.core,
+ org.eclipse.virgo.ide.facet.core
+Export-Package: org.eclipse.virgo.ide.pde.core.internal,
+ org.eclipse.virgo.ide.pde.core.internal.cmd
+Bundle-Localization: OSGI-INF/l10n/bundle
diff --git a/org.eclipse.virgo.ide.pde.core/OSGI-INF/l10n/bundle.properties b/org.eclipse.virgo.ide.pde.core/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 0000000..3f72026
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,5 @@
+Bundle-Name=Eclipse Virgo IDE (PDE Support)
+Bundle-Vendor=Eclipse.org - Virgo
+
+pdeNature=Eclipse Virgo PDE nature
+pdeBuilder=Eclipse Virgo PDE builder
diff --git a/org.eclipse.virgo.ide.pde.core/about.html b/org.eclipse.virgo.ide.pde.core/about.html
new file mode 100644
index 0000000..2abb573
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>April 13, 2012</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.pde.core/build.properties b/org.eclipse.virgo.ide.pde.core/build.properties
new file mode 100644
index 0000000..57e388d
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+               META-INF/,\
+               .,\
+               OSGI-INF/l10n/bundle.properties,\
+               OSGI-INF/,\
+               .options
diff --git a/org.eclipse.virgo.ide.pde.core/plugin.xml b/org.eclipse.virgo.ide.pde.core/plugin.xml
new file mode 100644
index 0000000..b6eb52c
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/plugin.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<!--
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+-->
+<plugin>
+
+   <extension
+         id="builder"
+         name="%pdeBuilder"
+         point="org.eclipse.core.resources.builders">
+      <builder
+            hasNature="true">
+         <run
+               class="org.eclipse.virgo.ide.pde.core.internal.Builder">
+         </run>
+      </builder>
+   </extension>
+   <extension
+         id="nature"
+         name="%pdeNature"
+         point="org.eclipse.core.resources.natures">
+      <runtime>
+         <run
+               class="org.eclipse.virgo.ide.pde.core.internal.Nature">
+         </run>
+      </runtime>
+      <builder
+            id="org.eclipse.virgo.ide.pde.core.builder">
+      </builder>
+      <requires-nature
+            id="org.eclipse.virgo.ide.facet.core.bundlenature">
+      </requires-nature>
+      <requires-nature
+            id="org.eclipse.pde.PluginNature">
+      </requires-nature>
+   </extension>
+
+</plugin>
diff --git a/org.eclipse.virgo.ide.pde.core/pom.xml b/org.eclipse.virgo.ide.pde.core/pom.xml
new file mode 100644
index 0000000..eb81e8d
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>org.eclipse.virgo.ide.parent</artifactId>
+    <groupId>org.eclipse.virgo.ide</groupId>
+    <version>1.0.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>org.eclipse.virgo.ide.pde.core</artifactId>
+  <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Builder.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Builder.java
new file mode 100644
index 0000000..6395edf
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Builder.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.META_INF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.OSGI_INF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.WebContent;
+import static org.eclipse.virgo.ide.pde.core.internal.Helper.DEBUG;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A custom build command that ensures that the content of META-INF is copied to the binary folder of the plug-in
+ * project so that Virgo Server can find it via class-path.
+ * <p>
+ * Additionally the builder parsers the MANIFEST.MF and copies to bin folder any nested JAR (Bundle-ClassPath header)
+ * and native libraries (Bundle-NativeCode header).
+ *
+ *
+ *
+ */
+public class Builder extends IncrementalProjectBuilder {
+
+    private static final Path WEBCONTENT_PATH = new Path(Constants.WebContent);
+
+    private static final Path OSGI_INF_PATH = new Path(OSGI_INF);
+
+    private static final Path META_INF_PATH = new Path(META_INF);
+
+    private static abstract class Predicate<T> {
+
+        public abstract boolean accept(T t);
+
+        public final static <T> Predicate<T> tautology() {
+            return new Predicate<T>() {
+
+                @Override
+                public boolean accept(T t) {
+                    return true;
+                }
+            };
+        }
+    }
+
+    public Builder() {
+        super();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map,
+     * org.eclipse.core.runtime.IProgressMonitor)
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
+        Helper.forcePDEEditor(getProject());
+
+        IPath outputLocation = Helper.getOutputLocation(getProject());
+
+        if (DEBUG) {
+            String typeStr = "UNKNOWN"; //$NON-NLS-1$
+            switch (kind) {
+                case INCREMENTAL_BUILD:
+                    typeStr = "INCREMENTAL"; //$NON-NLS-1$
+                    break;
+                case AUTO_BUILD:
+                    typeStr = "AUTO"; //$NON-NLS-1$
+                    break;
+                case CLEAN_BUILD:
+                    typeStr = "CLEAN"; //$NON-NLS-1$
+                    break;
+                case FULL_BUILD:
+                    typeStr = "FULL"; //$NON-NLS-1$
+                    break;
+            }
+            debug("Build type " + typeStr + " output location: " + outputLocation.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (kind == CLEAN_BUILD) {
+            if (DEBUG) {
+                debug("Doing nothing"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        if (kind == FULL_BUILD) {
+            fullBuild(outputLocation, monitor);
+        } else {
+            IResourceDelta delta = getDelta(getProject());
+            if (delta == null) {
+                if (DEBUG) {
+                    debug("Incremental build was requested but delta is null, performing full build"); //$NON-NLS-1$
+                }
+                fullBuild(outputLocation, monitor);
+                return null;
+            }
+
+            if (!Helper.checkMETAINFFolder(getProject())) {
+                if (DEBUG) {
+                    debug("Incremental build was requested but META-INF folder is missing from output location, performing full build"); //$NON-NLS-1$
+                }
+                fullBuild(outputLocation, monitor);
+                return null;
+            }
+
+            if (!Helper.checkLibraries(getProject())) {
+                if (DEBUG) {
+                    debug("Incremental build was requested but some libraries are missing from output location, performing full build"); //$NON-NLS-1$
+                }
+                fullBuild(outputLocation, monitor);
+                return null;
+            }
+
+            if (DEBUG) {
+                debug("Incremental build"); //$NON-NLS-1$
+            }
+            incrementalBuild(outputLocation, delta, monitor);
+            return null;
+        }
+
+        return null;
+    }
+
+    private void incrementalBuild(IPath outputLocation, final IResourceDelta delta, IProgressMonitor monitor) throws CoreException {
+        monitor.beginTask(Messages.Builder_IncrementalBuildMessage, 4);
+
+        if (delta.findMember(META_INF_PATH) != null) {
+            buildMetaInf(outputLocation, new SubProgressMonitor(monitor, 1));
+        } else {
+            monitor.worked(1);
+        }
+
+        if (delta.findMember(OSGI_INF_PATH) != null) {
+            buildOSGIInf(outputLocation, new SubProgressMonitor(monitor, 1));
+        } else {
+            monitor.worked(1);
+        }
+
+        if (delta.findMember(WEBCONTENT_PATH) != null) {
+            buildWebContent(outputLocation, new SubProgressMonitor(monitor, 1));
+        } else {
+            monitor.worked(1);
+        }
+
+        Predicate<String> selectChanged = new Predicate<String>() {
+
+            @Override
+            public boolean accept(String t) {
+                return delta.findMember(new Path(t)) != null;
+            }
+        };
+        buildLibraries(selectChanged, outputLocation, new SubProgressMonitor(monitor, 1));
+        monitor.done();
+    }
+
+    private void fullBuild(IPath outputLocation, IProgressMonitor monitor) throws CoreException {
+        if (DEBUG) {
+            debug("Full build, output location: " + outputLocation.toOSString()); //$NON-NLS-1$
+        }
+        monitor.beginTask(Messages.Builder_FullBuildMessage, 4);
+
+        buildMetaInf(outputLocation, new SubProgressMonitor(monitor, 1));
+        buildOSGIInf(outputLocation, new SubProgressMonitor(monitor, 1));
+        buildWebContent(outputLocation, new SubProgressMonitor(monitor, 1));
+
+        buildLibraries(null, outputLocation, new SubProgressMonitor(monitor, 1));
+
+        monitor.done();
+
+    }
+
+    private void buildLibraries(Predicate<String> predicate, IPath outputLocation, IProgressMonitor monitor) throws CoreException {
+        IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+        binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+
+        java.util.List<String> toCopy = Helper.getLibraryEntries(getProject());
+
+        monitor.beginTask(Messages.Builder_copy_libraries, toCopy.size());
+        for (String path : toCopy) {
+            if (predicate == null || predicate.accept(path)) {
+                Helper.copyLibraryToBin(getProject(), path);
+            }
+            monitor.worked(1);
+        }
+        monitor.done();
+    }
+
+    private void buildWebContent(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+        IFolder webContentFolder = getProject().getFolder(WebContent);
+        if (webContentFolder.exists()) {
+            buildFilesInFolder(monitor, webContentFolder, ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation),
+                Predicate.<IResource> tautology(), true);
+
+        }
+    }
+
+    private void buildMetaInf(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+        IProject project = getProject();
+        IFolder infFolder = project.getFolder(META_INF);
+
+        if (!infFolder.exists()) {
+            error(META_INF + " folder not found for project: " + getProject().getName()); //$NON-NLS-1$
+            return;
+        }
+        buildTopLevelFolder(outputLocation, monitor, infFolder, META_INF);
+    }
+
+    private void buildOSGIInf(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+        IProject project = getProject();
+        IFolder infFolder = project.getFolder(OSGI_INF);
+
+        if (!infFolder.exists()) {
+            return;
+        }
+        buildTopLevelFolder(outputLocation, monitor, infFolder, OSGI_INF);
+    }
+
+    private void buildTopLevelFolder(IPath outputLocation, IProgressMonitor monitor, IFolder infFolder, String folder) throws CoreException {
+        IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+        if (!binFolder.exists()) {
+            binFolder.create(true, true, null);
+        } else {
+            if (!binFolder.isSynchronized(IResource.DEPTH_ONE)) {
+                binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+            }
+        }
+        IFolder binaryInfFolder = binFolder.getFolder(folder);
+        if (!binaryInfFolder.exists()) {
+            binaryInfFolder.create(true, true, null);
+        } else {
+            if (!binaryInfFolder.isSynchronized(IResource.DEPTH_ONE)) {
+                binaryInfFolder.refreshLocal(IResource.DEPTH_ONE, null);
+            }
+        }
+
+        buildFilesInFolder(monitor, infFolder, binaryInfFolder, Predicate.<IResource> tautology(), false);
+        monitor.done();
+    }
+
+    private void buildRootFolder(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+        IProject project = getProject();
+        IFolder infFolder = project.getFolder(META_INF);
+
+        if (!infFolder.exists()) {
+            error(META_INF + " folder not found for project: " + getProject().getName()); //$NON-NLS-1$
+            return;
+        }
+
+        IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+        if (!binFolder.exists()) {
+            binFolder.create(true, true, null);
+        } else {
+            if (!binFolder.isSynchronized(IResource.DEPTH_ONE)) {
+                binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+            }
+        }
+        IFolder binaryInfFolder = binFolder.getFolder(META_INF);
+        if (!binaryInfFolder.exists()) {
+            binaryInfFolder.create(true, true, null);
+        } else {
+            if (!binaryInfFolder.isSynchronized(IResource.DEPTH_ONE)) {
+                binaryInfFolder.refreshLocal(IResource.DEPTH_ONE, null);
+            }
+        }
+
+        buildFilesInFolder(monitor, infFolder, binaryInfFolder, Predicate.<IResource> tautology(), false);
+        monitor.done();
+    }
+
+    private void buildFilesInFolder(IProgressMonitor monitor, IFolder from, IFolder to, Predicate<IResource> predicate, boolean merge)
+        throws CoreException {
+        IResource[] children = from.members();
+
+        SubMonitor sub = SubMonitor.convert(monitor, children.length);
+
+        sub.beginTask(NLS.bind(Messages.Builder_CopyContent, from.getName()), children.length);
+        for (IResource sourceResource : children) {
+            if (predicate.accept(sourceResource)) {
+                if (!sourceResource.isTeamPrivateMember() && !sourceResource.isDerived()) {
+                    IPath targetPath = to.getFullPath().append(sourceResource.getName());
+                    IResource targetResource = ResourcesPlugin.getWorkspace().getRoot().findMember(targetPath);
+                    if (targetResource != null && targetResource.exists()) {
+                        if (DEBUG) {
+                            debug(targetResource.getFullPath().toString() + " exists"); //$NON-NLS-1$
+                        }
+                        targetResource.refreshLocal(IResource.DEPTH_INFINITE, null);
+
+                        if (targetResource.getType() == IResource.FILE) {
+                            replaceFile(sourceResource, targetResource);
+                        } else {
+                            recurseInFolder(sourceResource, targetResource, predicate, merge);
+                        }
+                    } else {
+                        // resource did not exist in target folder, just copy
+                        sourceResource.copy(targetPath, true, null);
+                        if (DEBUG) {
+                            debug("Copied " + sourceResource.getFullPath().toString() + " to " + targetPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+                        }
+                    }
+                }
+                sub.worked(1);
+            }
+        }
+        monitor.done();
+    }
+
+    private void recurseInFolder(IResource from, IResource to, Predicate<IResource> predicate, boolean merge) throws CoreException {
+        IPath toPath = to.getFullPath();
+        if (!merge) {
+            to.delete(true, null);
+            from.copy(toPath, true, null);
+            if (DEBUG) {
+                debug("Copied " + from.getFullPath().toString() + " to " + toPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+        } else {
+            buildFilesInFolder(new NullProgressMonitor(), (IFolder) from, (IFolder) to, predicate, true);
+            if (DEBUG) {
+                debug("Merged " + from.getFullPath().toString() + " into " + toPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+        }
+    }
+
+    private void replaceFile(IResource from, IResource to) throws CoreException {
+        to.delete(true, null);
+        if (DEBUG) {
+            debug(to.getFullPath().toString() + " deleted"); //$NON-NLS-1$
+        }
+        from.copy(to.getFullPath(), true, null);
+        if (DEBUG) {
+            debug("Copied " + from.getFullPath().toString() + " to " + to.getFullPath().toString()); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    private void debug(String string) {
+        Helper.debug(getProject().getName() + " - " + string); //$NON-NLS-1$
+    }
+
+    private void error(String string) {
+        Helper.error(getProject().getName() + " - " + string); //$NON-NLS-1$
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Constants.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Constants.java
new file mode 100644
index 0000000..e9d7bb7
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Constants.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+/**
+ * Constant values.
+ *
+ */
+public final class Constants {
+
+    /**
+     * Bundle symbolic name.
+     */
+    public static final String PLUGIN_ID = "org.eclipse.virgo.ide.pde.core";//$NON-NLS-1$
+
+    /**
+     * Nature-id.
+     */
+    public static final String NATURE_ID = PLUGIN_ID + ".nature"; //$NON-NLS-1$
+
+    /** Builder-id. */
+    public static final String BUILDER_ID = PLUGIN_ID + ".builder"; //$NON-NLS-1$
+
+    /* debug key */
+    /* package */ static final String DEBUG_KEY = PLUGIN_ID + "/debug"; //$NON-NLS-1$
+
+    // path constants
+    /* package */ static final String META_INF = "META-INF"; //$NON-NLS-1$
+    /* package */ static final String OSGI_INF = "OSGI-INF"; //$NON-NLS-1$
+    /* package */ static final String MANIFEST_MF = "MANIFEST.MF"; //$NON-NLS-1$
+    /* package */ static final String WebContent = "WebContent"; //$NON-NLS-1$
+
+    private Constants() {
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Helper.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Helper.java
new file mode 100644
index 0000000..cefd0c2
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Helper.java
@@ -0,0 +1,312 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.MANIFEST_MF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.META_INF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.PLUGIN_ID;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * A Helper class used by the builder.
+ * <p />
+ */
+public class Helper {
+
+    /* package */ static boolean DEBUG = "true".equals(Platform.getDebugOption(Constants.DEBUG_KEY)); //$NON-NLS-1$
+
+    private static ILog log = Platform.getLog(FrameworkUtil.getBundle(Helper.class));
+
+    /* key for the preferred editor persistent property, see org.eclipse.ide.ui.IDE */
+    private static final QualifiedName EDITOR_PROPERTY = new QualifiedName("org.eclipse.ui.internal.registry.ResourceEditorRegistry", //$NON-NLS-1$
+        "EditorProperty"); //$NON-NLS-1$
+
+    /* ID of the PDE plug-in manifest editor, see org.eclipse.pde.internal.ui.IPDEUIConstants */
+    private static final String EDITOR_VALUE = "org.eclipse.pde.ui.manifestEditor"; //$NON-NLS-1$
+
+    /**
+     * emit debug log
+     */
+    /* package */ static void debug(String message) {
+        log.log(new Status(IStatus.OK, PLUGIN_ID, message));
+    }
+
+    /**
+     * emit error log
+     */
+    /* package */ static void error(String message) {
+        log.log(new Status(IStatus.ERROR, PLUGIN_ID, message));
+    }
+
+    /**
+     * Tells whether a META-INF folder exists in the output location that contains a MANIFEST.MF file
+     *
+     * @param outputLocation
+     * @return
+     * @throws CoreException
+     */
+    static boolean checkMETAINFFolder(IProject project) throws CoreException {
+        IPath outputLocation = getOutputLocation(project);
+        IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+        if (!binFolder.exists()) {
+            if (DEBUG) {
+                debug("Creating bin folder"); //$NON-NLS-1$
+            }
+            binFolder.create(true, true, null);
+            return false;
+        } else {
+            if (DEBUG) {
+                debug("Refreshing bin folder"); //$NON-NLS-1$
+            }
+            binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+        }
+        IFolder binaryMetaInf = binFolder.getFolder(META_INF);
+        if (!binaryMetaInf.exists()) {
+            if (DEBUG) {
+                debug("Creating bin/META-INF"); //$NON-NLS-1$
+            }
+            binaryMetaInf.create(true, true, null);
+            return false;
+        } else {
+            if (DEBUG) {
+                debug("bin/META-INF already exists, refreshing"); //$NON-NLS-1$
+            }
+            binaryMetaInf.refreshLocal(IResource.DEPTH_INFINITE, null);
+        }
+        IFile binaryManifest = binaryMetaInf.getFile(MANIFEST_MF);
+        if (!binaryManifest.exists()) {
+            if (DEBUG) {
+                debug("bin/META-INF/MANIFEST.MF does not exist"); //$NON-NLS-1$
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /* package */ static java.util.List<String> getLibraryEntries(IProject project) throws CoreException {
+        java.util.List<String> toCopy = getEntries(project);
+        if (DEBUG) {
+            debug("JARS declared in manifest: " + Arrays.toString(toCopy.toArray())); //$NON-NLS-1$
+        }
+        return toCopy;
+    }
+
+    private static java.util.List<String> getEntries(IProject project) throws CoreException {
+        IFolder metaInf = project.getFolder(META_INF);
+        if (!metaInf.exists()) {
+            return Collections.emptyList();
+        }
+
+        IFile manifest = metaInf.getFile(MANIFEST_MF);
+        if (!manifest.exists()) {
+            return Collections.emptyList();
+        }
+
+        HashMap<String, String> manifestEntries = new HashMap<String, String>();
+        try {
+            ManifestElement.parseBundleManifest(manifest.getContents(), manifestEntries);
+        } catch (Exception e) {
+            throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, Messages.Helper_ManifestParsingError, e));
+        }
+
+        java.util.List<String> toCopy = new ArrayList<String>();
+
+        String rawValue = manifestEntries.get("Bundle-ClassPath"); //$NON-NLS-1$
+        if (rawValue != null) {
+            String[] classpathEntries = ManifestElement.getArrayFromList(rawValue);
+            for (String classpathEntry : classpathEntries) {
+                if (".".equals(classpathEntry)) { //$NON-NLS-1$
+                    continue;
+                } else if (!classpathEntry.toLowerCase().endsWith(".jar")) {
+                    continue;
+                } else {
+                    toCopy.add(classpathEntry);
+                }
+            }
+        }
+
+        rawValue = manifestEntries.get("Bundle-NativeCode"); //$NON-NLS-1$
+        if (rawValue != null) {
+            ManifestElement[] value;
+            try {
+                value = ManifestElement.parseHeader("Bundle-NativeCode", rawValue); //$NON-NLS-1$
+            } catch (BundleException e) {
+                throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, Messages.Helper_ManifestParsingError, e));
+            }
+            for (ManifestElement manifestElement : value) {
+                toCopy.add(manifestElement.getValue());
+            }
+        }
+
+        return toCopy;
+    }
+
+    /**
+     * Gets the output location of the project. Either returns the global output location or the first output location
+     * found for a source folder.
+     *
+     * @return
+     * @throws CoreException
+     */
+    /* package */ static IPath getOutputLocation(IProject project) throws CoreException {
+        IJavaProject jp = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
+        IPath outputLocation = jp.getOutputLocation();
+
+        if (outputLocation == null) {
+            IClasspathEntry[] entries = jp.getRawClasspath();
+
+            for (IClasspathEntry iClasspathEntry : entries) {
+                if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+                    outputLocation = iClasspathEntry.getOutputLocation();
+                    if (outputLocation != null) {
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (outputLocation == null) {
+            throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, Messages.Helper_BinFolderError));
+        }
+        return outputLocation;
+    }
+
+    /**
+     * Copies a library pointed by the given MANIFEST.MF classpath under the outputlocation
+     *
+     * @param project
+     * @param path
+     * @param outputLocation
+     * @throws CoreException
+     */
+    /* package */ static void copyLibraryToBin(IProject project, String path) throws CoreException {
+        IPath outputLocation = getOutputLocation(project);
+        IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+
+        IResource target = binFolder.findMember(path);
+
+        if (target != null && target.exists()) {
+            if (DEBUG) {
+                debug(path + " already exists, deleting"); //$NON-NLS-1$
+            }
+            target.delete(true, null);
+            if (DEBUG) {
+                debug(path + " deleted"); //$NON-NLS-1$
+            }
+        }
+        IResource libraryResource = project.findMember(new Path(path));
+        if (libraryResource != null) {
+            IPath destinationPath = binFolder.getFullPath().append(path);
+            IPath binRelativePath = destinationPath.removeFirstSegments(outputLocation.segmentCount());
+            binRelativePath = binRelativePath.removeLastSegments(1);
+            int segmentCount = binRelativePath.segmentCount();
+            if (segmentCount > 0) {
+                for (int i = 0; i < segmentCount; i++) {
+                    IFolder aFolder = binFolder.getFolder(binRelativePath.removeLastSegments(segmentCount - 1 - i));
+                    if (!aFolder.exists()) {
+                        if (DEBUG) {
+                            debug("parent folder does not exist: " + aFolder.getFullPath().toString()); //$NON-NLS-1$
+                        }
+                        aFolder.create(true, true, null);
+                        if (DEBUG) {
+                            debug("parent folder created"); //$NON-NLS-1$
+                        }
+                    }
+                }
+            }
+
+            switch (libraryResource.getType()) {
+                case IResource.FILE:
+                    IFile libraryFile = project.getFile(new Path(path));
+                    libraryFile.copy(destinationPath, true, null);
+                    break;
+                case IResource.FOLDER:
+                    IFolder libraryFolder = project.getFolder(new Path(path));
+                    libraryFolder.copy(destinationPath, true, null);
+                    break;
+            }
+            if (DEBUG) {
+                debug("copied " + libraryResource.getFullPath().toString() + " to " + destinationPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+        } else {
+            if (DEBUG) {
+                debug("Manifest contains unexisting library entry: " + path); //$NON-NLS-1$
+            }
+        }
+
+    }
+
+    /* package */ static boolean checkLibraries(IProject project) throws CoreException {
+
+        List<String> entries = getLibraryEntries(project);
+        if (entries.isEmpty()) {
+            return true;
+        }
+        return checkFilesExist(project, entries);
+    }
+
+    private static boolean checkFilesExist(IProject project, List<String> entries) throws CoreException {
+        IPath outputLocation = getOutputLocation(project);
+        for (String string : entries) {
+            if (project.getFile(string).exists()) { // iff the library really exists
+                IPath binFile = outputLocation.append(string);
+                IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(binFile);
+                if (res == null) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public static void forcePDEEditor(IProject project) {
+        IFolder metaInf = project.getFolder(META_INF);
+        if (metaInf.exists()) {
+            IFile manifest = metaInf.getFile(MANIFEST_MF);
+            if (manifest.exists()) {
+                // quick hack to force Eclipse to use the PDE editor
+                try {
+                    manifest.setPersistentProperty(EDITOR_PROPERTY, EDITOR_VALUE);
+                } catch (CoreException e) {
+                    if (DEBUG) {
+                        log.log(e.getStatus());
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.java
new file mode 100644
index 0000000..60a9283
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localization support.
+ */
+public class Messages extends NLS {
+
+    public static String Builder_copy_nativecode;
+
+    public static String Builder_IncrementalBuildMessage;
+
+    public static String Builder_FullBuildMessage;
+
+    public static String Builder_copy_libraries;
+
+    public static String Builder_CopyContent;
+
+    public static String Helper_BinFolderError;
+
+    public static String Helper_ManifestParsingError;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(Messages.class.getName(), Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.properties b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.properties
new file mode 100644
index 0000000..6289cac
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.properties
@@ -0,0 +1,8 @@
+Builder_IncrementalBuildMessage=Incremental build
+Builder_FullBuildMessage=Publishing plug-in resources to binary location
+Builder_copy_libraries=Copying libraries to output folder
+Builder_copy_nativecode=Copying native code to output folder
+Builder_CopyContent=Copying {0} to output folder
+Helper_BinFolderError=Cannot find a binary folder
+Helper_ManifestParsingError=Error parsing manifest
+
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Nature.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Nature.java
new file mode 100644
index 0000000..5fd56bb
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Nature.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A marker nature that is used to contribute a custom build command, see {@link Builder}
+ *
+ *
+ */
+public class Nature implements IProjectNature {
+
+    private IProject project;
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.core.resources.IProjectNature#configure()
+     */
+    public void configure() throws CoreException {
+        IProjectDescription desc = this.project.getDescription();
+        ICommand[] commands = desc.getBuildSpec();
+
+        for (ICommand command : commands) {
+            if (command.getBuilderName().equals(Constants.BUILDER_ID)) {
+                return;
+            }
+        }
+
+        ICommand[] newCommands = new ICommand[commands.length + 1];
+        System.arraycopy(commands, 0, newCommands, 0, commands.length);
+        ICommand command = desc.newCommand();
+        command.setBuilderName(Constants.BUILDER_ID);
+        newCommands[newCommands.length - 1] = command;
+        desc.setBuildSpec(newCommands);
+        this.project.setDescription(desc, null);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.core.resources.IProjectNature#deconfigure()
+     */
+    public void deconfigure() throws CoreException {
+        IProjectDescription description = getProject().getDescription();
+        ICommand[] commands = description.getBuildSpec();
+        for (int i = 0; i < commands.length; ++i) {
+            if (commands[i].getBuilderName().equals(Constants.BUILDER_ID)) {
+                ICommand[] newCommands = new ICommand[commands.length - 1];
+                System.arraycopy(commands, 0, newCommands, 0, i);
+                System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
+                description.setBuildSpec(newCommands);
+                this.project.setDescription(description, null);
+                return;
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.core.resources.IProjectNature#getProject()
+     */
+    public IProject getProject() {
+        return this.project;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
+     */
+    public void setProject(IProject project) {
+        this.project = project;
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/SetupProjectOperation.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/SetupProjectOperation.java
new file mode 100644
index 0000000..49455e3
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/SetupProjectOperation.java
@@ -0,0 +1,242 @@
+
+package org.eclipse.virgo.ide.pde.core.internal.cmd;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.text.MessageFormat;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.pde.core.project.IBundleProjectDescription;
+import org.eclipse.pde.core.project.IBundleProjectService;
+import org.eclipse.virgo.ide.facet.core.FacetCorePlugin;
+import org.eclipse.virgo.ide.pde.core.internal.Constants;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * SetupProjectOperation updates an existing PDE project to make it a Virgo-PDE project. If a context root is passed, it
+ * is made a Web Bundle PDE project.
+ * <p>
+ * Note that this runnable is meant to adapt for Virgo a newly created PDE project. It is not intended for migrating a
+ * PDE project that has been modified after initial creation.
+ * <p>
+ */
+public class SetupProjectOperation implements IWorkspaceRunnable {
+
+    private static final String WST_FACET_NATURE = org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin.PLUGIN_ID + ".nature"; //$NON-NLS-1$
+
+    private static final String WEB_CONTENT_FOLDER = "WebContent"; //$NON-NLS-1$
+
+    private static final String BIN_WEB_INF_CLASSES = "bin/WEB-INF/classes"; //$NON-NLS-1$
+
+    private static final String SRC = "src"; //$NON-NLS-1$
+
+    private static final String BIN = "bin"; //$NON-NLS-1$
+
+    private static final String WEB_XML = "web.xml"; //$NON-NLS-1$
+
+    private static final String INDEX_HTML = "index.html"; //$NON-NLS-1$
+
+    private static final String BUILD_PROPERTIES = "build.properties"; //$NON-NLS-1$
+
+    private static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
+
+    private static final String ISO_8859_1 = "ISO-8859-1"; //$NON-NLS-1$
+
+    private static final String CLASS_PATH_VALUE = ".,WEB-INF/classes"; //$NON-NLS-1$
+
+    private static final String SLASH = "/"; //$NON-NLS-1$
+
+    private static final String HEADER_BUNDLE_CLASS_PATH = "Bundle-ClassPath"; //$NON-NLS-1$
+
+    private static final String HEADER_WEB_CONTEXT_PATH = "Web-ContextPath"; //$NON-NLS-1$
+
+    private final IProject project;
+
+    private final String contextRoot;
+
+    private final IBundleProjectService service;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param project a mandatory project resource
+     * @param contextRoot a context root name or <code>null</code> if the project is not a Web project
+     * @param service a {@link IBundleProjectService} instance
+     */
+    public SetupProjectOperation(IProject project, String contextRoot, IBundleProjectService service) {
+        Assert.isNotNull(project, "project cannot be null"); //$NON-NLS-1$
+        Assert.isNotNull(service, "service cannot be null"); //$NON-NLS-1$
+        this.project = project;
+        this.contextRoot = sanitizeContextRoot(contextRoot);
+        this.service = service;
+    }
+
+    private String sanitizeContextRoot(String contextRoot2) {
+        if (contextRoot2 != null) {
+            if (contextRoot2.startsWith(SLASH)) {
+                contextRoot2 = contextRoot2.substring(1);
+            }
+        }
+        return contextRoot2;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void run(IProgressMonitor monitor) throws CoreException {
+        monitor.beginTask("", 4); //$NON-NLS-1$
+
+        org.eclipse.virgo.ide.pde.core.internal.Helper.forcePDEEditor(project);
+        monitor.worked(1);
+
+        addNatures(project);
+        monitor.worked(1);
+
+        if (contextRoot != null && contextRoot.length() > 0) {
+            IPath webContentPath = configureWABClasspath(project);
+
+            createWebXML(contextRoot, webContentPath);
+            createIndexHTML(contextRoot, webContentPath);
+            createBuildProperties();
+
+            IBundleProjectDescription bundleDescription = service.getDescription(project);
+
+            bundleDescription.setHeader(HEADER_WEB_CONTEXT_PATH, SLASH + contextRoot);
+            bundleDescription.setHeader(HEADER_BUNDLE_CLASS_PATH, CLASS_PATH_VALUE);
+            bundleDescription.apply(null);
+        }
+        monitor.worked(1);
+
+        IFacetedProject fProject = ProjectFacetsManager.create(project.getProject(), true, null);
+        fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.BUNDLE_FACET_ID).getDefaultVersion(), null, null);
+        monitor.worked(1);
+        monitor.done();
+    }
+
+    private void createBuildProperties() throws CoreException {
+        String template = readResourceFromClassPath(BUILD_PROPERTIES, ISO_8859_1);
+        IFile file = project.getFile(BUILD_PROPERTIES);
+        try {
+            if (!file.exists()) {
+                file.create(new ByteArrayInputStream(template.getBytes(ISO_8859_1)), true, null);
+            } else {
+                file.setContents(new ByteArrayInputStream(template.getBytes(ISO_8859_1)), true, false, null);
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, e.getMessage(), e));
+        }
+    }
+
+    private void createIndexHTML(String contextRoot, IPath webContentPath) throws CoreException {
+        createFileFromTemplate(contextRoot, webContentPath, INDEX_HTML, UTF_8);
+    }
+
+    private void createWebXML(String contextRoot, IPath webContentPath) throws CoreException {
+        createFileFromTemplate(contextRoot, webContentPath, WEB_XML, UTF_8);
+    }
+
+    private void createFileFromTemplate(String contextRoot, IPath webContentPath, String fileNane, String charset) throws CoreException {
+        IFolder webContentFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(webContentPath);
+        if (!webContentFolder.exists()) {
+            webContentFolder.create(true, false, null);
+        }
+
+        IFile file = webContentFolder.getFile(fileNane);
+        if (!file.exists()) {
+            String template = readResourceFromClassPath(fileNane, charset);
+            String newWab = MessageFormat.format(template, contextRoot);
+            try {
+                file.create(new ByteArrayInputStream(newWab.getBytes(charset)), true, null);
+            } catch (UnsupportedEncodingException e) {
+                throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, e.getMessage(), e));
+            }
+        }
+    }
+
+    private String readResourceFromClassPath(String path, String charset) throws CoreException {
+        InputStream is = getClass().getResourceAsStream(path);
+        if (is != null) {
+            try {
+                InputStreamReader r = new InputStreamReader(is, charset);
+                StringBuilder sb = new StringBuilder();
+                int c;
+                while ((c = r.read()) != -1) {
+                    sb.append((char) c);
+                }
+                return sb.toString();
+            } catch (IOException e) {
+                throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, e.getMessage(), e));
+            } finally {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+        } else {
+            throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, "Template file missing " + path)); //$NON-NLS-1$
+        }
+
+    }
+
+    private IPath configureWABClasspath(IProject project) throws CoreException, JavaModelException {
+        IJavaProject javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
+        javaProject.setOutputLocation(project.getFullPath().append(BIN), null);
+        IClasspathEntry[] entries = javaProject.getRawClasspath();
+        IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
+        for (int i = 0; i < entries.length; i++) {
+            IClasspathEntry iClasspathEntry = entries[i];
+            if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE && iClasspathEntry.getPath().lastSegment().equals(SRC)) {
+                IClasspathEntry newEntry = JavaCore.newSourceEntry(iClasspathEntry.getPath(), iClasspathEntry.getInclusionPatterns(),
+                    iClasspathEntry.getExclusionPatterns(), project.getFullPath().append(BIN_WEB_INF_CLASSES));
+                newEntries[i] = newEntry;
+                break;
+            } else {
+                newEntries[i] = entries[i];
+            }
+        }
+
+        IPath webContentPath = project.getFullPath().append(WEB_CONTENT_FOLDER);
+        newEntries[entries.length] = JavaCore.newLibraryEntry(webContentPath, null, null);
+
+        javaProject.setRawClasspath(newEntries, null);
+        return webContentPath;
+    }
+
+    private IProjectDescription addNatures(IProject project) throws CoreException {
+        IProjectDescription description = project.getDescription();
+        String[] natures = description.getNatureIds();
+
+        // Add the natures
+        String[] newNatures = new String[natures.length + 3];
+        System.arraycopy(natures, 0, newNatures, 0, natures.length);
+
+        // <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+        newNatures[natures.length + 0] = WST_FACET_NATURE;
+        // <nature>org.eclipse.virgo.ide.facet.core.bundlenature</nature> <nature>
+        newNatures[natures.length + 1] = org.eclipse.virgo.ide.facet.core.FacetCorePlugin.BUNDLE_NATURE_ID;
+        newNatures[natures.length + 2] = org.eclipse.virgo.ide.pde.core.internal.Constants.NATURE_ID;
+
+        description.setNatureIds(newNatures);
+        project.setDescription(description, null);
+        return description;
+    }
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/build.properties b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/build.properties
new file mode 100644
index 0000000..e11abf1
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/build.properties
@@ -0,0 +1,6 @@
+source.WEB-INF/classes = src/		   
+output.WEB-INF/classes = bin/
+source..=WebContent
+output..=bin/
+bin.includes = META-INF/,\
+               .               
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/index.html b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/index.html
new file mode 100644
index 0000000..300233f
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/index.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+<head>
+<title>{0} index page</title>
+</head>
+<body>Welcome to Virgo!
+</body>
+</html>
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/web.xml b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/web.xml
new file mode 100644
index 0000000..b57ec1e
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/web.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app id="WebApp_{0}" version="3.0"
+	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+	<display-name>{0}</display-name>
+	<welcome-file-list>
+		<welcome-file>index.html</welcome-file>
+	</welcome-file-list>
+</web-app>
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF b/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF
index f30dab9..3244d6e 100644
--- a/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF
@@ -38,7 +38,10 @@
  org.eclipse.jdt.ui,
  org.eclipse.libra.framework.editor.core,
  org.eclipse.libra.framework.editor.ui,
- org.eclipse.ui.workbench.texteditor
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.virgo.repository,
+ org.eclipse.virgo.medic,
+ org.eclipse.virgo.util.math
 Import-Package: org.apache.commons.lang,
  org.apache.commons.logging
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/org.eclipse.virgo.ide.runtime.ui/icons/full/over08/pde_over.png b/org.eclipse.virgo.ide.runtime.ui/icons/full/over08/pde_over.png
new file mode 100644
index 0000000..8ff612c
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/icons/full/over08/pde_over.png
Binary files differ
diff --git a/org.eclipse.virgo.ide.runtime.ui/plugin.properties b/org.eclipse.virgo.ide.runtime.ui/plugin.properties
index 9073f73..712b3e7 100644
--- a/org.eclipse.virgo.ide.runtime.ui/plugin.properties
+++ b/org.eclipse.virgo.ide.runtime.ui/plugin.properties
@@ -1,3 +1,6 @@
 pluginName=Eclipse Virgo IDE (Server UI)

 providerName=Eclipse.org - Virgo

-

+serverPDEDecorator.label=Server PDE Decorator

+serverPDEDecorator.desc=Decorates Virgo server instances for which a corresponding PDE Target Platform exists.

+projectPDEDecorator.label=Project PDE Decorator

+projectPDEDecorator.desc=Decorates Virgo PDE projects.
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.runtime.ui/plugin.xml b/org.eclipse.virgo.ide.runtime.ui/plugin.xml
index 8a289cf..d8bbd60 100644
--- a/org.eclipse.virgo.ide.runtime.ui/plugin.xml
+++ b/org.eclipse.virgo.ide.runtime.ui/plugin.xml
@@ -71,12 +71,11 @@
 		<fragment 
 			id="org.eclipse.virgo.server.runtime.virgo" 
 			typeIds="org.eclipse.virgo.server.runtime.virgo"
-			class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment" />
-		  <fragment
-		        class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment"
-		        id="org.eclipse.virgo.server.runtime.virgo.35"
-		        typeIds="org.eclipse.virgo.server.runtime.virgo.35">
-		  </fragment>
+			class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment" />					
+   	    <fragment
+		    class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment"
+		    id="org.eclipse.virgo.server.runtime.virgo.35"
+		    typeIds="org.eclipse.virgo.server.runtime.virgo.35" />
 	</extension>
 
 	<extension point="org.eclipse.wst.common.project.facet.ui.images">
@@ -117,10 +116,17 @@
          class="org.eclipse.virgo.ide.runtime.internal.ui.editor.ArtefactOrderEditorSection">
       </section>
       <section
-         id="org.eclipse.virgo.ide.server.ui.configuration.editor.staticresources"
+         id="org.eclipse.virgo.ide.server.ui.configuration.editor.targetplatform"
          order="15"
          insertionId="org.eclipse.wst.server.editor.overview.left"
          typeIds="org.eclipse.virgo.server.virgo,org.eclipse.virgo.server.virgo.35"
+         class="org.eclipse.virgo.ide.runtime.internal.ui.editor.TargetPlatformSection">
+      </section>
+      <section
+         id="org.eclipse.virgo.ide.server.ui.configuration.editor.staticresources"
+         order="20"
+         insertionId="org.eclipse.wst.server.editor.overview.left"
+         typeIds="org.eclipse.virgo.server.virgo,org.eclipse.virgo.server.virgo.35"
          class="org.eclipse.virgo.ide.runtime.internal.ui.editor.StaticResourcesEditorSection">
       </section>
    </extension>
@@ -621,5 +627,40 @@
          </and>
       </enablement>
    </decorator>
+   <decorator
+         adaptable="true"
+         icon="icons/full/over08/virgo_obj.png"
+         id="org.eclipse.virgo.ide.runtime.ui.pde.project.decorator"
+         label="%projectPDEDecorator.label"
+         lightweight="true"
+         location="TOP_LEFT"
+         state="true">
+      <enablement>
+         <and>
+            <objectClass
+                  name="org.eclipse.core.resources.IProject">
+            </objectClass>
+            <objectState
+                  name="projectNature"
+                  value="org.eclipse.virgo.ide.pde.core.nature">
+            </objectState>
+         </and>
+      </enablement>
+      <description>
+         %projectPDEDecorator.desc
+      </description>
+   </decorator>
+   <decorator
+         adaptable="true"
+         class="org.eclipse.virgo.ide.runtime.internal.ui.providers.ServerTargetPlatformDecorator"
+         id="org.eclipse.virgo.ide.runtime.ui.server.targetplatform.decorator"
+         label="%serverPDEDecorator.label"
+         lightweight="true"
+         location="TOP_LEFT"
+         state="true">
+      <description>
+         %serverPDEDecorator.desc
+      </description>
+   </decorator>
 </extension>
 </plugin>
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/Messages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/Messages.java
new file mode 100644
index 0000000..37a14f4
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/Messages.java
@@ -0,0 +1,37 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+    private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.runtime.internal.ui.messages"; //$NON-NLS-1$
+
+    public static String PDETargetPlatformComposite_add;
+
+    public static String PDETargetPlatformComposite_add_dialog_message;
+
+    public static String PDETargetPlatformComposite_add_dialog_title;
+
+    public static String PDETargetPlatformComposite_edit;
+
+    public static String PDETargetPlatformComposite_edit_dialog_message;
+
+    public static String PDETargetPlatformComposite_edit_dialog_title;
+
+    public static String PDETargetPlatformComposite_enable_checkbox;
+
+    public static String PDETargetPlatformComposite_error_message;
+
+    public static String PDETargetPlatformComposite_note;
+
+    public static String PDETargetPlatformComposite_remove;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEHelper.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEHelper.java
new file mode 100644
index 0000000..19555f5
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEHelper.java
@@ -0,0 +1,439 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.pde.core.target.ITargetDefinition;
+import org.eclipse.pde.core.target.ITargetHandle;
+import org.eclipse.pde.core.target.ITargetLocation;
+import org.eclipse.pde.core.target.ITargetPlatformService;
+import org.eclipse.pde.core.target.LoadTargetDefinitionJob;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.virgo.ide.runtime.core.IServerRuntimeWorkingCopy;
+import org.eclipse.virgo.kernel.osgi.provisioning.tools.NoOpEventLogger;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.repository.ArtifactBridge;
+import org.eclipse.virgo.repository.ArtifactDescriptor;
+import org.eclipse.virgo.repository.ArtifactGenerationException;
+import org.eclipse.virgo.repository.builder.ArtifactDescriptorBuilder;
+import org.eclipse.virgo.repository.configuration.ExternalStorageRepositoryConfiguration;
+import org.eclipse.virgo.repository.configuration.ManagedStorageRepositoryConfiguration;
+import org.eclipse.virgo.repository.configuration.PropertiesRepositoryConfigurationReader;
+import org.eclipse.virgo.repository.configuration.RepositoryConfiguration;
+import org.eclipse.virgo.repository.configuration.WatchedStorageRepositoryConfiguration;
+import org.eclipse.virgo.util.math.OrderedPair;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+
+/**
+ * Utilities used for integrating Virgo Tools and PDE Tools.
+ *
+ */
+public final class PDEHelper {
+
+    private static final String DOT = "."; //$NON-NLS-1$
+
+    private static final String PLUGINS = "plugins"; //$NON-NLS-1$
+
+    private static final String CONFIG_FILENAME = "org.eclipse.virgo.repository.properties"; //$NON-NLS-1$
+
+    private static final String CONFIGURATION = "configuration"; //$NON-NLS-1$
+
+    private static final String ANY_JAR = "*.jar"; //$NON-NLS-1$
+
+    private static final String STAR = "*"; //$NON-NLS-1$
+
+    private static final String WATCH_DIRECTORY = ".watchDirectory"; //$NON-NLS-1$
+
+    private static final String TYPE_WATCHED = "watched"; //$NON-NLS-1$
+
+    private static final String REPO_TYPE = ".type"; //$NON-NLS-1$
+
+    private static final String ADDED_BY_VIRGO_TOOLS = "addedByVirgoTools"; //$NON-NLS-1$
+
+    private static final String COMMA = ","; //$NON-NLS-1$
+
+    private static final String CHAIN_PROPERTY = "chain"; //$NON-NLS-1$
+
+    private PDEHelper() {
+    }
+
+    /**
+     * Parses the 'org.eclipse.virgo.repository.properties' configuration file and returns the list of folders that must
+     * be used as the PDE target platform definition. Note that the returned list also includes the $VIRGO_HOME/plugins
+     * folder that, while not listed in the repository configuration file, contains bundles that the container makes
+     * available to deployed applications.
+     *
+     * @param runtime the runtime working copy
+     * @return the list of folders for the target definition
+     */
+    public static List<File> getFoldersForTargetDefinition(IRuntimeWorkingCopy runtime) {
+        Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+        List<File> locations = new ArrayList<File>();
+        if (runtime.getLocation() != null) {
+            locations.add(runtime.getLocation().append(PLUGINS).toFile());
+            locations.addAll(getRepositoryChain(runtime).values());
+        }
+        return locations;
+    }
+
+    /**
+     * Returns the list of folders contained in the repository configuration file and their name in the repository
+     * chain.
+     *
+     * @param runtime the runtime working copy
+     * @return the map from repository name to folder directory
+     */
+    private static LinkedHashMap<String, File> getRepositoryChain(IRuntimeWorkingCopy runtime) {
+        Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+        LinkedHashMap<String, File> locations = new LinkedHashMap<String, File>();
+        File rootDirectory = runtime.getLocation().toFile();
+        Set<ArtifactBridge> artifactBridges = createArtifactBridges();
+        EventLogger logger = new NoOpEventLogger();
+        File indexDirectory = ServerUiPlugin.getDefault().getStateLocation().append(runtime.getName()).toFile();
+        indexDirectory.mkdirs();
+        PropertiesRepositoryConfigurationReader reader = new PropertiesRepositoryConfigurationReader(indexDirectory, artifactBridges, logger, null,
+            rootDirectory);
+        File configurationFile = getRepositoryFile(runtime);
+        FileInputStream inStream = null;
+        try {
+            inStream = new FileInputStream(configurationFile);
+            Properties p = new Properties();
+            p.load(inStream);
+            OrderedPair<Map<String, RepositoryConfiguration>, List<String>> pair = reader.readConfiguration(p);
+            for (RepositoryConfiguration cfg : pair.getFirst().values()) {
+                if (cfg instanceof WatchedStorageRepositoryConfiguration) {
+                    WatchedStorageRepositoryConfiguration c1 = (WatchedStorageRepositoryConfiguration) cfg;
+                    locations.put(c1.getName(), c1.getDirectoryToWatch());
+                } else if (cfg instanceof ManagedStorageRepositoryConfiguration) {
+                    ManagedStorageRepositoryConfiguration m1 = (ManagedStorageRepositoryConfiguration) cfg;
+                    locations.put(m1.getName(), m1.getStorageLocation());
+                } else if (cfg instanceof ExternalStorageRepositoryConfiguration) {
+                    ExternalStorageRepositoryConfiguration e1 = (ExternalStorageRepositoryConfiguration) cfg;
+                    String patt = e1.getSearchPattern();
+                    IPath path = new Path(patt);
+                    String lastSegment = path.lastSegment();
+                    if (STAR.equals(lastSegment) || ANY_JAR.equals(lastSegment)) {
+                        path = path.removeLastSegments(1);
+                        if (!path.toOSString().contains(STAR)) {
+                            locations.put(e1.getName(), path.toFile());
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+        } finally {
+            if (inStream != null) {
+                try {
+                    inStream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+
+        return locations;
+    }
+
+    private static File getRepositoryFile(IRuntimeWorkingCopy runtime) {
+        return runtime.getLocation().append(CONFIGURATION).append(CONFIG_FILENAME).toFile();
+    }
+
+    private static Set<ArtifactBridge> createArtifactBridges() {
+        Set<ArtifactBridge> artefactBridges = new HashSet<ArtifactBridge>();
+        artefactBridges.add(new ArtifactBridge() {
+
+            public ArtifactDescriptor generateArtifactDescriptor(File arg0) throws ArtifactGenerationException {
+                return new ArtifactDescriptorBuilder().setUri(arg0.toURI()).setName(arg0.getName()).build();
+            }
+
+        });
+        return artefactBridges;
+    }
+
+    /**
+     * Tells whether a PDE Target Definition with the given name exists or not.
+     *
+     * @param name the target definition name (cannot be null)
+     * @return true if a target definition is found, false otherwise
+     */
+    public static boolean existsTargetDefinition(String name) {
+        Assert.isNotNull(name, "name cannot be null"); //$NON-NLS-1$
+        ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+        ITargetHandle[] targetplatforms = srv.getTargets(null);
+        for (ITargetHandle iTargetHandle : targetplatforms) {
+            try {
+                if (iTargetHandle.getTargetDefinition().getName().equals(name)) {
+                    return true;
+                }
+            } catch (CoreException e) {
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Deletes the target definition(s) with the given name.
+     *
+     * @param name the name (cannot be null)
+     */
+    public static void deleteTargetDefinition(String name) {
+        Assert.isNotNull(name, "name cannot be null"); //$NON-NLS-1$
+        ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+        ITargetHandle[] targetplatforms = srv.getTargets(null);
+        for (ITargetHandle iTargetHandle : targetplatforms) {
+            try {
+                if (iTargetHandle.getTargetDefinition().getName().equals(name)) {
+                    srv.deleteTarget(iTargetHandle);
+                }
+            } catch (CoreException e) {
+            }
+        }
+    }
+
+    /**
+     * Creates a target platform for the given runtime using the given folders.
+     *
+     * @param monitor a monitor for progress reporting
+     * @param runtime the runtime working copy
+     * @param folders the target platform folders
+     * @return a status indicating the operation result
+     */
+    public static Status createTargetDefinition(IProgressMonitor monitor, IRuntimeWorkingCopy runtime, List<File> folders) {
+        Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask("", 2); //$NON-NLS-1$
+        MultiStatus st = new MultiStatus(ServerUiPlugin.PLUGIN_ID, 1, "Error creating target platform", null); //$NON-NLS-1$
+        if (folders != null) {
+            IServerRuntimeWorkingCopy serverRuntimeWorkingCopy = (IServerRuntimeWorkingCopy) runtime.loadAdapter(IServerRuntimeWorkingCopy.class,
+                null);
+            ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+            ITargetHandle[] handles = srv.getTargets(null);
+            for (ITargetHandle iTargetHandle : handles) {
+                try {
+                    if (iTargetHandle.getTargetDefinition().getName().equals(runtime.getName())) {
+                        srv.deleteTarget(iTargetHandle);
+                    }
+                } catch (CoreException e) {
+                    // ignore, in the worst case another target platform is created with the same name and set active
+                }
+            }
+            ITargetDefinition targetplatform = srv.newTarget();
+            targetplatform.setName(runtime.getName());
+            targetplatform.setJREContainer(JavaRuntime.newJREContainerPath(serverRuntimeWorkingCopy.getVMInstall()));
+            ITargetLocation[] locations = new ITargetLocation[folders.size()];
+            int i = 0;
+
+            for (File folder : folders) {
+                try {
+                    locations[i++] = srv.newDirectoryLocation(folder.getCanonicalPath());
+                } catch (IOException e) {
+                    st.add(new Status(IStatus.ERROR, ServerUiPlugin.PLUGIN_ID, e.getLocalizedMessage(), e));
+                }
+            }
+            if (st.isOK()) {
+                monitor.worked(1);
+                targetplatform.setTargetLocations(locations);
+                try {
+                    srv.saveTargetDefinition(targetplatform);
+                    LoadTargetDefinitionJob.load(targetplatform);
+                } catch (CoreException e1) {
+                    st.add(new Status(IStatus.ERROR, ServerUiPlugin.PLUGIN_ID, "Cannot save target platform definition", e1));
+                }
+            }
+        }
+        monitor.done();
+        return st;
+    }
+
+    /**
+     * Updates the Virgo repository configuration to match the specified list of folders.
+     *
+     * @param runtime the runtime working copy
+     * @param newFolders the new folders
+     * @throws IOException if the file modification fails for some reason
+     */
+    public static void updateRepositoryConfiguration(IRuntimeWorkingCopy runtime, List<File> newFolders) throws IOException {
+        Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+        if (runtime.getLocation() != null) {
+            LinkedHashMap<String, File> oldFolders = getRepositoryChain(runtime);
+
+            HashSet<File> oldFoldersSet = new HashSet<File>(oldFolders.values());
+            HashSet<File> newFoldersSet = newFolders != null ? new HashSet<File>(newFolders) : new HashSet<File>();
+
+            newFoldersSet.remove(runtime.getLocation().append(PLUGINS).toFile());
+
+            if (oldFoldersSet.equals(newFoldersSet)) {
+                return;
+            }
+
+            LinkedHashMap<String, File> removed = new LinkedHashMap<String, File>(oldFolders);
+            for (Iterator<Entry<String, File>> eIt = removed.entrySet().iterator(); eIt.hasNext();) {
+                Entry<String, File> e = eIt.next();
+                if (newFoldersSet.remove(e.getValue())) {
+                    eIt.remove(); // remove those that still exist
+                }
+            }
+
+            Properties added = new Properties();
+            int count = 0;
+
+            for (File file : newFoldersSet) {
+                added.put(ADDED_BY_VIRGO_TOOLS + count + REPO_TYPE, TYPE_WATCHED);
+                added.put(ADDED_BY_VIRGO_TOOLS + count + WATCH_DIRECTORY, file.getCanonicalPath());
+                count++;
+            }
+
+            File configurationFile = getRepositoryFile(runtime);
+
+            Properties oldProperties = readRepositoryProperties(configurationFile);
+
+            for (Iterator<Entry<Object, Object>> eIt = oldProperties.entrySet().iterator(); eIt.hasNext();) {
+                String entryKey = eIt.next().getKey().toString();
+                for (String removedRepo : removed.keySet()) {
+                    if (entryKey.startsWith(removedRepo + DOT)) {
+                        eIt.remove();
+                        break;
+                    }
+                }
+            }
+
+            oldProperties.putAll(added);
+
+            String chain = (String) oldProperties.get(CHAIN_PROPERTY);
+            StringBuilder sb = new StringBuilder();
+            if (chain != null) {
+                String[] chainArray = chain.split(COMMA);
+                for (String string : chainArray) {
+                    if (!removed.containsKey(string)) {
+                        sb.append(string).append(COMMA);
+                    }
+                }
+            }
+
+            for (int i = 0; i < count; i++) {
+                sb.append(ADDED_BY_VIRGO_TOOLS + i).append(COMMA);
+            }
+
+            if (sb.length() > 0) {
+                sb.setLength(sb.length() - 1);
+            }
+
+            chain = sb.toString();
+
+            oldProperties.put(CHAIN_PROPERTY, chain);
+
+            writeRepositoryProperties(configurationFile, oldProperties);
+        }
+
+    }
+
+    private static void writeRepositoryProperties(File configurationFile, Properties properties) throws IOException {
+        File newFile = new File(configurationFile.getCanonicalPath());
+        File backupFile = new File(configurationFile.getCanonicalPath() + ".backup_" + System.currentTimeMillis()); //$NON-NLS-1$
+        if (backupFile.exists()) {
+            backupFile.delete();
+        }
+        configurationFile.renameTo(backupFile);
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(newFile);
+            properties.store(fos, "Edited by Virgo Tools"); //$NON-NLS-1$
+            fos.flush();
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    private static Properties readRepositoryProperties(File configurationFile) throws IOException {
+        FileInputStream fis = null;
+        Properties properties = new Properties();
+        try {
+            fis = new FileInputStream(configurationFile);
+            properties.load(fis);
+            return properties;
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Refreshes the target definition identified by the given name or does nothing if such a target platform does not
+     * exist.
+     *
+     * @param monitor a monitor for progress reporting
+     * @param name the target definition name;
+     * @return true if a target platform was found and refreshed.
+     * @throws CoreException
+     */
+    public static boolean refreshTargetDefinition(IProgressMonitor monitor, String name) throws CoreException {
+        Assert.isNotNull(name, "name cannot be null"); //$NON-NLS-1$
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+        ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+        ITargetDefinition def = srv.getWorkspaceTargetDefinition();
+        if (!def.getName().equals(name)) {
+            def = null;
+            ITargetHandle[] handles = srv.getTargets(null);
+            for (ITargetHandle iTargetHandle : handles) {
+                ITargetDefinition def2 = iTargetHandle.getTargetDefinition();
+                if (def2.getName().equals(name)) {
+                    def = def2;
+                    break;
+                }
+            }
+        }
+
+        if (def != null) {
+            srv.saveTargetDefinition(def);
+            def.resolve(monitor);
+            LoadTargetDefinitionJob.load(def);
+            return true;
+
+        }
+        return false;
+    }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformComposite.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformComposite.java
new file mode 100644
index 0000000..f49e00c
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformComposite.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.BaseLabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.runtime.internal.core.utils.StatusUtil;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+
+/**
+ * Gather required data for setting up a PDE target platform.
+ */
+public class PDETargetPlatformComposite extends Composite {
+
+    class DirectoryLabelProvider extends BaseLabelProvider implements ITableLabelProvider {
+
+        public Image getColumnImage(Object element, int columnIndex) {
+            return null;
+        }
+
+        public String getColumnText(Object element, int columnIndex) {
+            return element != null ? element.toString() : null;
+        }
+
+    }
+
+    private List<File> folders;
+
+    private final Button enablePDEDevelopmentButton;
+
+    private final TableViewer foldersTableViewer;
+
+    private final Button addButton;
+
+    private final Button removeButton;
+
+    private final Button editButton;
+
+    private final Label comment;
+
+    private final IRunnableContext runnableContext;
+
+    private final IRuntimeWorkingCopy runtimeWorkingCopy;
+
+    private boolean repositoryConfigurationChanged;
+
+    public PDETargetPlatformComposite(Composite parent, IRunnableContext runnableContext, IRuntimeWorkingCopy iRuntimeWorkingCopy) {
+        super(parent, SWT.NONE);
+
+        this.runnableContext = runnableContext;
+        this.runtimeWorkingCopy = iRuntimeWorkingCopy;
+
+        setLayout(GridLayoutFactory.swtDefaults().numColumns(2).create());
+        setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
+
+        enablePDEDevelopmentButton = new Button(this, SWT.CHECK);
+        enablePDEDevelopmentButton.setSelection(false);
+        enablePDEDevelopmentButton.setText(Messages.PDETargetPlatformComposite_enable_checkbox);
+        enablePDEDevelopmentButton.setLayoutData(GridDataFactory.swtDefaults().span(2, SWT.DEFAULT).create());
+
+        foldersTableViewer = new TableViewer(this);
+        foldersTableViewer.setContentProvider(ArrayContentProvider.getInstance());
+        foldersTableViewer.setSorter(new ViewerSorter());
+        foldersTableViewer.setLabelProvider(new DirectoryLabelProvider());
+        foldersTableViewer.getTable().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).span(1, 3).create());
+        foldersTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+            public void selectionChanged(SelectionChangedEvent event) {
+                int size = foldersTableViewer.getStructuredSelection().size();
+                editButton.setEnabled(size == 1);
+                removeButton.setEnabled(size > 0);
+            }
+        });
+
+        addButton = new Button(this, SWT.PUSH);
+        addButton.setLayoutData(GridDataFactory.fillDefaults().create());
+        addButton.setText(Messages.PDETargetPlatformComposite_add);
+        addButton.addSelectionListener(new SelectionAdapter() {
+
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                PDETargetPlatformComposite.this.addPressed(e);
+            }
+        });
+
+        removeButton = new Button(this, SWT.PUSH);
+        removeButton.setText(Messages.PDETargetPlatformComposite_remove);
+        removeButton.setLayoutData(GridDataFactory.fillDefaults().create());
+        removeButton.addSelectionListener(new SelectionAdapter() {
+
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                PDETargetPlatformComposite.this.removePressed(e);
+            }
+        });
+
+        editButton = new Button(this, SWT.PUSH);
+        editButton.setText(Messages.PDETargetPlatformComposite_edit);
+        editButton.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).create());
+        editButton.addSelectionListener(new SelectionAdapter() {
+
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                PDETargetPlatformComposite.this.editPressed(e);
+            }
+        });
+
+        comment = new Label(this, SWT.WRAP);
+        comment.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(2, SWT.DEFAULT).create());
+        comment.setText(Messages.PDETargetPlatformComposite_note);
+
+        if (PDEHelper.existsTargetDefinition(runtimeWorkingCopy.getName())) {
+            enableTargetPlatform(true);
+            enablePDEDevelopmentButton.setSelection(true);
+        } else {
+            enableTargetPlatform(false);
+        }
+
+        enablePDEDevelopmentButton.addSelectionListener(new SelectionAdapter() {
+
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                PDETargetPlatformComposite.this.enableButtonSelected(e);
+            }
+        });
+    }
+
+    protected void editPressed(SelectionEvent e) {
+        DirectoryDialog dlg = new DirectoryDialog(e.display.getActiveShell());
+        dlg.setText(Messages.PDETargetPlatformComposite_edit_dialog_title);
+        dlg.setMessage(Messages.PDETargetPlatformComposite_edit_dialog_message);
+        String path = dlg.open();
+        if (path != null) {
+            LinkedHashSet<File> folders2 = new LinkedHashSet<File>(getTargetPlatformFolders());
+            folders2.remove(this.foldersTableViewer.getStructuredSelection().getFirstElement());
+            folders2.add(new File(path));
+            List<File> folders3 = new ArrayList<File>(folders2);
+            setTableInput(folders3);
+            repositoryConfigurationChanged = true;
+        }
+    }
+
+    protected void removePressed(SelectionEvent e) {
+        LinkedHashSet<File> folders2 = new LinkedHashSet<File>(getTargetPlatformFolders());
+        folders2.removeAll(this.foldersTableViewer.getStructuredSelection().toList());
+        List<File> folders3 = new ArrayList<File>(folders2);
+        setTableInput(folders3);
+        repositoryConfigurationChanged = true;
+    }
+
+    protected void addPressed(SelectionEvent e) {
+        DirectoryDialog dlg = new DirectoryDialog(e.display.getActiveShell());
+        dlg.setText(Messages.PDETargetPlatformComposite_add_dialog_title);
+        dlg.setMessage(Messages.PDETargetPlatformComposite_add_dialog_message);
+        String path = dlg.open();
+        if (path != null) {
+            LinkedHashSet<File> folders2 = new LinkedHashSet<File>(getTargetPlatformFolders());
+            folders2.add(new File(path));
+            List<File> folders3 = new ArrayList<File>(folders2);
+            setTableInput(folders3);
+            repositoryConfigurationChanged = true;
+        }
+    }
+
+    protected void enableButtonSelected(SelectionEvent e) {
+        enableTargetPlatform(enablePDEDevelopmentButton.getSelection());
+    }
+
+    protected void enableTargetPlatform(boolean enabled) {
+        comment.setEnabled(enabled);
+        foldersTableViewer.getTable().setEnabled(enabled);
+        addButton.setEnabled(enabled);
+        removeButton.setEnabled(enabled);
+        editButton.setEnabled(enabled);
+
+        if (enabled) {
+            try {
+                runnableContext.run(true, false, new IRunnableWithProgress() {
+
+                    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+                        folders = PDEHelper.getFoldersForTargetDefinition(runtimeWorkingCopy);
+                        monitor.done();
+                        if (foldersTableViewer.getTable() != null && !foldersTableViewer.getTable().isDisposed()) {
+                            foldersTableViewer.getTable().getDisplay().asyncExec(new Runnable() {
+
+                                public void run() {
+                                    foldersTableViewer.setInput(folders);
+                                }
+                            });
+                        }
+
+                    }
+                });
+            } catch (Exception e) {
+                StatusUtil.error(Messages.PDETargetPlatformComposite_error_message, e, StatusManager.LOG | StatusManager.SHOW);
+            }
+        } else {
+            foldersTableViewer.setInput(Collections.emptyList());
+        }
+    }
+
+    public Button getEnablePDEDevelopmentButton() {
+        return enablePDEDevelopmentButton;
+    }
+
+    public void setTableInput(List<File> targetPlatformFolders) {
+        this.folders = targetPlatformFolders;
+        foldersTableViewer.setInput(targetPlatformFolders);
+    }
+
+    public List<File> getTargetPlatformFolders() {
+        return folders;
+    }
+
+    public boolean isRepositoryConfigurationChanged() {
+        return repositoryConfigurationChanged;
+    }
+
+    public void performFinish(IProgressMonitor monitor) {
+        final List<File> folders = getTargetPlatformFolders();
+        boolean changed = isRepositoryConfigurationChanged();
+
+        Status st = PDEHelper.createTargetDefinition(monitor, runtimeWorkingCopy, folders);
+        if (!st.isOK()) {
+            StatusManager.getManager().handle(st, StatusManager.SHOW | StatusManager.LOG);
+        } else {
+            if (changed) {
+                getDisplay().syncExec(new Runnable() {
+
+                    public void run() {
+                        boolean applyToRepository = MessageDialog.openQuestion(getShell(),
+                            PDEUIMessages.PDETargetPlatformWizardFragment_update_dialog_title,
+                            PDEUIMessages.PDETargetPlatformWizardFragment_update_dialog_message);
+                        if (applyToRepository) {
+                            try {
+                                PDEHelper.updateRepositoryConfiguration(runtimeWorkingCopy, folders);
+                            } catch (IOException e) {
+                                StatusUtil.error(PDEUIMessages.PDETargetPlatformWizardFragment_update_dialog_error, e,
+                                    StatusManager.SHOW | StatusManager.LOG);
+                            }
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformWizardFragment.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformWizardFragment.java
new file mode 100644
index 0000000..550eced
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformWizardFragment.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+import org.eclipse.wst.server.core.TaskModel;
+import org.eclipse.wst.server.ui.wizard.IWizardHandle;
+import org.eclipse.wst.server.ui.wizard.WizardFragment;
+
+/**
+ * A {@link WizardFragment} that adds an extra page for setting up the PDE target platform.
+ */
+public class PDETargetPlatformWizardFragment extends WizardFragment {
+
+    private PDETargetPlatformComposite targetPlatformComposite;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean hasComposite() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Composite createComposite(Composite parent, final IWizardHandle handle) {
+        handle.setTitle(PDEUIMessages.PDETargetPlatformWizardFragment_title);
+        handle.setDescription(PDEUIMessages.PDETargetPlatformWizardFragment_desc);
+
+        IRunnableContext ctx = new IRunnableContext() {
+
+            public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
+                handle.run(fork, cancelable, runnable);
+            }
+        };
+        targetPlatformComposite = new PDETargetPlatformComposite(parent, ctx, (IRuntimeWorkingCopy) getTaskModel().getObject(TaskModel.TASK_RUNTIME));
+        return targetPlatformComposite;
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isComplete() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void enter() {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void performFinish(IProgressMonitor monitor) throws CoreException {
+        targetPlatformComposite.performFinish(monitor);
+    }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEUIMessages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEUIMessages.java
new file mode 100644
index 0000000..0c84502
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEUIMessages.java
@@ -0,0 +1,27 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class PDEUIMessages extends NLS {
+
+    private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.runtime.internal.ui.pdeuimessages"; //$NON-NLS-1$
+
+    public static String PDETargetPlatformWizardFragment_desc;
+
+    public static String PDETargetPlatformWizardFragment_title;
+
+    public static String PDETargetPlatformWizardFragment_update_dialog_error;
+
+    public static String PDETargetPlatformWizardFragment_update_dialog_message;
+
+    public static String PDETargetPlatformWizardFragment_update_dialog_title;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, PDEUIMessages.class);
+    }
+
+    private PDEUIMessages() {
+    }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/RuntimeListener.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/RuntimeListener.java
new file mode 100644
index 0000000..63937dd
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/RuntimeListener.java
@@ -0,0 +1,55 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.progress.WorkbenchJob;
+import org.eclipse.virgo.ide.runtime.internal.core.runtimes.VirgoRuntimeProvider;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IRuntimeLifecycleListener;
+
+public class RuntimeListener implements IRuntimeLifecycleListener {
+
+    private RuntimeListener() {
+        super();
+    }
+
+    private static RuntimeListener self = new RuntimeListener();
+
+    public static RuntimeListener getDefault() {
+        return self;
+    }
+
+    public void runtimeAdded(IRuntime runtime) {
+    }
+
+    public void runtimeChanged(IRuntime runtime) {
+    }
+
+    public void runtimeRemoved(IRuntime runtime) {
+        if (runtime.getRuntimeType().getId().startsWith(VirgoRuntimeProvider.SERVER_VIRGO_BASE)) {
+            final String name = runtime.getName();
+            UIJob job = new WorkbenchJob("RemoveVirgoTargetPlatform") { //$NON-NLS-1$
+
+                @Override
+                public IStatus runInUIThread(IProgressMonitor monitor) {
+                    if (PDEHelper.existsTargetDefinition(name)) {
+                        boolean delete = MessageDialog.openQuestion(getDisplay().getActiveShell(), "Delete target platform?",
+                            "A Virgo Runtime has been deleted. Do you also want to delete the associated PDE Target Platform?");
+                        if (delete) {
+                            PDEHelper.deleteTargetDefinition(name);
+                        }
+                    }
+                    return Status.OK_STATUS;
+                }
+            };
+
+            job.setUser(true);
+            job.schedule();
+        }
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java
index f2bae56..ff9f28d 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java
@@ -71,6 +71,8 @@
 
     public static final String IMG_VIRGO_OVER = NAME_PREFIX + "virgo_over.png";
 
+    public static final String IMG_PDE_OVER = NAME_PREFIX + "pde_over.png";
+
     public static final String IMG_OBJ_BUNDLE = NAME_PREFIX + "bundle_obj.gif";
 
     public static final String IMG_OBJ_BUNDLE_SRC = NAME_PREFIX + "bundle_src_obj.gif";
@@ -99,6 +101,8 @@
 
     public static final ImageDescriptor DESC_OBJ_VIRGO_OVER = createManaged(OVER, IMG_OBJ_VIRGO);
 
+    public static final ImageDescriptor DESC_OBJ_PDE_OVER = createManaged(OVER, IMG_PDE_OVER);
+
     public static final ImageDescriptor DESC_OBJ_PORT = createManaged(OBJECT, IMG_OBJ_PORT);
 
     public static final ImageDescriptor DESC_OBJ_VIRGO = createManaged(OBJECT, IMG_OBJ_VIRGO);
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java
index 49de687..45e42b8 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java
@@ -19,6 +19,7 @@
 import org.eclipse.jface.resource.ImageRegistry;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.eclipse.virgo.ide.runtime.internal.ui.projects.ServerProjectManager;
+import org.eclipse.wst.server.core.ServerCore;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -90,6 +91,8 @@
         }
         plugin.getPreferenceStore().setDefault(PREF_DOWNLOAD_MESSAGE_KEY, false);
 
+        ServerCore.addRuntimeLifecycleListener(RuntimeListener.getDefault());
+
         ServerProjectManager.getInstance().updateProjects();
     }
 
@@ -101,6 +104,7 @@
     @Override
     public void stop(BundleContext context) throws Exception {
         plugin = null;
+        ServerCore.removeRuntimeLifecycleListener(RuntimeListener.getDefault());
         super.stop(context);
     }
 
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java
index 76f5399..ab26602 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java
@@ -11,6 +11,8 @@
 
 package org.eclipse.virgo.ide.runtime.internal.ui;
 
+import java.util.List;
+
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.swt.widgets.Composite;
@@ -46,8 +48,8 @@
 
     @Override
     public Composite createComposite(Composite parent, IWizardHandle wizard) {
-        String wizardTitle = ServerUiPlugin.getResourceString("virgoWizardTitle");
-        String wizardDescription = ServerUiPlugin.getResourceString("virgoWizardDescription");
+        String wizardTitle = ServerUiPlugin.getResourceString("virgoWizardTitle"); //$NON-NLS-1$
+        String wizardDescription = ServerUiPlugin.getResourceString("virgoWizardDescription"); //$NON-NLS-1$
         this.comp = new ServerRuntimeComposite(parent, wizard, wizardTitle, wizardDescription, ServerUiImages.DESC_WIZB_VIRGO_SERVER);
         return this.comp;
     }
@@ -65,7 +67,17 @@
         IRuntimeWorkingCopy runtime = (IRuntimeWorkingCopy) getTaskModel().getObject(TaskModel.TASK_RUNTIME);
         IPath path = runtime.getLocation();
         if (runtime.validate(null).getSeverity() != IStatus.ERROR) {
-            ServerCorePlugin.setPreference("location" + runtime.getRuntimeType().getId(), path.toString());
+            ServerCorePlugin.setPreference("location" + runtime.getRuntimeType().getId(), path.toString()); //$NON-NLS-1$
         }
     }
+
+    private PDETargetPlatformWizardFragment childFragment;
+
+    @Override
+    protected void createChildFragments(List<WizardFragment> list) {
+        if (childFragment == null) {
+            childFragment = new PDETargetPlatformWizardFragment();
+        }
+        list.add(childFragment);
+    }
 }
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformEditWizard.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformEditWizard.java
new file mode 100644
index 0000000..b2e10ae
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformEditWizard.java
@@ -0,0 +1,66 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui.editor;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDETargetPlatformComposite;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDEUIMessages;
+import org.eclipse.virgo.ide.ui.ServerIdeUiPlugin;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+
+public class TargetPlatformEditWizard extends Wizard {
+
+    private final class PDEPage extends WizardPage {
+
+        private PDEPage() {
+            super("main"); //$NON-NLS-1$
+            setTitle("Configure Eclipse PDE Target Platform"); //$NON-NLS-1$
+            setDescription("Define a PDE Target Platform if you intend to develop using PDE Tools"); //$NON-NLS-1$
+        }
+
+        public void createControl(Composite parent) {
+            composite = new PDETargetPlatformComposite(parent, getContainer(), workingCopy);
+            composite.getEnablePDEDevelopmentButton().setEnabled(false);
+            setControl(composite);
+        }
+    }
+
+    private final IRuntimeWorkingCopy workingCopy;
+
+    private PDETargetPlatformComposite composite;
+
+    public TargetPlatformEditWizard(IRuntimeWorkingCopy workingCopy) {
+        super();
+        this.workingCopy = workingCopy;
+        setNeedsProgressMonitor(true);
+    }
+
+    @Override
+    public void addPages() {
+        addPage(new PDEPage());
+    }
+
+    @Override
+    public boolean performFinish() {
+        try {
+            getContainer().run(true, false, new IRunnableWithProgress() {
+
+                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+                    composite.performFinish(monitor);
+                }
+            });
+        } catch (Exception e) {
+            StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, TargetPlatformSectionMessages.TargetPlatformSection_InternalError, e),
+                StatusManager.LOG | StatusManager.SHOW);
+        }
+        return true;
+    }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSection.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSection.java
new file mode 100644
index 0000000..3beb052
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSection.java
@@ -0,0 +1,122 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui.editor;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.runtime.core.IServerWorkingCopy;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDEHelper;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDEUIMessages;
+import org.eclipse.virgo.ide.ui.ServerIdeUiPlugin;
+import org.eclipse.wst.server.ui.editor.ServerEditorSection;
+
+public class TargetPlatformSection extends ServerEditorSection {
+
+    private static String FORM_TEXT = TargetPlatformSectionMessages.TargetPlatformSection_form_text;
+
+    private IServerWorkingCopy serverWorkingCopy;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void createSection(Composite parent) {
+        super.createSection(parent);
+        FormToolkit toolkit = getFormToolkit(parent.getDisplay());
+
+        Section section = toolkit.createSection(parent, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR
+            | Section.DESCRIPTION | ExpandableComposite.FOCUS_TITLE);
+        section.setText(TargetPlatformSectionMessages.TargetPlatformSection_title);
+        section.setDescription(TargetPlatformSectionMessages.TargetPlatformSection_description);
+        section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+        Composite composite = toolkit.createComposite(section);
+        GridLayout layout = new GridLayout();
+        layout.numColumns = 1;
+        composite.setLayout(layout);
+        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+        toolkit.paintBordersFor(composite);
+        section.setClient(composite);
+
+        FormText text = toolkit.createFormText(composite, true);
+        text.setText(FORM_TEXT, true, false);
+        text.addHyperlinkListener(new HyperlinkAdapter() {
+
+            @Override
+            public void linkActivated(HyperlinkEvent e) {
+                if (!PDEHelper.existsTargetDefinition(server.getRuntime().getName())) {
+                    MessageDialog.openInformation(getShell(), TargetPlatformSectionMessages.TargetPlatformSection_not_configured_title,
+                        TargetPlatformSectionMessages.TargetPlatformSection_not_configured_message);
+                    return;
+                }
+                if ("refresh".equals(e.getHref())) { //$NON-NLS-1$
+                    refreshPressed();
+                    return;
+                }
+                if ("edit".equals(e.getHref())) { //$NON-NLS-1$
+                    editPressed();
+                    return;
+                }
+            }
+        });
+
+    }
+
+    protected void editPressed() {
+        TargetPlatformEditWizard wiz = new TargetPlatformEditWizard(server.getRuntime().createWorkingCopy());
+        wiz.setWindowTitle(PDEUIMessages.PDETargetPlatformWizardFragment_title);
+
+        WizardDialog dlg = new WizardDialog(getShell(), wiz);
+        dlg.setTitle(PDEUIMessages.PDETargetPlatformWizardFragment_title);
+        dlg.open();
+    }
+
+    protected void refreshPressed() {
+        ProgressMonitorDialog dlg = new ProgressMonitorDialog(getShell());
+        try {
+            dlg.run(true, false, new IRunnableWithProgress() {
+
+                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+                    try {
+                        PDEHelper.refreshTargetDefinition(monitor, server.getRuntime().getName());
+                    } catch (CoreException e) {
+                        StatusManager.getManager().handle(e.getStatus(), StatusManager.SHOW);
+                    }
+                }
+            });
+        } catch (Exception e) {
+            StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, e.getMessage(), e),
+                StatusManager.SHOW | StatusManager.LOG);
+        }
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void init(IEditorSite site, IEditorInput input) {
+        super.init(site, input);
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSectionMessages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSectionMessages.java
new file mode 100644
index 0000000..de1e560
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSectionMessages.java
@@ -0,0 +1,29 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui.editor;
+
+import org.eclipse.osgi.util.NLS;
+
+public class TargetPlatformSectionMessages extends NLS {
+
+    private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.runtime.internal.ui.editor.tpsectionmessages"; //$NON-NLS-1$
+
+    public static String TargetPlatformSection_description;
+
+    public static String TargetPlatformSection_form_text;
+
+    public static String TargetPlatformSection_InternalError;
+
+    public static String TargetPlatformSection_not_configured_message;
+
+    public static String TargetPlatformSection_not_configured_title;
+
+    public static String TargetPlatformSection_title;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, TargetPlatformSectionMessages.class);
+    }
+
+    private TargetPlatformSectionMessages() {
+    }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties
index 4d9b16e..15fcc3d 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties
@@ -55,7 +55,7 @@
 StartupEditorSection_description=Specify startup options. Changing a setting requires a server restart.
 StartupEditorSection_maxpermsize_label=-XX:MaxPermSize=
 StartupEditorSection_start_with_clean_button=Start server with -clean option
-StartupEditorSection_tail_into_console_button=Tail application trace files into Console view
+StartupEditorSection_tail_into_console_button=Tail deploy events into Console view
 StartupEditorSection_title=Server Startup Configuration
 StaticResourcesEditorSection_14=<form><p><a href="exportbundle">Restore default</a> filename pattern</p></form>
 StaticResourcesEditorSection_add_button=Add
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/tpsectionmessages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/tpsectionmessages.properties
new file mode 100644
index 0000000..db757e6
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/tpsectionmessages.properties
@@ -0,0 +1,6 @@
+TargetPlatformSection_description=Configure a PDE Target Platform definition for developing using PDE.
+TargetPlatformSection_form_text=<form><p><a href="refresh">Reload</a> the current Target Platform definition due to bundle changes or <a href="edit">edit</a> its content.</p></form>
+TargetPlatformSection_InternalError=Internal Error
+TargetPlatformSection_not_configured_message=A PDE Target Platform definition is not configured for this Virgo runtime. Please use the Server Runtime wizard to configure a PDE Target platform definition.
+TargetPlatformSection_not_configured_title=PDE Target Platform not configured
+TargetPlatformSection_title=Target Platform
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties
index 663bdf0..7e44e36 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties
@@ -10,6 +10,16 @@
 version=&Virgo Version:
 installedJRE=&JRE:
 installedJREs=&Installed JREs...
+PDETargetPlatformComposite_add=Add
+PDETargetPlatformComposite_add_dialog_message=Select a directory of bundles to add to the target
+PDETargetPlatformComposite_add_dialog_title=Add directory
+PDETargetPlatformComposite_edit=Edit
+PDETargetPlatformComposite_edit_dialog_message=Select a directory of bundles to add to the target
+PDETargetPlatformComposite_edit_dialog_title=Edit directory
+PDETargetPlatformComposite_enable_checkbox=Enable development using Eclipse PDE Tools
+PDETargetPlatformComposite_error_message=Internal Error
+PDETargetPlatformComposite_note=Note: Virgo external repositories are not supported by PDE Target platform.
+PDETargetPlatformComposite_remove=Remove
 selectInstallDir=Select server installation directory.
 runtimeDefaultJRE=Workbench default JRE
 
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/pdeuimessages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/pdeuimessages.properties
new file mode 100644
index 0000000..f8720dc
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/pdeuimessages.properties
@@ -0,0 +1,5 @@
+PDETargetPlatformWizardFragment_desc=Define a PDE Target Platform if you intend to develop using PDE Tools
+PDETargetPlatformWizardFragment_title=Configure Eclipse PDE Target Platform
+PDETargetPlatformWizardFragment_update_dialog_error=Error updating repository configuration
+PDETargetPlatformWizardFragment_update_dialog_message=A PDE Target Platform has been created to include the requested list of directories. Do you want the Virgo repository configuration to be updated accordingly?
+PDETargetPlatformWizardFragment_update_dialog_title=Update Virgo repository configuration?
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/providers/ServerTargetPlatformDecorator.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/providers/ServerTargetPlatformDecorator.java
new file mode 100644
index 0000000..7d787f8
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/providers/ServerTargetPlatformDecorator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui.providers;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.BaseLabelProvider;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.eclipse.pde.core.target.ITargetHandle;
+import org.eclipse.pde.core.target.ITargetPlatformService;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.virgo.ide.runtime.core.ServerCorePlugin;
+import org.eclipse.virgo.ide.runtime.internal.ui.ServerUiImages;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IServer;
+
+/**
+ * A lightweight decorator that overlays a decoration on the top left of servers whose runtime has an associated PDE
+ * target platform.
+ */
+public class ServerTargetPlatformDecorator extends BaseLabelProvider implements ILightweightLabelDecorator {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void decorate(Object element, IDecoration decoration) {
+        if (element instanceof IServer) {
+            IServer srv = (IServer) element;
+            if (srv.getServerType().getId().equals(ServerCorePlugin.VIRGO_SERVER_ID)) {
+                IRuntime runtime = srv.getRuntime();
+                String name = runtime.getName();
+                ITargetPlatformService service = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+                ITargetHandle handle = null;
+                try {
+                    handle = service.getWorkspaceTargetHandle();
+                } catch (CoreException e) {
+                }
+                if (handle != null) {
+                    try {
+                        String name2 = handle.getTargetDefinition().getName();
+                        if (name.equals(name2)) {
+                            decoration.addOverlay(ServerUiImages.DESC_OBJ_PDE_OVER, IDecoration.TOP_LEFT);
+                        }
+                    } catch (CoreException e) {
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF b/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF
index 5bb1c5a..d9bcb09 100644
--- a/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF
@@ -40,7 +40,8 @@
  org.eclipse.core.filesystem,
  org.eclipse.ltk.core.refactoring,
  org.eclipse.wst.sse.ui.infopop;bundle-version="1.0.300",
- org.eclipse.ui.navigator
+ org.eclipse.virgo.ide.pde.core,
+ org.eclipse.wst.web
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.virgo.ide.internal.ui,
diff --git a/org.eclipse.virgo.ide.ui/icons/full/obj16/pde_project_obj.png b/org.eclipse.virgo.ide.ui/icons/full/obj16/pde_project_obj.png
new file mode 100644
index 0000000..95b6af1
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/icons/full/obj16/pde_project_obj.png
Binary files differ
diff --git a/org.eclipse.virgo.ide.ui/plugin.properties b/org.eclipse.virgo.ide.ui/plugin.properties
index 87ca512..9b18382 100644
--- a/org.eclipse.virgo.ide.ui/plugin.properties
+++ b/org.eclipse.virgo.ide.ui/plugin.properties
@@ -1,3 +1,5 @@
 pluginName=Eclipse Virgo IDE (UI)

 providerName=Eclipse.org - Virgo

 

+pdeProjectWizard.name=PDE Bundle Project

+pdeProjectWizard.desc=Create a new PDE bundle project
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.ui/plugin.xml b/org.eclipse.virgo.ide.ui/plugin.xml
index fa82626..ab6a447 100644
--- a/org.eclipse.virgo.ide.ui/plugin.xml
+++ b/org.eclipse.virgo.ide.ui/plugin.xml
@@ -32,6 +32,7 @@
          </description>
       </wizard>  
       <wizard
+            canFinishEarly="false"
             category="org.eclipse.virgo.ide.ui.category"
             class="org.eclipse.virgo.ide.ui.wizards.NewBundleProjectWizard"
             finalPerspective="org.eclipse.virgo.ide.runtime.ui.perspective"
@@ -44,6 +45,20 @@
             Create a new OSGi bundle project
          </description>
       </wizard>
+   <wizard
+         category="org.eclipse.virgo.ide.ui.category"
+         class="org.eclipse.virgo.ide.ui.wizards.NewPDEProjectWizard"
+         finalPerspective="org.eclipse.virgo.ide.runtime.ui.perspective"
+         hasPages="true"
+         icon="icons/full/obj16/pde_project_obj.png"
+         id="org.eclipse.virgo.ide.ui.pdeprojectwizard"
+         name="%pdeProjectWizard.name"
+         project="true">
+          <description>
+            %pdeProjectWizard.desc
+         </description>
+   </wizard>
+      
    </extension>
    
    <extension
@@ -298,17 +313,20 @@
    <actionSet
          id="org.eclipse.wst.server.ui.new.actionSet">
    </actionSet>
-                            <newWizardShortcut
+       <newWizardShortcut
              id="org.eclipse.virgo.ide.ui.wizards.osgiProject">
        </newWizardShortcut>
        <newWizardShortcut
+             id="org.eclipse.virgo.ide.ui.pdeprojectwizard">
+       </newWizardShortcut>       
+       <newWizardShortcut
              id="org.eclipse.virgo.ide.ui.wizards.parProject">
        </newWizardShortcut>
        <newWizardShortcut
              id="org.eclipse.wst.server.ui.new.server">
        </newWizardShortcut>
-            <newWizardShortcut id="org.eclipse.ui.wizards.new.folder"/>
-            <newWizardShortcut id="org.eclipse.ui.wizards.new.file"/>
+       <newWizardShortcut id="org.eclipse.ui.wizards.new.folder"/>
+       <newWizardShortcut id="org.eclipse.ui.wizards.new.file"/>
 
        
             <viewShortcut id="org.eclipse.ui.navigator.ProjectExplorer"/> 
@@ -406,7 +424,7 @@
    <viewShortcut
          id="org.eclipse.virgo.ide.runtime.ui.virgoLog">
    </viewShortcut>
-       </perspectiveExtension>
+   </perspectiveExtension>
    <perspectiveExtension
          targetID="org.eclipse.jdt.ui.JavaPerspective">
       <perspectiveShortcut
@@ -468,6 +486,26 @@
 </or>      
             </enablement>
    </commonWizard>
+      <commonWizard
+         type="new"
+         wizardId="org.eclipse.virgo.ide.ui.pdeprojectwizard">
+      <enablement>
+      <or>
+      <with 
+            variable="selection"> 
+         <count 
+               value="0"> 
+         </count> 
+      </with>
+      <instanceof
+            value="org.eclipse.core.resources.IProject">
+      </instanceof>
+      <instanceof
+            value="org.eclipse.core.resources.IWorkspaceRoot">
+      </instanceof> 
+</or>      
+            </enablement>
+   </commonWizard>   
 </extension>
 <extension
       point="org.eclipse.ui.views">
@@ -476,4 +514,20 @@
          name="Virgo">
    </category>
 </extension>
+<extension
+      point="org.eclipse.pde.ui.pluginContent">
+   <wizard
+         class="org.eclipse.virgo.ide.ui.wizards.NewPDEProjectContentWizard"
+         id="org.eclipse.virgo.ide.ui.pdetemplate"
+         java="true"
+         name="Virgo"
+         pureOSGi="true"
+         rcp="false"
+         requiresActivator="false"
+         ui-content="false">
+      <description>
+         This wizard creates new PDE projects that can be deployed to a Virgo test environment.
+      </description>
+   </wizard>
+</extension>
 </plugin>
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java
index e5045a9..8541573 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java
@@ -26,8 +26,8 @@
 
     public AbstractPropertiesPage(String name) {
         super(name);
-        setTitle("Bundle Properties");
-        setDescription("Set the additional properties of the bundle. " + "You can modify the properties at any time in the MANIFEST.MF file.");
+        setTitle(Messages.AbstractPropertiesPage_title);
+        setDescription(Messages.AbstractPropertiesPage_description + Messages.AbstractPropertiesPage_description2);
     }
 
     public void createControl(Composite parent) {
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/Messages.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/Messages.java
new file mode 100644
index 0000000..c5babfd
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/Messages.java
@@ -0,0 +1,91 @@
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+    private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.ui.wizards.messages"; //$NON-NLS-1$
+
+    public static String AbstractPropertiesPage_description;
+
+    public static String AbstractPropertiesPage_description2;
+
+    public static String AbstractPropertiesPage_title;
+
+    public static String NewBundleInformationPage_Additional_Properties;
+
+    public static String NewBundleInformationPage_Classpath_Management;
+
+    public static String NewBundleInformationPage_enable_container;
+
+    public static String NewBundleInformationPage_WAB;
+
+    public static String NewBundleProjectSettingsPage_DESCRIPTION;
+
+    public static String NewBundleProjectSettingsPage_TITLE;
+
+    public static String NewBundleProjectWizard_title;
+
+    public static String NewParProjectReferencePage_desc;
+
+    public static String NewParProjectReferencePage_title;
+
+    public static String NewParProjectSettingsPage_DESCRIPTION;
+
+    public static String NewParProjectSettingsPage_TITLE;
+
+    public static String NewParProjectWizard_title;
+
+    public static String NewPDEProjectWABPage_context_root;
+
+    public static String NewPDEProjectWABPage_description;
+
+    public static String NewPDEProjectWABPage_title;
+
+    public static String NewPDEProjectWizard_title;
+
+    public static String ProjectContentPageStrings_bundle_content;
+
+    public static String ProjectContentPageStrings_bundle_content_desc;
+
+    public static String ProjectContentPageStrings_bundle_desc;
+
+    public static String ProjectContentPageStrings_bundle_name;
+
+    public static String ProjectContentPageStrings_bundle_plugin;
+
+    public static String ProjectContentPageStrings_bundle_properties;
+
+    public static String ProjectContentPageStrings_bundle_version;
+
+    public static String ProjectContentPageStrings_par_content;
+
+    public static String ProjectContentPageStrings_par_content_desc;
+
+    public static String ProjectContentPageStrings_par_desc;
+
+    public static String ProjectContentPageStrings_par_name;
+
+    public static String ProjectContentPageStrings_par_plugin;
+
+    public static String ProjectContentPageStrings_par_prorperties;
+
+    public static String ProjectContentPageStrings_par_symb_name;
+
+    public static String ProjectContentPageStrings_par_version;
+
+    public static String ProjectContentPageStrings_symb_name;
+
+    public static String WebModulePropertiesPage_context_path;
+
+    public static String WebModulePropertiesPage_text;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java
index e30a9dd..c55ee70 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java
@@ -79,20 +79,20 @@
         Group propertiesGroup = new Group(container, SWT.NONE);
         propertiesGroup.setLayout(new GridLayout(3, false));
         propertiesGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        propertiesGroup.setText("Additional Properties");
+        propertiesGroup.setText(Messages.NewBundleInformationPage_Additional_Properties);
 
         this.moduleType = new Button(propertiesGroup, SWT.CHECK);
-        this.moduleType.setText("Web Application Bundle");
+        this.moduleType.setText(Messages.NewBundleInformationPage_WAB);
         this.moduleType.setSelection(false);
         this.moduleType.addSelectionListener(this.moduleTypeListener);
 
         Group classpathGroup = new Group(container, SWT.NONE);
         classpathGroup.setLayout(new GridLayout(1, false));
         classpathGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        classpathGroup.setText("Classpath Management");
+        classpathGroup.setText(Messages.NewBundleInformationPage_Classpath_Management);
 
         this.enableClasspathContainer = new Button(classpathGroup, SWT.CHECK);
-        this.enableClasspathContainer.setText("Enable Bundle Classpath Container");
+        this.enableClasspathContainer.setText(Messages.NewBundleInformationPage_enable_container);
         this.enableClasspathContainer.setSelection(true);
     }
 
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java
index 42f04c4..37006b9 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java
@@ -19,9 +19,9 @@
  */
 public class NewBundleProjectSettingsPage extends NewJavaProjectWizardPageOne {
 
-    private static String NEW_PROJECT_SETTINGS_TITLE = "Create a Bundle project";
+    private static String NEW_PROJECT_SETTINGS_TITLE = Messages.NewBundleProjectSettingsPage_TITLE;
 
-    private static String NEW_PROJECT_SETTINGS_DESCRIPTION = "Create a Bundle project in the workspace or in an external location.";
+    private static String NEW_PROJECT_SETTINGS_DESCRIPTION = Messages.NewBundleProjectSettingsPage_DESCRIPTION;
 
     public NewBundleProjectSettingsPage() {
         super();
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java
index 5626389..068b0c2 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java
@@ -84,7 +84,7 @@
 
     private final IDataModel model;
 
-    private final String title = "New Bundle Project";
+    private final String title = Messages.NewBundleProjectWizard_title;
 
     private Map<String, String> properties;
 
@@ -93,7 +93,7 @@
     public NewBundleProjectWizard() {
         super();
         setWindowTitle(this.title);
-        setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-bundle.png"));
+        setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-bundle.png")); //$NON-NLS-1$
         setNeedsProgressMonitor(true);
         this.bundleData = new PluginFieldData();
         this.model = DataModelFactory.createDataModel(new BundleFacetInstallDataModelProvider());
@@ -110,8 +110,8 @@
                 // WST 3.0 only
 
                 if (NewBundleProjectWizard.this.model.getBooleanProperty(BundleFacetInstallDataModelProvider.ENABLE_WEB_BUNDLE)) {
-                    fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet("jst.java").getDefaultVersion(), null, monitor);
-                    fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.WEB_FACET_ID).getVersion("2.5"), null, monitor);
+                    fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet("jst.java").getDefaultVersion(), null, monitor); //$NON-NLS-1$
+                    fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.WEB_FACET_ID).getVersion("2.5"), null, monitor); //$NON-NLS-1$
 
                     // wanna uninstall JavaScript facet, but it doesn't seem to
                     // be there yet
@@ -119,8 +119,8 @@
                     // .getProjectFacet(FacetCorePlugin.WEB_JS_FACET_ID).getDefaultVersion(),
                     // null, monitor);
 
-                    removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.web.container", monitor);
-                    removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.module.container", monitor);
+                    removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.web.container", monitor); //$NON-NLS-1$
+                    removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.module.container", monitor); //$NON-NLS-1$
                 }
 
                 fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.BUNDLE_FACET_ID).getDefaultVersion(), null,
@@ -138,10 +138,10 @@
         try {
             getContainer().run(true, true, oper);
         } catch (InvocationTargetException e) {
-            StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Failure opening project facets.", e));
+            StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Failure opening project facets.", e)); //$NON-NLS-1$
         } catch (InterruptedException e) {
             StatusManager.getManager().handle(
-                new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while opening project facets.", e));
+                new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while opening project facets.", e)); //$NON-NLS-1$
         }
     }
 
@@ -260,14 +260,14 @@
                 }
             });
 
-            IFile manifestFile = (IFile) project.getProject().findMember("src/META-INF/MANIFEST.MF");
+            IFile manifestFile = (IFile) project.getProject().findMember("src/META-INF/MANIFEST.MF"); //$NON-NLS-1$
             if (manifestFile != null) {
                 IWorkbenchWindow workbenchWindow = getWorkbench().getActiveWorkbenchWindow();
                 IWorkbenchPage page = workbenchWindow.getActivePage();
                 try {
                     page.openEditor(new FileEditorInput(manifestFile), BundleManifestEditor.ID_EDITOR);
                 } catch (PartInitException e) {
-                    MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", e.getMessage());
+                    MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", e.getMessage()); //$NON-NLS-1$
                 }
             }
         }
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectContentWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectContentWizard.java
new file mode 100644
index 0000000..17400e0
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectContentWizard.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.core.plugin.IPluginReference;
+import org.eclipse.pde.ui.IFieldData;
+import org.eclipse.pde.ui.IPluginContentWizard;
+
+/**
+ * A content wizard that adds a page for collecting the context root of a WAB. The bundle is assumed to be a WAB if the
+ * contect root is not empty.
+ * <p />
+ */
+public class NewPDEProjectContentWizard extends Wizard implements IPluginContentWizard {
+
+    private NewPDEProjectWABPage wabPage;
+
+    /**
+     * {@inheritDoc}
+     */
+    public void init(IFieldData data) {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public IPluginReference[] getDependencies(String schemaVersion) {
+        return new IPluginReference[0];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addPages() {
+        wabPage = new NewPDEProjectWABPage();
+        addPage(wabPage);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean performFinish(IProject project, IPluginModelBase model, IProgressMonitor monitor) {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean performFinish() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String[] getNewFiles() {
+        return new String[0];
+    }
+
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWABPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWABPage.java
new file mode 100644
index 0000000..f5c0827
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWABPage.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.wst.project.facet.SimpleWebFacetInstallDataModelProvider;
+
+/**
+ * A wizard page for specifying a Web Bundle context root.
+ * <p />
+ *
+ */
+public class NewPDEProjectWABPage extends WizardPage {
+
+    /**
+     * A subclass created for the purpose of increasing the visibility of the validation method.
+     */
+    private static class WSTValidator extends SimpleWebFacetInstallDataModelProvider {
+
+        @Override
+        public org.eclipse.core.runtime.IStatus validateContextRoot(String contextRoot) {
+            return super.validateContextRoot(contextRoot);
+        };
+    };
+
+    private final WSTValidator validator = new WSTValidator();
+
+    /**
+     * The page name.
+     */
+    public static final String PAGE_NAME = NewPDEProjectWABPage.class.getSimpleName();
+
+    public NewPDEProjectWABPage() {
+        super(PAGE_NAME);
+        setTitle(Messages.NewPDEProjectWABPage_title);
+        setDescription(Messages.NewPDEProjectWABPage_description);
+    }
+
+    private Label contextPathLabel;
+
+    private Text contextPathText;
+
+    private String contextRoot;
+
+    /**
+     * {@inheritDoc}
+     */
+    public void createControl(Composite parent) {
+        Composite container = new Composite(parent, SWT.NONE);
+        container.setLayout(new GridLayout());
+        createContextRootSection(container);
+        setControl(container);
+    }
+
+    /**
+     * Creates the context root text field.
+     *
+     * @param container the parent composite
+     */
+    protected void createContextRootSection(Composite container) {
+        container.setLayout(new GridLayout(3, false));
+        container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        this.contextPathLabel = new Label(container, SWT.NONE);
+        this.contextPathLabel.setText(Messages.NewPDEProjectWABPage_context_root);
+
+        this.contextPathText = new Text(container, SWT.BORDER | SWT.SINGLE);
+        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).span(2, 1).applyTo(this.contextPathText);
+
+        this.contextPathText.addModifyListener(new ModifyListener() {
+
+            public void modifyText(ModifyEvent e) {
+                NewPDEProjectWABPage.this.modifyText(e);
+            }
+        });
+    }
+
+    /**
+     * Validates the context root.
+     *
+     * @param e the modify event fired by the text widget
+     */
+    protected void modifyText(ModifyEvent e) {
+        contextRoot = null;
+
+        String name = contextPathText.getText();
+        IStatus status = validator.validateContextRoot(name);
+
+        if (!status.isOK()) {
+            setPageComplete(false);
+            setErrorMessage(status.getMessage());
+            return;
+        }
+
+        contextRoot = name;
+        setPageComplete(true);
+        setErrorMessage(null);
+    }
+
+    /**
+     * Returns the value of the context root.
+     *
+     * @return the context root
+     */
+    public String getContextRoot() {
+        return contextRoot;
+    }
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWizard.java
new file mode 100644
index 0000000..964f9d3
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWizard.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ *  Copyright (c) 2015 GianMaria Romanato
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.pde.core.project.IBundleProjectService;
+import org.eclipse.pde.ui.templates.NewPluginProjectFromTemplateWizard;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.pde.core.internal.cmd.SetupProjectOperation;
+import org.eclipse.virgo.ide.ui.ServerIdeUiPlugin;
+
+/**
+ * A PDE template wizard used to create PDE projects for Virgo tools.
+ * <p />
+ *
+ */
+public class NewPDEProjectWizard extends NewPluginProjectFromTemplateWizard {
+
+    public NewPDEProjectWizard() {
+        super();
+        setWindowTitle(Messages.NewPDEProjectWizard_title);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String getTemplateID() {
+        return "org.eclipse.virgo.ide.ui.pdetemplate"; //$NON-NLS-1$
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean performFinish() {
+        boolean result = super.performFinish();
+        if (result) {
+            // on finish modify the newly created PDE project
+            WizardNewProjectCreationPage newProjectCreationPage = (WizardNewProjectCreationPage) getPage("main"); //$NON-NLS-1$
+            IProject project = newProjectCreationPage.getProjectHandle();
+            IBundleProjectService service = PlatformUI.getWorkbench().getService(IBundleProjectService.class);
+            String contextRoot = getContextRoot();
+
+            final SetupProjectOperation operation = new SetupProjectOperation(project, contextRoot, service);
+
+            try {
+                getContainer().run(true, false, new IRunnableWithProgress() {
+
+                    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+                        try {
+                            ResourcesPlugin.getWorkspace().run(operation, monitor);
+                        } catch (CoreException e) {
+                            StatusManager.getManager().handle(e.getStatus(), StatusManager.LOG | StatusManager.SHOW);
+                        }
+                    }
+                });
+            } catch (Exception e) {
+                IStatus s = new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, e.getMessage(), e);
+                StatusManager.getManager().handle(s, StatusManager.LOG | StatusManager.SHOW);
+            }
+        }
+        return true;
+    }
+
+    private String getContextRoot() {
+        NewPDEProjectWABPage wabPage = (NewPDEProjectWABPage) getPage(NewPDEProjectWABPage.class.getSimpleName());
+        String contextRoot = wabPage.getContextRoot();
+        return contextRoot;
+    }
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java
index 432ea57..987619e 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java
@@ -22,9 +22,9 @@
  */
 public class NewParProjectReferencePage extends WizardNewProjectReferencePage {
 
-    private static String NEW_PROJECT_REFERENCE_TITLE = "Bundle References";
+    private static String NEW_PROJECT_REFERENCE_TITLE = Messages.NewParProjectReferencePage_title;
 
-    private static String NEW_PROJECT_REFERENCE_DESCRIPTION = "Add bundles to PAR project.";
+    private static String NEW_PROJECT_REFERENCE_DESCRIPTION = Messages.NewParProjectReferencePage_desc;
 
     public NewParProjectReferencePage(String pageName) {
         super(pageName);
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java
index 8c9ffc2..3f10f4f 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java
@@ -22,9 +22,9 @@
  */
 public class NewParProjectSettingsPage extends WizardNewProjectCreationPage {
 
-    private static String NEW_PROJECT_SETTINGS_TITLE = "Create a PAR project";
+    private static String NEW_PROJECT_SETTINGS_TITLE = Messages.NewParProjectSettingsPage_TITLE;
 
-    private static String NEW_PROJECT_SETTINGS_DESCRIPTION = "Enter a name and location for the PAR project.";
+    private static String NEW_PROJECT_SETTINGS_DESCRIPTION = Messages.NewParProjectSettingsPage_DESCRIPTION;
 
     private final IStructuredSelection selection;
 
@@ -38,7 +38,7 @@
     @Override
     public void createControl(Composite parent) {
         super.createControl(parent);
-        createWorkingSetGroup((Composite) getControl(), this.selection, new String[] { "org.eclipse.jdt.ui.JavaWorkingSetPage" });
+        createWorkingSetGroup((Composite) getControl(), this.selection, new String[] { "org.eclipse.jdt.ui.JavaWorkingSetPage" }); //$NON-NLS-1$
         Dialog.applyDialogFont(getControl());
     }
 
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java
index 0c09d4f..d735b32 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java
@@ -72,9 +72,9 @@
  */
 public class NewParProjectWizard extends AbstractNewParProjectWizard implements INewWizard {
 
-    private static final String PAR_FILE_NAME = ".settings/org.eclipse.virgo.ide.runtime.core.par.xml";
+    private static final String PAR_FILE_NAME = ".settings/org.eclipse.virgo.ide.runtime.core.par.xml"; //$NON-NLS-1$
 
-    private static final String ENCODING_UTF8 = "UTF-8";
+    private static final String ENCODING_UTF8 = "UTF-8"; //$NON-NLS-1$
 
     private WizardNewProjectCreationPage mainPage;
 
@@ -88,7 +88,7 @@
 
     private final IDataModel model;
 
-    private final String title = "New PAR Project";
+    private final String title = Messages.NewParProjectWizard_title;
 
     protected ParPackage parPackage = ParPackage.eINSTANCE;
 
@@ -128,16 +128,16 @@
         try {
             getContainer().run(true, true, oper);
         } catch (InvocationTargetException e) {
-            StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Exception while adding project facets.", e));
+            StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Exception while adding project facets.", e)); //$NON-NLS-1$
         } catch (InterruptedException e) {
             StatusManager.getManager().handle(
-                new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while adding project facets.", e));
+                new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while adding project facets.", e)); //$NON-NLS-1$
         }
     }
 
     @Override
     public void addPages() {
-        this.mainPage = new NewParProjectSettingsPage("basicNewProjectPage", getSelection());
+        this.mainPage = new NewParProjectSettingsPage("basicNewProjectPage", getSelection()); //$NON-NLS-1$
         setMainPage(this.mainPage);
         addPage(this.mainPage);
 
@@ -161,7 +161,7 @@
 
         // only add page if there are already projects in the workspace
         if (ResourcesPlugin.getWorkspace().getRoot().getProjects().length > 0) {
-            this.referencePage = new NewParProjectReferencePage("basicReferenceProjectPage");
+            this.referencePage = new NewParProjectReferencePage("basicReferenceProjectPage"); //$NON-NLS-1$
             addPage(this.referencePage);
         }
     }
@@ -244,7 +244,7 @@
             getWorkbench().getWorkingSetManager().addToWorkingSets(getNewProject(), workingSets);
         }
 
-        IFile manifestFile = (IFile) getNewProject().findMember("META-INF/MANIFEST.MF");
+        IFile manifestFile = (IFile) getNewProject().findMember("META-INF/MANIFEST.MF"); //$NON-NLS-1$
         if (manifestFile != null) {
             // Select the new file resource in the current view.
             //
@@ -266,7 +266,7 @@
             try {
                 page.openEditor(new FileEditorInput(manifestFile), ParManifestEditor.ID_EDITOR);
             } catch (PartInitException exception) {
-                MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", exception.getMessage());
+                MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", exception.getMessage()); //$NON-NLS-1$
             }
             return true;
         }
@@ -298,7 +298,7 @@
 
     @Override
     protected void initializeDefaultPageImageDescriptor() {
-        setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-par.png"));
+        setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-par.png")); //$NON-NLS-1$
     }
 
 }
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java
index de71d2b..49bd930 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java
@@ -21,7 +21,7 @@
  */
 public class NullPropertiesPage extends AbstractPropertiesPage {
 
-    protected static String ID_PAGE = "null.properties";
+    protected static String ID_PAGE = "null.properties"; //$NON-NLS-1$
 
     public NullPropertiesPage() {
         super(ID_PAGE);
@@ -34,7 +34,7 @@
 
     @Override
     public String getModuleType() {
-        return "";
+        return ""; //$NON-NLS-1$
     }
 
     @Override
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java
index 0e55744..ae3042e 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java
@@ -19,36 +19,36 @@
 public class ProjectContentPageStrings {
 
     // PDEUIMessages (modified)
-    public static String Bundle_ContentPage_title = "Bundle Content";
+    public static String Bundle_ContentPage_title = Messages.ProjectContentPageStrings_bundle_content;
 
-    public static String Par_ContentPage_title = "PAR Content";
+    public static String Par_ContentPage_title = Messages.ProjectContentPageStrings_par_content;
 
-    public static String Bundle_ContentPage_desc = "Enter the data required to generate the bundle.";
+    public static String Bundle_ContentPage_desc = Messages.ProjectContentPageStrings_bundle_content_desc;
 
-    public static String Par_ContentPage_desc = "Enter the data required to generate the PAR.";
+    public static String Par_ContentPage_desc = Messages.ProjectContentPageStrings_par_content_desc;
 
-    public static String Bundle_ContentPage_pGroup = "Bundle Properties";
+    public static String Bundle_ContentPage_pGroup = Messages.ProjectContentPageStrings_bundle_properties;
 
-    public static String Par_ContentPage_pGroup = "PAR Properties";
+    public static String Par_ContentPage_pGroup = Messages.ProjectContentPageStrings_par_prorperties;
 
-    public static String Bundle_ContentPage_pid = "Bundle Symbolic Name";
+    public static String Bundle_ContentPage_pid = Messages.ProjectContentPageStrings_symb_name;
 
-    public static String Par_ContentPage_pid = "Application Symbolic Name";
+    public static String Par_ContentPage_pid = Messages.ProjectContentPageStrings_par_symb_name;
 
-    public static String Bundle_ContentPage_pversion = "Bundle Version";
+    public static String Bundle_ContentPage_pversion = Messages.ProjectContentPageStrings_bundle_version;
 
-    public static String Par_ContentPage_pversion = "Application Version";
+    public static String Par_ContentPage_pversion = Messages.ProjectContentPageStrings_par_version;
 
-    public static String Bundle_ContentPage_pname = "Bundle Name";
+    public static String Bundle_ContentPage_pname = Messages.ProjectContentPageStrings_bundle_name;
 
-    public static String Par_ContentPage_pname = "Application Name";
+    public static String Par_ContentPage_pname = Messages.ProjectContentPageStrings_par_name;
 
-    public static String Bundle_ContentPage_pprovider = "Bundle Description";
+    public static String Bundle_ContentPage_pprovider = Messages.ProjectContentPageStrings_bundle_desc;
 
-    public static String Par_ContentPage_pprovider = "Application Description";
+    public static String Par_ContentPage_pprovider = Messages.ProjectContentPageStrings_par_desc;
 
-    public static String Bundle_ContentPage_plugin = "{0} Bundle";
+    public static String Bundle_ContentPage_plugin = Messages.ProjectContentPageStrings_bundle_plugin;
 
-    public static String Par_ContentPage_plugin = "{0} PAR";
+    public static String Par_ContentPage_plugin = Messages.ProjectContentPageStrings_par_plugin;
 
 }
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java
index ea59bca..0431f05 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java
@@ -29,7 +29,7 @@
  */
 public class WebModulePropertiesPage extends AbstractPropertiesPage {
 
-    protected static String ID_PAGE = "web.properties";
+    protected static String ID_PAGE = "web.properties"; //$NON-NLS-1$
 
     private Label contextPathLabel;
 
@@ -44,10 +44,10 @@
         Group propertiesGroup = new Group(container, SWT.NONE);
         propertiesGroup.setLayout(new GridLayout(3, false));
         propertiesGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        propertiesGroup.setText("Web Module Properties");
+        propertiesGroup.setText(Messages.WebModulePropertiesPage_text);
 
         this.contextPathLabel = new Label(propertiesGroup, SWT.NONE);
-        this.contextPathLabel.setText("Web-ContextPath");
+        this.contextPathLabel.setText(Messages.WebModulePropertiesPage_context_path);
 
         this.contextPathText = new Text(propertiesGroup, SWT.BORDER | SWT.SINGLE);
         GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).span(2, 1).applyTo(this.contextPathText);
@@ -62,7 +62,7 @@
 
     @Override
     public String getModuleType() {
-        return "Web";
+        return "Web"; //$NON-NLS-1$
     }
 
 }
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/messages.properties b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/messages.properties
new file mode 100644
index 0000000..0152f53
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/messages.properties
@@ -0,0 +1,37 @@
+AbstractPropertiesPage_description=Set the additional properties of the bundle. 
+AbstractPropertiesPage_description2=You can modify the properties at any time in the MANIFEST.MF file.
+AbstractPropertiesPage_title=Bundle Properties
+NewBundleInformationPage_Additional_Properties=Additional Properties
+NewBundleInformationPage_Classpath_Management=Classpath Management
+NewBundleInformationPage_enable_container=Enable Bundle Classpath Container
+NewBundleInformationPage_WAB=Web Application Bundle
+NewBundleProjectSettingsPage_DESCRIPTION=Create a Bundle project in the workspace or in an external location.
+NewBundleProjectSettingsPage_TITLE=Create a Bundle project
+NewBundleProjectWizard_title=New Bundle Project
+NewParProjectReferencePage_desc=Add bundles to PAR project.
+NewParProjectReferencePage_title=Bundle References
+NewParProjectSettingsPage_DESCRIPTION=Enter a name and location for the PAR project.
+NewParProjectSettingsPage_TITLE=Create a PAR project
+NewParProjectWizard_title=New PAR Project
+NewPDEProjectWABPage_context_root=Context root:
+NewPDEProjectWABPage_description=Specify a Context root if you want the project to be a WAB
+NewPDEProjectWABPage_title=Web Application Bundle
+NewPDEProjectWizard_title=New Virgo PDE Bundle Project
+ProjectContentPageStrings_bundle_content=Bundle Content
+ProjectContentPageStrings_bundle_content_desc=Enter the data required to generate the bundle.
+ProjectContentPageStrings_bundle_desc=Bundle Description
+ProjectContentPageStrings_bundle_name=Bundle Name
+ProjectContentPageStrings_bundle_plugin={0} Bundle
+ProjectContentPageStrings_bundle_properties=Bundle Properties
+ProjectContentPageStrings_bundle_version=Bundle Version
+ProjectContentPageStrings_par_content=PAR Content
+ProjectContentPageStrings_par_content_desc=Enter the data required to generate the PAR.
+ProjectContentPageStrings_par_desc=Application Description
+ProjectContentPageStrings_par_name=Application Name
+ProjectContentPageStrings_par_plugin={0} PAR
+ProjectContentPageStrings_par_prorperties=PAR Properties
+ProjectContentPageStrings_par_symb_name=Application Symbolic Name
+ProjectContentPageStrings_par_version=Application Version
+ProjectContentPageStrings_symb_name=Bundle Symbolic Name
+WebModulePropertiesPage_context_path=Web-ContextPath
+WebModulePropertiesPage_text=Web Module Properties
diff --git a/pom.xml b/pom.xml
index 3d0dc1c..e666c2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,7 @@
     <module>org.eclipse.virgo.ide.export</module>
     <module>org.eclipse.virgo.ide.export.tests</module>
     <module>org.eclipse.virgo.ide.facet.core</module>
+    <module>org.eclipse.virgo.ide.pde.core</module>
     <module>org.eclipse.virgo.ide.feature</module>
     <module>org.eclipse.virgo.ide.jdt.core</module>
     <module>org.eclipse.virgo.ide.jdt.ui</module>