Bug 576379 - Migrate the preference spy to PDE

Change-Id: Iba50317df732799605a416f8fc8b45429890ef44
Signed-off-by: Lars Vogel <Lars.Vogel@vogella.com>
Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/186036
Tested-by: PDE Bot <pde-bot@eclipse.org>
diff --git a/features/org.eclipse.pde-feature/feature.xml b/features/org.eclipse.pde-feature/feature.xml
index 4e040b3..3dba1d4 100644
--- a/features/org.eclipse.pde-feature/feature.xml
+++ b/features/org.eclipse.pde-feature/feature.xml
@@ -209,4 +209,11 @@
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="org.eclipse.pde.spy.preferences"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
 </feature>
diff --git a/pom.xml b/pom.xml
index 26d424b..b6bb9a6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,7 @@
     <module>ui/org.eclipse.pde.spy.core</module>
     <module>ui/org.eclipse.pde.spy.css</module>
     <module>ui/org.eclipse.pde.spy.model</module> 
+    <module>ui/org.eclipse.pde.spy.preferences</module> 
     <module>ui/org.eclipse.tools.layout.spy</module>
     <module>ui/org.eclipse.pde.ui.templates.tests</module>
     <module>ui/org.eclipse.ui.trace</module>
diff --git a/ui/org.eclipse.pde.spy.preferences/.classpath b/ui/org.eclipse.pde.spy.preferences/.classpath
new file mode 100644
index 0000000..e801ebf
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/.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/JavaSE-11"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/ui/org.eclipse.pde.spy.preferences/.project b/ui/org.eclipse.pde.spy.preferences/.project
new file mode 100644
index 0000000..1b4f8a1
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.pde.spy.preferences</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/ui/org.eclipse.pde.spy.preferences/.settings/org.eclipse.jdt.core.prefs b/ui/org.eclipse.pde.spy.preferences/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..c9545f0
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/ui/org.eclipse.pde.spy.preferences/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.spy.preferences/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a12db02
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %name
+Bundle-SymbolicName: org.eclipse.pde.spy.preferences;singleton:=true
+Bundle-Version: 0.12.100.qualifier
+Automatic-Module-Name: org.eclipse.pde.spy.preferences
+Bundle-RequiredExecutionEnvironment: JavaSE-11
+Bundle-Vendor: %provider-name
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.e4.ui.model.workbench;bundle-version="1.1.0",
+ org.eclipse.e4.core.di;bundle-version="1.4.0",
+ org.eclipse.e4.core.di.extensions;bundle-version="0.12.0",
+ org.eclipse.e4.core.services;bundle-version="1.2.0",
+ org.eclipse.osgi.services;bundle-version="3.4.0",
+ org.eclipse.e4.ui.di;bundle-version="1.0.0",
+ org.eclipse.core.databinding;bundle-version="1.4.1",
+ org.eclipse.core.databinding.beans;bundle-version="1.2.200",
+ org.eclipse.core.databinding.observable;bundle-version="1.4.1",
+ org.eclipse.core.databinding.property;bundle-version="1.4.200",
+ org.eclipse.jface.databinding;bundle-version="1.6.200",
+ org.eclipse.e4.ui.services;bundle-version="1.1.0",
+ org.eclipse.e4.ui.workbench;bundle-version="1.1.0",
+ org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.pde.spy.core;bundle-version="1.0.0"
+Import-Package: javax.annotation;version="1.3.5",
+ javax.inject;version="1.0.0"
+Bundle-ActivationPolicy: lazy
diff --git a/ui/org.eclipse.pde.spy.preferences/about.html b/ui/org.eclipse.pde.spy.preferences/about.html
new file mode 100644
index 0000000..8249486
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/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>December 3, 2009</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/ui/org.eclipse.pde.spy.preferences/build.properties b/ui/org.eclipse.pde.spy.preferences/build.properties
new file mode 100644
index 0000000..86fd816
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               about.html,\
+               icons/,\
+               plugin.xml,\
+               fragment.e4xmi
+src.includes = about.html
diff --git a/ui/org.eclipse.pde.spy.preferences/forceQualifierUpdate.txt b/ui/org.eclipse.pde.spy.preferences/forceQualifierUpdate.txt
new file mode 100644
index 0000000..396f087
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/forceQualifierUpdate.txt
@@ -0,0 +1,2 @@
+# To force a version qualifier update add the bug here
+Bug 403237 - o.e.e4.tools cannot be build with "mvn clean install"
diff --git a/ui/org.eclipse.pde.spy.preferences/fragment.e4xmi b/ui/org.eclipse.pde.spy.preferences/fragment.e4xmi
new file mode 100644
index 0000000..e1bd29f
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/fragment.e4xmi
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/descriptor/basic" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_YKjYcGxMEeSQ7v0akw7aRA">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_wcDNcGxMEeSQ7v0akw7aRA" featurename="addons" parentElementId="xpath:/">
+    <elements xsi:type="application:Addon" xmi:id="_ztg-MGxMEeSQ7v0akw7aRA" elementId="org.eclipse.pde.spy.preferences.addon" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.addon.PreferenceSpyAddon">
+      <persistedState key="persistState" value="false"/>
+    </elements>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_P3fYQGxbEeSQ7v0akw7aRA" featurename="descriptors" parentElementId="xpath:/">
+    <elements xsi:type="basic:PartDescriptor" xmi:id="_T4iy4GxbEeSQ7v0akw7aRA" elementId="org.eclipse.pde.spy.preferences.parts.PreferenceSpyPart" label="Preference Spy" iconURI="platform:/plugin/org.eclipse.pde.spy.preferences/icons/preference_spy.png" category="Eclipse runtime spies" closeable="true" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.parts.PreferenceSpyPart">
+      <persistedState key="perstistState" value="false"/>
+      <tags>View</tags>
+      <tags>Spy</tags>
+      <tags>categoryTag:Eclipse runtime spies</tags>
+      <handlers xmi:id="_lADpICKSEey779Ohesl6_A" elementId="org.eclipse.pde.spy.preferences.handler.removeall" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.handler.RemoveAllHandler" command="_eBGTEGxiEeSQ7v0akw7aRA">
+        <persistedState key="persistState" value="false"/>
+      </handlers>
+      <handlers xmi:id="_lAGFYCKSEey779Ohesl6_A" elementId="org.eclipse.pde.spy.preferences.handler.removeentry" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.handler.RemoveEntryHandler" command="_iGEkYGxiEeSQ7v0akw7aRA">
+        <persistedState key="persistState" value="false"/>
+      </handlers>
+      <handlers xmi:id="_lAGscCKSEey779Ohesl6_A" elementId="org.eclipse.pde.spy.preferences.handler.showall" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.handler.ShowAllPreferencesHandler" command="_ufxRsHY2EeSuTdKDH5hMwg">
+        <persistedState key="persistState" value="false"/>
+      </handlers>
+      <handlers xmi:id="_lAGscSKSEey779Ohesl6_A" elementId="org.eclipse.pde.spy.preferences.handler.expandall" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.handler.ExpandAllHandler" command="_4NM_IH_gEeSk-4v3KnNHPw">
+        <persistedState key="persistState" value="false"/>
+      </handlers>
+      <handlers xmi:id="_lAHTgCKSEey779Ohesl6_A" elementId="org.eclipse.pde.spy.preferences.handler.collapseall" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.handler.CollapseAllHandler" command="_68UQwH_gEeSk-4v3KnNHPw">
+        <persistedState key="persistState" value="false"/>
+      </handlers>
+      <toolbar xmi:id="_z17t0GxhEeSQ7v0akw7aRA" elementId="org.eclipse.pde.spy.preferences.toolbar">
+        <children xsi:type="menu:ToolControl" xmi:id="_HKPQsIboEeS8O7Wb7Enz2Q" elementId="org.eclipse.pde.spy.preferences.toolcontrol.layout" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.handler.ToggleLayoutControl"/>
+        <children xsi:type="menu:ToolBarSeparator" xmi:id="_BW4yAIboEeS8O7Wb7Enz2Q" elementId="org.eclipse.pde.spy.preferences.toolbarseparator.0"/>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_WhdsMHY7EeSuTdKDH5hMwg" elementId="org.eclipse.pde.spy.preferences.handledtoolitem.showall" iconURI="platform:/plugin/org.eclipse.pde.spy.preferences/icons/show_all_preferences.png" command="_ufxRsHY2EeSuTdKDH5hMwg"/>
+        <children xsi:type="menu:ToolControl" xmi:id="_D4kokIVcEeSI3e-Kt-dGSA" elementId="org.eclipse.pde.spy.preferences.toolcontrol.trace" contributionURI="bundleclass://org.eclipse.pde.spy.preferences/org.eclipse.pde.spy.preferences.handler.TogglePreferenceTraceControl"/>
+        <children xsi:type="menu:ToolBarSeparator" xmi:id="_xSwgEH_hEeSk-4v3KnNHPw" elementId="org.eclipse.pde.spy.preferences.toolbarseparator.1"/>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_zYuuEH_hEeSk-4v3KnNHPw" elementId="org.eclipse.pde.spy.preferences.handledtoolitem.expandall" iconURI="platform:/plugin/org.eclipse.pde.spy.preferences/icons/expandall.png" command="_4NM_IH_gEeSk-4v3KnNHPw"/>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_4wyX4H_hEeSk-4v3KnNHPw" elementId="org.eclipse.pde.spy.preferences.handledtoolitem.collapseall" iconURI="platform:/plugin/org.eclipse.pde.spy.preferences/icons/collapseall.png" command="_68UQwH_gEeSk-4v3KnNHPw"/>
+        <children xsi:type="menu:ToolBarSeparator" xmi:id="_7dG0MH_hEeSk-4v3KnNHPw" elementId="org.eclipse.pde.spy.preferences.toolbarseparator.2"/>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_A6VYQGxiEeSQ7v0akw7aRA" elementId="org.eclipse.pde.spy.preferences.handledtoolitem.removeentry" iconURI="platform:/plugin/org.eclipse.pde.spy.preferences/icons/remove_co.png" command="_iGEkYGxiEeSQ7v0akw7aRA"/>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_Tj_JEGxkEeSQ7v0akw7aRA" elementId="org.eclipse.pde.spy.preferences.handledtoolitem.removeall" iconURI="platform:/plugin/org.eclipse.pde.spy.preferences/icons/removeall_co.png" command="_eBGTEGxiEeSQ7v0akw7aRA"/>
+      </toolbar>
+    </elements>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_YcT00GxiEeSQ7v0akw7aRA" featurename="commands" parentElementId="xpath:/">
+    <elements xsi:type="commands:Command" xmi:id="_eBGTEGxiEeSQ7v0akw7aRA" elementId="org.eclipse.pde.spy.preferences.command.removeAll" commandName="Remove All">
+      <persistedState key="persistState" value="false"/>
+      <parameters xmi:id="_ujUuENlxEemSlqvMhebMxQ" elementId="org.eclipse.pde.spy.preferences.commandparameter.0" name="Command Parameter 0"/>
+    </elements>
+    <elements xsi:type="commands:Command" xmi:id="_iGEkYGxiEeSQ7v0akw7aRA" elementId="org.eclipse.pde.spy.preferences.command.removeEntry" commandName="Remove Entry">
+      <persistedState key="persistState" value="false"/>
+    </elements>
+    <elements xsi:type="commands:Command" xmi:id="_ufxRsHY2EeSuTdKDH5hMwg" elementId="org.eclipse.pde.spy.preferences.command.showAllPreferences" commandName="Show All Preferences">
+      <persistedState key="persistState" value="false"/>
+    </elements>
+    <elements xsi:type="commands:Command" xmi:id="_4NM_IH_gEeSk-4v3KnNHPw" elementId="org.eclipse.pde.spy.preferences.command.expandAll" commandName="Expand All">
+      <persistedState key="persistState" value="false"/>
+    </elements>
+    <elements xsi:type="commands:Command" xmi:id="_68UQwH_gEeSk-4v3KnNHPw" elementId="org.eclipse.pde.spy.preferences.command.collapseAll" commandName="Collapse All">
+      <persistedState key="persistState" value="false"/>
+    </elements>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/collapseall.png b/ui/org.eclipse.pde.spy.preferences/icons/collapseall.png
new file mode 100644
index 0000000..a40ba4e
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/collapseall.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/expandall.png b/ui/org.eclipse.pde.spy.preferences/icons/expandall.png
new file mode 100644
index 0000000..fcdfcbd
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/expandall.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/flatLayout.png b/ui/org.eclipse.pde.spy.preferences/icons/flatLayout.png
new file mode 100644
index 0000000..06750ba
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/flatLayout.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/hierarchicalLayout.png b/ui/org.eclipse.pde.spy.preferences/icons/hierarchicalLayout.png
new file mode 100644
index 0000000..ae6d660
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/hierarchicalLayout.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/preference_spy.png b/ui/org.eclipse.pde.spy.preferences/icons/preference_spy.png
new file mode 100644
index 0000000..42508a4
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/preference_spy.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/remove_co.png b/ui/org.eclipse.pde.spy.preferences/icons/remove_co.png
new file mode 100644
index 0000000..d1cd8b6
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/remove_co.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/removeall_co.png b/ui/org.eclipse.pde.spy.preferences/icons/removeall_co.png
new file mode 100644
index 0000000..e968f58
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/removeall_co.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/show_all_preferences.png b/ui/org.eclipse.pde.spy.preferences/icons/show_all_preferences.png
new file mode 100644
index 0000000..c0aa2ab
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/show_all_preferences.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/icons/trace_preferences.png b/ui/org.eclipse.pde.spy.preferences/icons/trace_preferences.png
new file mode 100644
index 0000000..78ef0c9
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/icons/trace_preferences.png
Binary files differ
diff --git a/ui/org.eclipse.pde.spy.preferences/plugin.properties b/ui/org.eclipse.pde.spy.preferences/plugin.properties
new file mode 100644
index 0000000..5aeac94
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/plugin.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2021, vogella GmbH Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+#     Lars Vogel - initial API and implementation
+###############################################################################
+#
+#
+name = Preference Spy
+provider-name = Eclipse.org
diff --git a/ui/org.eclipse.pde.spy.preferences/plugin.xml b/ui/org.eclipse.pde.spy.preferences/plugin.xml
new file mode 100644
index 0000000..d371a75
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/plugin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin>
+
+   <extension
+         id="org.eclipse.pde.spy.preferences.fragment"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="fragment.e4xmi">
+      </fragment>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            class="org.eclipse.pde.spy.preferences.preferencepage.TracePreferencePage"
+            id="org.eclipse.pde.spy.preferences.tracepreferencespage"
+            name="Preference Spy">
+      </page>
+   </extension>
+   <extension
+		 point="org.eclipse.pde.spy.core.spyPart">
+      <spyPart
+            description="Spy to display preferences"
+            icon="icons/preference_spy.png"
+            name="Preference Spy"
+            part="org.eclipse.pde.spy.preferences.parts.PreferenceSpyPart"
+            shortcut="M2+M3+F11">
+      </spyPart>
+   </extension>
+</plugin>
diff --git a/ui/org.eclipse.pde.spy.preferences/pom.xml b/ui/org.eclipse.pde.spy.preferences/pom.xml
new file mode 100644
index 0000000..9898b8b
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2012, 2019 Eclipse Foundation and others.
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Distribution License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/org/documents/edl-v10.php
+
+  Contributors:
+     Igor Fedorenko - initial implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>eclipse.pde.ui</artifactId>
+    <groupId>eclipse.pde.ui</groupId>
+    <version>4.22.0-SNAPSHOT</version>
+    <relativePath>../../</relativePath>
+  </parent>
+
+   <properties>
+    <skipAPIAnalysis>true</skipAPIAnalysis>
+  </properties>
+
+
+  <groupId>org.eclipse.e4</groupId>
+  <artifactId>org.eclipse.pde.spy.preferences</artifactId>
+  <version>0.12.100-SNAPSHOT</version>
+  <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/PreferenceSpyConfiguration.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/PreferenceSpyConfiguration.java
new file mode 100644
index 0000000..125947d
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/PreferenceSpyConfiguration.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Gives access to the scope preferences
+ */
+public class PreferenceSpyConfiguration {
+
+	private static ScopedPreferenceStore preferenceStore;
+
+	public static IPreferenceStore getPreferenceStore() {
+		// Create the preference store lazily.
+		if (preferenceStore == null) {
+			preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
+					FrameworkUtil.getBundle(PreferenceSpyConfiguration.class).getSymbolicName());
+
+		}
+		return preferenceStore;
+	}
+
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/addon/PreferenceSpyAddon.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/addon/PreferenceSpyAddon.java
new file mode 100644
index 0000000..31adce2
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/addon/PreferenceSpyAddon.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.addon;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.eclipse.core.internal.preferences.EclipsePreferences;
+import org.eclipse.core.runtime.preferences.BundleDefaultsScope;
+import org.eclipse.core.runtime.preferences.ConfigurationScope;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.di.extensions.Preference;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.pde.spy.preferences.PreferenceSpyConfiguration;
+import org.eclipse.pde.spy.preferences.constants.PreferenceConstants;
+import org.eclipse.pde.spy.preferences.constants.PreferenceSpyEventTopics;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * This model addon is used to register an IPreferenceChangeListener for all
+ * {@link EclipsePreferences} and it fires an
+ * {@link PreferenceSpyEventTopics#PREFERENCESPY_PREFERENCE_CHANGED} event via
+ * the {@link IEventBroker}.<br/>
+ * The Object, which is send within the
+ * {@link PreferenceSpyEventTopics#PREFERENCESPY_PREFERENCE_CHANGED} event is a
+ * PreferenceChangeEvent.
+ *
+ */
+@SuppressWarnings("restriction")
+public class PreferenceSpyAddon {
+
+	@Inject
+	private Logger LOG;
+
+	@Inject
+	private IEventBroker eventBroker;
+
+	private IEclipsePreferences bundleDefaultsScopePreferences = BundleDefaultsScope.INSTANCE.getNode("");
+	private IEclipsePreferences configurationScopePreferences = ConfigurationScope.INSTANCE.getNode("");
+	private IEclipsePreferences defaultScopePreferences = DefaultScope.INSTANCE.getNode("");
+	private IEclipsePreferences instanceScopePreferences = InstanceScope.INSTANCE.getNode("");
+
+	private ChangedPreferenceListener preferenceChangedListener = new ChangedPreferenceListener();
+
+	@Inject
+	@Optional
+	public void initialzePreferenceSpy(
+			@Preference(value = PreferenceConstants.TRACE_PREFERENCES) boolean tracePreferences) {
+		if (tracePreferences) {
+			registerVisitors();
+		} else {
+			deregisterVisitors();
+		}
+	}
+
+	private void registerVisitors() {
+		addPreferenceListener(bundleDefaultsScopePreferences);
+		addPreferenceListener(configurationScopePreferences);
+		addPreferenceListener(defaultScopePreferences);
+		addPreferenceListener(instanceScopePreferences);
+	}
+
+	private void addPreferenceListener(IEclipsePreferences rootPreference) {
+		try {
+			rootPreference.accept(new IPreferenceNodeVisitor() {
+				@Override
+				public boolean visit(IEclipsePreferences node) throws BackingStoreException {
+					node.addPreferenceChangeListener(preferenceChangedListener);
+					return true;
+				}
+			});
+		} catch (BackingStoreException e) {
+			LOG.error(e);
+		}
+	}
+
+	private void deregisterVisitors() {
+		removePreferenceListener(bundleDefaultsScopePreferences);
+		removePreferenceListener(configurationScopePreferences);
+		removePreferenceListener(defaultScopePreferences);
+		removePreferenceListener(instanceScopePreferences);
+	}
+
+	private void removePreferenceListener(IEclipsePreferences rootPreference) {
+		try {
+			rootPreference.accept(new IPreferenceNodeVisitor() {
+				@Override
+				public boolean visit(IEclipsePreferences node) throws BackingStoreException {
+					node.removePreferenceChangeListener(preferenceChangedListener);
+					return true;
+				}
+			});
+		} catch (BackingStoreException e) {
+			LOG.error(e);
+		}
+	}
+
+	@PostConstruct
+	public void initializeDefaultPreferences() {
+		IPreferenceStore store = PreferenceSpyConfiguration.getPreferenceStore();
+		store.setDefault(PreferenceConstants.TRACE_PREFERENCES, false);
+	}
+
+	private final class ChangedPreferenceListener implements IPreferenceChangeListener {
+
+		@Override
+		public void preferenceChange(PreferenceChangeEvent event) {
+			eventBroker.post(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_CHANGED, event);
+		}
+	}
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/constants/PreferenceConstants.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/constants/PreferenceConstants.java
new file mode 100644
index 0000000..7415818
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/constants/PreferenceConstants.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.constants;
+
+/**
+ * Constant definitions for plug-in preferences
+ */
+public class PreferenceConstants {
+
+	public enum ViewerLayouts {
+		Flat, Hierarchical;
+	}
+
+	public static final String TRACE_PREFERENCES = "tracepreferences";
+	public static final String HIERARCHICAL_LAYOUT = "hierarchicalLayoutPreference";
+
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/constants/PreferenceSpyEventTopics.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/constants/PreferenceSpyEventTopics.java
new file mode 100644
index 0000000..c8a3d9a
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/constants/PreferenceSpyEventTopics.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.constants;
+
+public interface PreferenceSpyEventTopics {
+
+	public static final String PREFERENCESPY_PREFERENCE_ENTRIES_DELETE_ALL = "TOPIC_PREFERENCESPY/PREFERENCE_ENTRIES/DELETE_ALL";
+	public static final String PREFERENCESPY_PREFERENCE_ENTRIES_DELETE = "TOPIC_PREFERENCESPY/PREFERENCE_ENTRIES/DELETE";
+
+	public static final String PREFERENCESPY_PREFERENCE_CHANGED = "TOPIC_PREFERENCESPY/PREFERENCE/CHANGED";
+	public static final String PREFERENCESPY_PREFERENCE_SHOW = "TOPIC_PREFERENCESPY/PREFERENCE/SHOW";
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/CollapseAllHandler.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/CollapseAllHandler.java
new file mode 100644
index 0000000..b339e24
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/CollapseAllHandler.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.handler;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.pde.spy.preferences.parts.PreferenceSpyPart;
+
+public class CollapseAllHandler {
+
+	@Execute
+	public void execute(MPart part) {
+		Object partImpl = part.getObject();
+		if (partImpl instanceof PreferenceSpyPart) {
+			((PreferenceSpyPart) partImpl).getViewer().collapseAll();
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ExpandAllHandler.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ExpandAllHandler.java
new file mode 100644
index 0000000..7ed87d4
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ExpandAllHandler.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.handler;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.pde.spy.preferences.parts.PreferenceSpyPart;
+
+public class ExpandAllHandler {
+
+	@Execute
+	public void execute(MPart part) {
+		Object partImpl = part.getObject();
+		if (partImpl instanceof PreferenceSpyPart) {
+			((PreferenceSpyPart) partImpl).getViewer().expandAll();
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/RemoveAllHandler.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/RemoveAllHandler.java
new file mode 100644
index 0000000..b440888
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/RemoveAllHandler.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.handler;
+
+import java.util.List;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.pde.spy.preferences.constants.PreferenceSpyEventTopics;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+
+public class RemoveAllHandler {
+	@Execute
+	public void execute(IEventBroker eventBroker,
+			@Optional @Named(IServiceConstants.ACTIVE_SELECTION) List<PreferenceEntry> preferenceEntries) {
+		eventBroker.post(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_ENTRIES_DELETE_ALL, preferenceEntries);
+	}
+
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/RemoveEntryHandler.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/RemoveEntryHandler.java
new file mode 100644
index 0000000..cd9a217
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/RemoveEntryHandler.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.handler;
+
+import java.util.List;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.pde.spy.preferences.constants.PreferenceSpyEventTopics;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+
+public class RemoveEntryHandler {
+	@Execute
+	public void execute(IEventBroker eventBroker,
+			@Optional @Named(IServiceConstants.ACTIVE_SELECTION) List<PreferenceEntry> preferenceEntries) {
+		eventBroker.post(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_ENTRIES_DELETE, preferenceEntries);
+	}
+
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ShowAllPreferencesHandler.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ShowAllPreferencesHandler.java
new file mode 100644
index 0000000..ae78f2b
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ShowAllPreferencesHandler.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.handler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.BundleDefaultsScope;
+import org.eclipse.core.runtime.preferences.ConfigurationScope;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.pde.spy.preferences.constants.PreferenceSpyEventTopics;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+import org.eclipse.pde.spy.preferences.model.PreferenceNodeEntry;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.service.prefs.BackingStoreException;
+
+public class ShowAllPreferencesHandler {
+	@Execute
+	public void execute(Shell shell, IEventBroker eventBroker) {
+		Map<String, PreferenceNodeEntry> preferenceEntries = new HashMap<String, PreferenceNodeEntry>();
+		IEclipsePreferences bundleDefaultsScopePreferences = BundleDefaultsScope.INSTANCE.getNode("");
+		IEclipsePreferences configurationScopePreferences = ConfigurationScope.INSTANCE.getNode("");
+		IEclipsePreferences defaultScopePreferences = DefaultScope.INSTANCE.getNode("");
+		IEclipsePreferences instanceScopePreferences = InstanceScope.INSTANCE.getNode("");
+		try {
+			bundleDefaultsScopePreferences.accept(new PrefereneGatherer(preferenceEntries));
+			configurationScopePreferences.accept(new PrefereneGatherer(preferenceEntries));
+			defaultScopePreferences.accept(new PrefereneGatherer(preferenceEntries));
+			instanceScopePreferences.accept(new PrefereneGatherer(preferenceEntries));
+		} catch (BackingStoreException e) {
+			ErrorDialog.openError(shell, "BackingStoreException", e.getLocalizedMessage(),
+					Status.error(e.getMessage()));
+		}
+		eventBroker.post(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_SHOW, preferenceEntries.values());
+	}
+
+	private class PrefereneGatherer implements IPreferenceNodeVisitor {
+
+		private Map<String, PreferenceNodeEntry> preferenceEntries;
+
+		public PrefereneGatherer(Map<String, PreferenceNodeEntry> preferenceEntries) {
+			this.preferenceEntries = preferenceEntries;
+		}
+
+		@Override
+		public boolean visit(IEclipsePreferences node) throws BackingStoreException {
+			// only show nodes, which have changed keys
+			String[] keys = node.keys();
+			if (keys.length <= 0) {
+				return true;
+			}
+			PreferenceNodeEntry preferenceNodeEntry = preferenceEntries.get(node.absolutePath());
+			if (null == preferenceNodeEntry) {
+				preferenceNodeEntry = new PreferenceNodeEntry(node.absolutePath());
+				preferenceEntries.put(node.absolutePath(), preferenceNodeEntry);
+			}
+			for (String key : keys) {
+				String value = node.get(key, "*default*");
+				PreferenceEntry preferenceEntry = new PreferenceEntry(node.absolutePath(), key, value, value);
+				preferenceNodeEntry.addChildren(preferenceEntry);
+			}
+			return true;
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ToggleLayoutControl.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ToggleLayoutControl.java
new file mode 100644
index 0000000..bb758f7
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/ToggleLayoutControl.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.handler;
+
+import java.net.URL;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.e4.core.di.extensions.Preference;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.pde.spy.preferences.constants.PreferenceConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.prefs.BackingStoreException;
+
+@SuppressWarnings("restriction")
+public class ToggleLayoutControl {
+
+	@Inject
+	Logger LOG;
+
+	private ToolItem toolItem;
+	private ResourceManager resourceManager;
+
+	@Inject
+	public void tracePreferenceChanged(
+			@Preference(value = PreferenceConstants.HIERARCHICAL_LAYOUT) boolean hierarchicalLayoutPreference) {
+		if (toolItem != null && !toolItem.isDisposed()) {
+			toolItem.setSelection(hierarchicalLayoutPreference);
+			toolItem.setImage(
+					hierarchicalLayoutPreference ? getResourceManager().createImage(getHierarchicalImageDescriptor())
+							: getResourceManager().createImage(getFlatImageDescriptor()));
+			toolItem.setToolTipText(
+					hierarchicalLayoutPreference ? "Toogle to flat layout" : "Toggle to hierarchical layout");
+		}
+	}
+
+	@PostConstruct
+	public void createGui(Composite parent, final @Preference IEclipsePreferences preferences,
+			@Preference(value = PreferenceConstants.HIERARCHICAL_LAYOUT) boolean hierarchicalLayoutPreference) {
+		ToolBar toolBar = new ToolBar(parent, SWT.NONE);
+		toolItem = new ToolItem(toolBar, SWT.CHECK);
+		toolItem.setToolTipText(
+				hierarchicalLayoutPreference ? "Toogle to flat layout" : "Toggle to hierarchical layout");
+		toolItem.addSelectionListener(new SelectionAdapter() {
+
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				Object source = event.getSource();
+				if (source instanceof ToolItem) {
+					preferences.putBoolean(PreferenceConstants.HIERARCHICAL_LAYOUT, ((ToolItem) source).getSelection());
+					try {
+						preferences.flush();
+					} catch (BackingStoreException e) {
+						LOG.error(e);
+					}
+				}
+			}
+		});
+		tracePreferenceChanged(hierarchicalLayoutPreference);
+	}
+
+	@PreDestroy
+	public void dispose() {
+		if (resourceManager != null) {
+			resourceManager.dispose();
+		}
+	}
+
+	protected ResourceManager getResourceManager() {
+		if (null == resourceManager) {
+			resourceManager = new LocalResourceManager(JFaceResources.getResources());
+		}
+		return resourceManager;
+	}
+
+	protected ImageDescriptor getFlatImageDescriptor() {
+		Bundle bundle = FrameworkUtil.getBundle(getClass());
+		URL url = FileLocator.find(bundle, new Path("icons/flatLayout.png"), null);
+		return ImageDescriptor.createFromURL(url);
+	}
+
+	protected ImageDescriptor getHierarchicalImageDescriptor() {
+		Bundle bundle = FrameworkUtil.getBundle(getClass());
+		URL url = FileLocator.find(bundle, new Path("icons/hierarchicalLayout.png"), null);
+		return ImageDescriptor.createFromURL(url);
+	}
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/TogglePreferenceTraceControl.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/TogglePreferenceTraceControl.java
new file mode 100644
index 0000000..97212ba
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/handler/TogglePreferenceTraceControl.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.handler;
+
+import java.net.URL;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.e4.core.di.extensions.Preference;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.pde.spy.preferences.constants.PreferenceConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.prefs.BackingStoreException;
+
+@SuppressWarnings("restriction")
+public class TogglePreferenceTraceControl {
+
+	@Inject
+	Logger LOG;
+
+	private ToolItem toolItem;
+	private ResourceManager resourceManager;
+
+	@Inject
+	public void tracePreferenceChanged(
+			@Preference(value = PreferenceConstants.TRACE_PREFERENCES) boolean tracePreferences) {
+		if (toolItem != null && !toolItem.isDisposed()) {
+			toolItem.setSelection(tracePreferences);
+		}
+	}
+
+	@PostConstruct
+	public void createGui(Composite parent, final @Preference IEclipsePreferences preferences,
+			@Preference(value = PreferenceConstants.TRACE_PREFERENCES) boolean tracePreferences) {
+		ToolBar toolBar = new ToolBar(parent, SWT.NONE);
+		toolItem = new ToolItem(toolBar, SWT.CHECK);
+		toolItem.setSelection(tracePreferences);
+		toolItem.setToolTipText("Toggle Preference Trace");
+		toolItem.setImage(getResourceManager().createImage(getImageDescriptor()));
+		toolItem.addSelectionListener(new SelectionAdapter() {
+
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				Object source = event.getSource();
+				if (source instanceof ToolItem) {
+					preferences.putBoolean(PreferenceConstants.TRACE_PREFERENCES, ((ToolItem) source).getSelection());
+					try {
+						preferences.flush();
+					} catch (BackingStoreException e) {
+						LOG.error(e);
+					}
+				}
+			}
+		});
+	}
+
+	@PreDestroy
+	public void dispose() {
+		if (resourceManager != null) {
+			resourceManager.dispose();
+		}
+	}
+
+	protected ResourceManager getResourceManager() {
+		if (null == resourceManager) {
+			resourceManager = new LocalResourceManager(JFaceResources.getResources());
+		}
+		return resourceManager;
+	}
+
+	protected ImageDescriptor getImageDescriptor() {
+		Bundle bundle = FrameworkUtil.getBundle(getClass());
+		URL url = FileLocator.find(bundle, new Path("icons/trace_preferences.png"), null);
+		return ImageDescriptor.createFromURL(url);
+	}
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/AbstractModelObject.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/AbstractModelObject.java
new file mode 100644
index 0000000..f598dd4
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/AbstractModelObject.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.model;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+public abstract class AbstractModelObject {
+	private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
+
+	public void addPropertyChangeListener(PropertyChangeListener listener) {
+		propertyChangeSupport.addPropertyChangeListener(listener);
+	}
+
+	public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
+	}
+
+	public void removePropertyChangeListener(PropertyChangeListener listener) {
+		propertyChangeSupport.removePropertyChangeListener(listener);
+	}
+
+	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
+	}
+
+	protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+		propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
+	}
+
+	protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
+		propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
+	}
+
+	protected void firePropertyChange(String propertyName, int oldValue, int newValue) {
+		propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
+	}
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntry.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntry.java
new file mode 100644
index 0000000..751a48f
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntry.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.model;
+
+public class PreferenceEntry extends AbstractModelObject {
+
+	public enum Fields {
+		nodePath, key, oldValue, newValue;
+	}
+
+	private PreferenceEntry parent;
+
+	private boolean recentlyChanged;
+
+	private String nodePath;
+
+	private String key;
+
+	private String oldValue;
+
+	private String newValue;
+
+	private long time;
+
+	public PreferenceEntry() {
+	}
+
+	public PreferenceEntry(String nodePath, String key) {
+		this.nodePath = nodePath;
+		this.key = key;
+	}
+
+	public PreferenceEntry(String nodePath, String key, String oldValue, String newValue) {
+		this.nodePath = nodePath;
+		this.key = key;
+		this.oldValue = oldValue;
+		this.newValue = newValue;
+	}
+
+	public PreferenceEntry(PreferenceEntry parent, String nodePath, String key, String oldValue, String newValue) {
+		this.nodePath = nodePath;
+		this.key = key;
+		this.oldValue = oldValue;
+		this.newValue = newValue;
+	}
+
+	public PreferenceEntry getParent() {
+		return parent;
+	}
+
+	public void setParent(PreferenceEntry parent) {
+		firePropertyChange("parent", this.parent, this.parent = parent);
+	}
+
+	public String getNodePath() {
+		return nodePath;
+	}
+
+	public void setNodePath(String nodePath) {
+		firePropertyChange("nodePath", this.nodePath, this.nodePath = nodePath);
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		firePropertyChange("key", this.key, this.key = key);
+	}
+
+	public String getOldValue() {
+		return oldValue;
+	}
+
+	public void setOldValue(String oldValue) {
+		firePropertyChange("oldValue", this.oldValue, this.oldValue = oldValue);
+	}
+
+	public String getNewValue() {
+		return newValue;
+	}
+
+	public void setNewValue(String newValue) {
+		firePropertyChange("newValue", this.newValue, this.newValue = newValue);
+	}
+
+	public boolean isRecentlyChanged() {
+		return recentlyChanged;
+	}
+
+	public void setRecentlyChanged(boolean recentlyChanged) {
+		firePropertyChange("recentlyChanged", this.recentlyChanged, this.recentlyChanged = recentlyChanged);
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((key == null) ? 0 : key.hashCode());
+		result = prime * result + ((newValue == null) ? 0 : newValue.hashCode());
+		result = prime * result + ((nodePath == null) ? 0 : nodePath.hashCode());
+		result = prime * result + ((oldValue == null) ? 0 : oldValue.hashCode());
+		result = prime * result + ((parent == null) ? 0 : parent.hashCode());
+		result = prime * result + (recentlyChanged ? 1231 : 1237);
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		PreferenceEntry other = (PreferenceEntry) obj;
+		if (key == null) {
+			if (other.key != null) {
+				return false;
+			}
+		} else if (!key.equals(other.key)) {
+			return false;
+		}
+		if (newValue == null) {
+			if (other.newValue != null) {
+				return false;
+			}
+		} else if (!newValue.equals(other.newValue)) {
+			return false;
+		}
+		if (nodePath == null) {
+			if (other.nodePath != null) {
+				return false;
+			}
+		} else if (!nodePath.equals(other.nodePath)) {
+			return false;
+		}
+		if (oldValue == null) {
+			if (other.oldValue != null) {
+				return false;
+			}
+		} else if (!oldValue.equals(other.oldValue)) {
+			return false;
+		}
+		if (parent == null) {
+			if (other.parent != null) {
+				return false;
+			}
+		} else if (!parent.equals(other.parent)) {
+			return false;
+		}
+		if (recentlyChanged != other.recentlyChanged) {
+			return false;
+		}
+		return true;
+	}
+
+	public long getTime() {
+		return time;
+	}
+
+	public void setTime(long time) {
+		this.time = time;
+	}
+
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntryManager.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntryManager.java
new file mode 100644
index 0000000..c388c62
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntryManager.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PreferenceEntryManager extends PreferenceNodeEntry {
+
+	private Map<String, PreferenceNodeEntry> recentPreferenceEntries = new HashMap<String, PreferenceNodeEntry>();
+
+	public PreferenceEntryManager() {
+	}
+
+	public PreferenceNodeEntry getRecentPreferenceNodeEntry(String nodePath) {
+		return recentPreferenceEntries.get(nodePath);
+	}
+
+	public PreferenceNodeEntry removeRecentPreferenceNodeEntry(String nodePath) {
+		return recentPreferenceEntries.remove(nodePath);
+	}
+
+	public void clearRecentPreferenceNodeEntry() {
+		recentPreferenceEntries.clear();
+	}
+
+	public void putRecentPreferenceEntry(String nodePath, PreferenceNodeEntry preferenceNodeEntry) {
+		recentPreferenceEntries.put(nodePath, preferenceNodeEntry);
+	}
+
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntryPatternFilter.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntryPatternFilter.java
new file mode 100644
index 0000000..00c62a7
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceEntryPatternFilter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.model;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+public class PreferenceEntryPatternFilter extends PatternFilter {
+
+	public PreferenceEntryPatternFilter() {
+		super();
+	}
+
+	@Override
+	protected boolean isLeafMatch(Viewer viewer, Object element) {
+
+		if (element instanceof PreferenceEntry) {
+			PreferenceEntry preferenceEntry = (PreferenceEntry) element;
+			if (wordMatches(preferenceEntry.getNodePath()) || wordMatches(preferenceEntry.getKey())
+					|| wordMatches(preferenceEntry.getOldValue()) || wordMatches(preferenceEntry.getNewValue())) {
+				return true;
+			}
+		}
+
+		return super.isLeafMatch(viewer, element);
+	}
+
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceNodeEntry.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceNodeEntry.java
new file mode 100644
index 0000000..9d12510
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/model/PreferenceNodeEntry.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.observable.set.WritableSet;
+
+public class PreferenceNodeEntry extends PreferenceEntry {
+
+	private IObservableSet<Object> preferenceEntries = new WritableSet<>();
+
+	public PreferenceNodeEntry() {
+		super();
+	}
+
+	public PreferenceNodeEntry(String nodePath) {
+		super(nodePath, "", "", "");
+	}
+
+	public void addChildren(Collection<PreferenceEntry> entries) {
+		getPreferenceEntries().addAll(entries);
+	}
+
+	public boolean addChildren(PreferenceEntry... entry) {
+		return getPreferenceEntries().addAll(Arrays.asList(entry));
+	}
+
+	public void removeChildren(Collection<PreferenceEntry> entries) {
+		getPreferenceEntries().removeAll(entries);
+	}
+
+	public void removeChildren(PreferenceEntry... entry) {
+		getPreferenceEntries().removeAll(Arrays.asList(entry));
+	}
+
+	public IObservableSet<Object> getPreferenceEntries() {
+		return preferenceEntries;
+	}
+
+	public void setPreferenceEntries(IObservableSet<Object> preferenceEntries) {
+		this.preferenceEntries = preferenceEntries;
+	}
+
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/parts/PreferenceSpyPart.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/parts/PreferenceSpyPart.java
new file mode 100644
index 0000000..a6eafbf
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/parts/PreferenceSpyPart.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.parts;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.eclipse.core.databinding.beans.typed.BeanProperties;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.property.Properties;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.di.extensions.Preference;
+import org.eclipse.e4.ui.di.UIEventTopic;
+import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.jface.databinding.swt.DisplayRealm;
+import org.eclipse.jface.resource.FontDescriptor;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.pde.spy.preferences.constants.PreferenceConstants;
+import org.eclipse.pde.spy.preferences.constants.PreferenceSpyEventTopics;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry.Fields;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntryManager;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntryPatternFilter;
+import org.eclipse.pde.spy.preferences.model.PreferenceNodeEntry;
+import org.eclipse.pde.spy.preferences.viewer.PreferenceEntriesContentProvider;
+import org.eclipse.pde.spy.preferences.viewer.PreferenceEntryViewerComparator;
+import org.eclipse.pde.spy.preferences.viewer.PreferenceMapLabelProvider;
+import org.eclipse.pde.spy.preferences.viewer.PreferenceSpyEditingSupport;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.dialogs.FilteredTree;
+
+public class PreferenceSpyPart {
+
+	private FilteredTree filteredTree;
+	private boolean hierarchicalLayoutPreference;
+	private PreferenceEntryManager preferenceEntryManager;
+
+	@SuppressWarnings("unchecked")
+	@PostConstruct
+	public void postConstruct(Composite parent, final ESelectionService selectionService, EModelService modelService,
+			MWindow window) {
+
+		preferenceEntryManager = new PreferenceEntryManager();
+
+		PreferenceEntryPatternFilter patternFilter = new PreferenceEntryPatternFilter();
+		patternFilter.setIncludeLeadingWildcard(true);
+		filteredTree = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, patternFilter,
+				true, true);
+
+		Tree table = filteredTree.getViewer().getTree();
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+
+		filteredTree.getViewer().addSelectionChangedListener(new ISelectionChangedListener() {
+
+			@Override
+			public void selectionChanged(SelectionChangedEvent event) {
+				ISelection selection = event.getSelection();
+				if (selection instanceof IStructuredSelection) {
+					ArrayList<PreferenceEntry> preferenceEntries = new ArrayList<PreferenceEntry>(
+							((IStructuredSelection) selection).toList());
+					selectionService.setSelection(preferenceEntries);
+				}
+			}
+		});
+
+		createColumn(Fields.nodePath, "Nodepath", 300);
+		createColumn(Fields.key, "Key", 300);
+		createColumn(Fields.oldValue, "Old Value", 150);
+		createColumn(Fields.newValue, "New Value", 150);
+
+		filteredTree.getViewer().setComparator(new PreferenceEntryViewerComparator());
+
+		FontDescriptor fontDescriptor = getBoldFontDescriptor();
+
+		Realm realm = DisplayRealm.getRealm(filteredTree.getViewer().getControl().getDisplay());
+		PreferenceEntriesContentProvider contentProvider = new PreferenceEntriesContentProvider(
+				BeanProperties.set("preferenceEntries", PreferenceNodeEntry.class).setFactory(realm), null);
+		contentProvider.setHierarchicalLayout(hierarchicalLayoutPreference);
+		filteredTree.getViewer().setContentProvider(contentProvider);
+		filteredTree.getViewer().setLabelProvider(new PreferenceMapLabelProvider(fontDescriptor,
+				Properties.observeEach(contentProvider.getKnownElements(), BeanProperties.values(PreferenceEntry.class, "nodePath", "key", "oldValue", "newValue"))));
+		filteredTree.getViewer().setInput(preferenceEntryManager);
+	}
+
+	private FontDescriptor getBoldFontDescriptor() {
+		Font origFont = filteredTree.getViewer().getControl().getFont();
+		FontDescriptor fontDescriptor = FontDescriptor.createFrom(origFont);
+		return fontDescriptor.setStyle(SWT.BOLD);
+	}
+
+	private void createColumn(Fields field, String columnName, int width) {
+		TreeViewerColumn viewerColumn = new TreeViewerColumn(filteredTree.getViewer(), SWT.NONE);
+		viewerColumn.getColumn().setWidth(width);
+		viewerColumn.getColumn().setText(columnName);
+
+		viewerColumn.setLabelProvider(new ColumnLabelProvider());
+		viewerColumn.setEditingSupport(new PreferenceSpyEditingSupport(filteredTree.getViewer(), field));
+	}
+
+	@Inject
+	public void layoutChanged(
+			@Preference(value = PreferenceConstants.HIERARCHICAL_LAYOUT) boolean hierarchicalLayoutPreference) {
+		this.hierarchicalLayoutPreference = hierarchicalLayoutPreference;
+		if (filteredTree != null && !filteredTree.getViewer().getControl().isDisposed()) {
+			PreferenceEntriesContentProvider contentProvider = (PreferenceEntriesContentProvider) filteredTree
+					.getViewer().getContentProvider();
+			contentProvider.setHierarchicalLayout(hierarchicalLayoutPreference);
+			filteredTree.getViewer().refresh();
+		}
+	}
+
+	@Inject
+	@Optional
+	public void preferenceChanged(
+			@UIEventTopic(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_CHANGED) PreferenceChangeEvent event) {
+
+		PreferenceNodeEntry preferenceNodeEntry = preferenceEntryManager
+				.getRecentPreferenceNodeEntry(event.getNode().absolutePath());
+		PreferenceEntry preferenceEntry = new PreferenceEntry(event.getNode().absolutePath(), event.getKey());
+		preferenceEntry.setRecentlyChanged(true);
+		if (null == preferenceNodeEntry) {
+			preferenceNodeEntry = new PreferenceNodeEntry(event.getNode().absolutePath());
+			preferenceNodeEntry.setRecentlyChanged(true);
+			preferenceNodeEntry.addChildren(preferenceEntry);
+			preferenceEntry.setParent(preferenceNodeEntry);
+			preferenceEntryManager.addChildren(preferenceNodeEntry);
+			filteredTree.getViewer().setInput(preferenceEntryManager);
+			preferenceEntryManager.putRecentPreferenceEntry(event.getNode().absolutePath(), preferenceNodeEntry);
+		} else {
+			preferenceEntry.setParent(preferenceNodeEntry);
+			PreferenceEntry existingPreferenceEntry = findPreferenceEntry(preferenceEntry);
+			if (existingPreferenceEntry != null) {
+				preferenceEntry = existingPreferenceEntry;
+			} else {
+				preferenceNodeEntry.addChildren(preferenceEntry);
+			}
+		}
+
+		preferenceEntry.setOldValue(String.valueOf(event.getOldValue()));
+		preferenceEntry.setNewValue(String.valueOf(event.getNewValue()));
+		long currentTimeMillis = System.currentTimeMillis();
+		preferenceEntry.setTime(currentTimeMillis);
+		preferenceEntry.getParent().setTime(currentTimeMillis);
+
+		filteredTree.getViewer().refresh();
+	}
+
+	private PreferenceEntry findPreferenceEntry(PreferenceEntry preferenceEntry) {
+		PreferenceEntry parent = preferenceEntry.getParent();
+		if (parent instanceof PreferenceNodeEntry) {
+			IObservableSet<?> preferenceEntries = ((PreferenceNodeEntry) parent).getPreferenceEntries();
+			for (Object object : preferenceEntries) {
+				if (object instanceof PreferenceEntry) {
+					PreferenceEntry existingPreferenceEntry = (PreferenceEntry) object;
+					if (existingPreferenceEntry.getKey().equals(preferenceEntry.getKey())) {
+						return existingPreferenceEntry;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Inject
+	@Optional
+	public void preferenceChanged(
+			@UIEventTopic(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_SHOW) Collection<PreferenceEntry> preferenceEntries) {
+		preferenceEntryManager.addChildren(preferenceEntries);
+		filteredTree.getViewer().refresh();
+	}
+
+	@Inject
+	@Optional
+	public void DeletePreferenceEntries(
+			@UIEventTopic(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_ENTRIES_DELETE) List<PreferenceEntry> preferenceEntries) {
+		if (preferenceEntries != null && !preferenceEntries.isEmpty()) {
+			for (PreferenceEntry preferenceEntry : preferenceEntries) {
+				preferenceEntryManager.removeChildren(preferenceEntry);
+			}
+			preferenceEntryManager.removeChildren(preferenceEntries);
+			filteredTree.getViewer().refresh();
+		}
+	}
+
+	@Inject
+	@Optional
+	public void DeleteAllPreferenceEntries(
+			@UIEventTopic(PreferenceSpyEventTopics.PREFERENCESPY_PREFERENCE_ENTRIES_DELETE_ALL) List<PreferenceEntry> preferenceEntries) {
+		if (preferenceEntryManager != null) {
+			preferenceEntryManager.clearRecentPreferenceNodeEntry();
+			preferenceEntryManager.getPreferenceEntries().clear();
+			filteredTree.getViewer().refresh();
+		}
+	}
+
+	public TreeViewer getViewer() {
+		return filteredTree.getViewer();
+	}
+
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/preferencepage/TracePreferencePage.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/preferencepage/TracePreferencePage.java
new file mode 100644
index 0000000..9c513b0
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/preferencepage/TracePreferencePage.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.preferencepage;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.pde.spy.preferences.PreferenceSpyConfiguration;
+import org.eclipse.pde.spy.preferences.constants.PreferenceConstants;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class TracePreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+
+	public TracePreferencePage() {
+		super(GRID);
+		setPreferenceStore(PreferenceSpyConfiguration.getPreferenceStore());
+		setDescription("Settings for the preference spy");
+	}
+
+	/**
+	 * Creates the field editors
+	 */
+	@Override
+	public void createFieldEditors() {
+		addField(new BooleanFieldEditor(PreferenceConstants.TRACE_PREFERENCES, "&Trace preference values ",
+				getFieldEditorParent()));
+		addField(new BooleanFieldEditor(PreferenceConstants.HIERARCHICAL_LAYOUT, "&Use hierarchical layout in the tree",
+				getFieldEditorParent()));
+	}
+
+	@Override
+	public void init(IWorkbench workbench) {
+	}
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceEntriesContentProvider.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceEntriesContentProvider.java
new file mode 100644
index 0000000..9c1806a
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceEntriesContentProvider.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.viewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.jface.databinding.viewers.ObservableSetTreeContentProvider;
+import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+import org.eclipse.pde.spy.preferences.model.PreferenceNodeEntry;
+
+@SuppressWarnings("rawtypes")
+public class PreferenceEntriesContentProvider extends ObservableSetTreeContentProvider {
+
+	private boolean hierarchicalLayout;
+
+	@SuppressWarnings("unchecked")
+	public PreferenceEntriesContentProvider(IObservableFactory setFactory, TreeStructureAdvisor structureAdvisor) {
+		super(setFactory, structureAdvisor);
+	}
+
+	@Override
+	public Object[] getElements(Object inputElement) {
+		Object[] children = super.getElements(inputElement);
+		if (isHierarchicalLayout()) {
+			return children;
+		}
+
+		List<PreferenceEntry> childList = new ArrayList<PreferenceEntry>();
+
+		for (Object object : children) {
+			getChildren(object, childList);
+		}
+
+		return childList.toArray();
+	}
+
+	private void getChildren(Object element, List<PreferenceEntry> childList) {
+		if (element instanceof PreferenceNodeEntry) {
+			IObservableSet preferenceEntries = ((PreferenceNodeEntry) element).getPreferenceEntries();
+			for (Object object : preferenceEntries) {
+				getChildren(object, childList);
+			}
+		} else if (element instanceof PreferenceEntry) {
+			childList.add((PreferenceEntry) element);
+		}
+	}
+
+	public boolean isHierarchicalLayout() {
+		return hierarchicalLayout;
+	}
+
+	public void setHierarchicalLayout(boolean hierarchicalLayout) {
+		this.hierarchicalLayout = hierarchicalLayout;
+	}
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceEntryViewerComparator.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceEntryViewerComparator.java
new file mode 100644
index 0000000..5c2b555
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceEntryViewerComparator.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.viewer;
+
+import java.util.Comparator;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+
+public class PreferenceEntryViewerComparator extends ViewerComparator {
+
+	public PreferenceEntryViewerComparator() {
+	}
+
+	public PreferenceEntryViewerComparator(Comparator<? super String> comparator) {
+		super(comparator);
+	}
+
+	@Override
+	public int compare(Viewer viewer, Object e1, Object e2) {
+		if (e1 instanceof PreferenceEntry && e2 instanceof PreferenceEntry) {
+			PreferenceEntry entry1 = (PreferenceEntry) e1;
+			PreferenceEntry entry2 = (PreferenceEntry) e2;
+
+			long time = entry1.getTime();
+			long time2 = entry2.getTime();
+
+			if (time != 0 && time2 != 0) {
+				return (int) (time2 - time);
+			}
+		}
+
+		return super.compare(viewer, e1, e2);
+	}
+
+	@Override
+	public int category(Object element) {
+		if (element instanceof PreferenceEntry) {
+			return ((PreferenceEntry) element).isRecentlyChanged() ? 0 : 1;
+		}
+		return 2;
+	}
+
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceMapLabelProvider.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceMapLabelProvider.java
new file mode 100644
index 0000000..ed9cca4
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceMapLabelProvider.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.viewer;
+
+import org.eclipse.core.databinding.observable.map.IObservableMap;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
+import org.eclipse.jface.resource.FontDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.viewers.IFontProvider;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+import org.eclipse.swt.graphics.Font;
+
+public class PreferenceMapLabelProvider extends ObservableMapLabelProvider implements IFontProvider {
+
+	private LocalResourceManager resourceManager;
+	private FontDescriptor fontDescriptor;
+
+
+	public PreferenceMapLabelProvider(FontDescriptor fontDescriptor, IObservableMap<Object,Object>[] attributeMaps) {
+		super(attributeMaps);
+		Assert.isNotNull(fontDescriptor, "<fontDescriptor> must not be null");
+		this.fontDescriptor = fontDescriptor;
+	}
+
+	@Override
+	public String getColumnText(Object element, int columnIndex) {
+		String columnText = super.getColumnText(element, columnIndex);
+		if ("".equals(columnText) && element instanceof PreferenceEntry) {
+			PreferenceEntry entry = (PreferenceEntry) element;
+			switch (columnIndex) {
+			case 1:
+				columnText = entry.getKey();
+				break;
+			case 2:
+				columnText = entry.getOldValue();
+				break;
+			case 3:
+				columnText = entry.getNewValue();
+				break;
+			default:
+				columnText = entry.getNodePath();
+				break;
+			}
+		}
+		return columnText;
+	}
+
+	@Override
+	public Font getFont(Object element) {
+		if (element instanceof PreferenceEntry && ((PreferenceEntry) element).isRecentlyChanged()) {
+			return getResourceManager().createFont(fontDescriptor);
+		}
+		return null;
+	}
+
+	@Override
+	public void dispose() {
+		super.dispose();
+		if (resourceManager != null) {
+			resourceManager.dispose();
+		}
+	}
+
+	protected ResourceManager getResourceManager() {
+		if (null == resourceManager) {
+			resourceManager = new LocalResourceManager(JFaceResources.getResources());
+		}
+		return resourceManager;
+	}
+}
diff --git a/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceSpyEditingSupport.java b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceSpyEditingSupport.java
new file mode 100644
index 0000000..5dba4e4
--- /dev/null
+++ b/ui/org.eclipse.pde.spy.preferences/src/org/eclipse/pde/spy/preferences/viewer/PreferenceSpyEditingSupport.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2015 vogella GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.spy.preferences.viewer;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry;
+import org.eclipse.pde.spy.preferences.model.PreferenceEntry.Fields;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+public class PreferenceSpyEditingSupport extends EditingSupport {
+
+	private Fields field;
+
+	public PreferenceSpyEditingSupport(ColumnViewer viewer, Fields field) {
+		super(viewer);
+		this.field = field;
+	}
+
+	@Override
+	protected CellEditor getCellEditor(Object element) {
+		return new TextCellEditor((Composite) getViewer().getControl(), SWT.READ_ONLY);
+	}
+
+	@Override
+	protected boolean canEdit(Object element) {
+		return true;
+	}
+
+	@Override
+	protected Object getValue(Object element) {
+		String value = null;
+		if (element instanceof PreferenceEntry) {
+			PreferenceEntry preferenceEntry = (PreferenceEntry) element;
+			switch (field) {
+			case nodePath:
+				value = preferenceEntry.getNodePath();
+				break;
+			case key:
+				value = preferenceEntry.getKey();
+				break;
+			case oldValue:
+				value = preferenceEntry.getOldValue();
+				break;
+			case newValue:
+				value = preferenceEntry.getNewValue();
+				break;
+			default:
+				break;
+			}
+		}
+
+		return value;
+	}
+
+	@Override
+	protected void setValue(Object element, Object value) {
+	}
+
+}