Cleaning up preference pages.
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference_Test.java
index 5f54bba..12483d6 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference_Test.java
@@ -34,23 +34,23 @@
 
   @Test public void should_read_value_from_IPreferenceStore() {
     when(store.getBoolean(name)).thenReturn(true);
-    assertTrue(preference.value());
+    assertTrue(preference.getValue());
     verify(store).getBoolean(name);
   }
 
   @Test public void should_read_default_value_from_IPreferenceStore() {
     when(store.getDefaultBoolean(name)).thenReturn(true);
-    assertTrue(preference.defaultValue());
+    assertTrue(preference.getDefaultValue());
     verify(store).getDefaultBoolean(name);
   }
 
   @Test public void should_update_value_in_IPreferenceStore() {
-    preference.value(true);
+    preference.setValue(true);
     verify(store).setValue(name, true);
   }
 
   @Test public void should_update_default_value_in_IPreferenceStore() {
-    preference.defaultValue(true);
+    preference.setDefaultValue(true);
     verify(store).setDefault(name, true);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/Buttons_add_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/Buttons_add_Test.java
index f29ca4f..0d3cd8a 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/Buttons_add_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/Buttons_add_Test.java
@@ -14,8 +14,10 @@
 import org.eclipse.swt.widgets.Button;
 import org.junit.*;
 
+import com.google.eclipse.protobuf.ui.preferences.pages.ButtonGroup;
+
 /**
- * Tests for <code>{@link Buttons#add(SelectionListener)}</code>.
+ * Tests for <code>{@link ButtonGroup#add(SelectionListener)}</code>.
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
@@ -30,7 +32,7 @@
   }
 
   @Test public void should_add_SelectionListener_to_all_buttons() {
-    Buttons.with(buttons).add(listener);
+    ButtonGroup.with(buttons).add(listener);
     for (Button b : buttons) {
       verify(b).addSelectionListener(listener);
     }
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection_Test.java
index cffb1fb..dc3f226 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection_Test.java
@@ -8,13 +8,14 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.binding;
 
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToButtonSelection.bindSelectionOf;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 import static org.mockito.Mockito.*;
 
 import org.eclipse.swt.widgets.Button;
 import org.junit.*;
 
 import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection;
 
 /**
  * Tests for <code>{@link BindingToButtonSelection}</code>.
@@ -35,16 +36,16 @@
   }
 
   @Test public void should_apply_preference_value_to_selection_in_Button() {
-    when(preference.value()).thenReturn(true);
+    when(preference.getValue()).thenReturn(true);
     binding.applyPreferenceValueToTarget();
-    verify(preference).value();
+    verify(preference).getValue();
     verify(button).setSelection(true);
   }
 
   @Test public void should_apply_preference_default_value_to_selection_in_Button() {
-    when(preference.defaultValue()).thenReturn(true);
+    when(preference.getDefaultValue()).thenReturn(true);
     binding.applyDefaultPreferenceValueToTarget();
-    verify(preference).defaultValue();
+    verify(preference).getDefaultValue();
     verify(button).setSelection(true);
   }
 
@@ -52,6 +53,6 @@
     when(button.getSelection()).thenReturn(true);
     binding.savePreferenceValue();
     verify(button).getSelection();
-    verify(preference).value(true);
+    verify(preference).setValue(true);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems_Test.java
index ba57ad9..8eef4ed 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems_Test.java
@@ -8,7 +8,7 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.binding;
 
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToListItems.bindItemsOf;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToListItems.bindItemsOf;
 import static java.util.Arrays.asList;
 import static org.mockito.Mockito.*;
 
@@ -16,6 +16,7 @@
 import org.junit.*;
 
 import com.google.eclipse.protobuf.ui.preferences.StringListPreference;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToListItems;
 
 /**
  * Tests for <code>{@link BindingToListItems}</code>.
@@ -36,18 +37,18 @@
   }
 
   @Test public void should_apply_preference_value_to_selection_in_Button() {
-    when(preference.value()).thenReturn(asList("One" , "Two"));
+    when(preference.getValue()).thenReturn(asList("One" , "Two"));
     binding.applyPreferenceValueToTarget();
-    verify(preference).value();
+    verify(preference).getValue();
     verify(list).removeAll();
     verify(list).add("One");
     verify(list).add("Two");
   }
 
   @Test public void should_apply_preference_default_value_to_selection_in_Button() {
-    when(preference.defaultValue()).thenReturn(asList("One" , "Two"));
+    when(preference.getDefaultValue()).thenReturn(asList("One" , "Two"));
     binding.applyDefaultPreferenceValueToTarget();
-    verify(preference).defaultValue();
+    verify(preference).getDefaultValue();
     verify(list).removeAll();
     verify(list).add("One");
     verify(list).add("Two");
@@ -57,6 +58,6 @@
     when(list.getItems()).thenReturn(new String[] { "One", "Two" });
     binding.savePreferenceValue();
     verify(list).getItems();
-    verify(preference).value(asList("One" , "Two"));
+    verify(preference).setValue(asList("One" , "Two"));
   }
 }
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue_Test.java
index ce8367d..c7782e7 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue_Test.java
@@ -8,13 +8,14 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.binding;
 
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToTextValue.bindTextOf;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToTextValue.bindTextOf;
 import static org.mockito.Mockito.*;
 
 import org.eclipse.swt.widgets.Text;
 import org.junit.*;
 
 import com.google.eclipse.protobuf.ui.preferences.StringPreference;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToTextValue;
 
 /**
  * Tests for <code>{@link BindingToTextValue}</code>.
@@ -35,16 +36,16 @@
   }
 
   @Test public void should_apply_preference_value_to_selection_in_Button() {
-    when(preference.value()).thenReturn("Hello World");
+    when(preference.getValue()).thenReturn("Hello World");
     binding.applyPreferenceValueToTarget();
-    verify(preference).value();
+    verify(preference).getValue();
     verify(text).setText("Hello World");
   }
 
   @Test public void should_apply_preference_default_value_to_selection_in_Button() {
-    when(preference.defaultValue()).thenReturn("Hello World");
+    when(preference.getDefaultValue()).thenReturn("Hello World");
     binding.applyDefaultPreferenceValueToTarget();
-    verify(preference).defaultValue();
+    verify(preference).getDefaultValue();
     verify(text).setText("Hello World");
   }
 
@@ -52,6 +53,6 @@
     when(text.getText()).thenReturn("Hello World");
     binding.savePreferenceValue();
     verify(text).getText();
-    verify(preference).value("Hello World");
+    verify(preference).setValue("Hello World");
   }
 }
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder_Test.java
index 7456a41..1765cd2 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder_Test.java
@@ -12,6 +12,8 @@
 
 import org.junit.*;
 
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
+
 /**
  * Tests for <code>{@link PreferenceBinder}</code>.
  *
diff --git a/com.google.eclipse.protobuf.ui/plugin.xml b/com.google.eclipse.protobuf.ui/plugin.xml
index c46e8aa..ffe8025 100644
--- a/com.google.eclipse.protobuf.ui/plugin.xml
+++ b/com.google.eclipse.protobuf.ui/plugin.xml
@@ -53,7 +53,7 @@
   </extension>
   <extension point="org.eclipse.ui.preferencePages">
     <page
-      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.pages.general.GeneralPreferencePage"
+      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.general.page.GeneralPreferencePage"
       id="com.google.eclipse.protobuf.Protobuf"
       name="%page.name">
       <keywordReference id="com.google.eclipse.protobuf.ui.keyword_Protobuf" />
@@ -67,29 +67,29 @@
     </page>
     <page
       category="com.google.eclipse.protobuf.Protobuf"
-      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.pages.compiler.CompilerPreferencePage"
-      id="com.google.eclipse.protobuf.ui.preferences.pages.compiler.CompilerPreferencePage"
+      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.compiler.page.CompilerPreferencePage"
+      id="com.google.eclipse.protobuf.ui.preferences.compiler.page.CompilerPreferencePage"
       name="%page.name.2">
       <keywordReference id="com.google.eclipse.protobuf.ui.keyword_Protobuf" />
     </page>
     <page
       category="com.google.eclipse.protobuf.Protobuf"
-      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.pages.editor.EditorPreferencePage"
-      id="com.google.eclipse.protobuf.ui.preferences.pages.editor"
+      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.editor.general.page.EditorPreferencePage"
+      id="com.google.eclipse.protobuf.ui.preferences.editor.general.page.EditorPreferencePage"
       name="%page.name.4">
       <keywordReference id="com.google.eclipse.protobuf.ui.keyword_Protobuf" />
     </page>
     <page
       category="com.google.eclipse.protobuf.ui.preferences.pages.editor"
-      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferencePage"
-      id="com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferencePage"
+      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.editor.save.page.SaveActionsPreferencePage"
+      id="com.google.eclipse.protobuf.ui.preferences.editor.save.page.SaveActionsPreferencePage"
       name="%page.name.5">
       <keywordReference id="com.google.eclipse.protobuf.ui.keyword_Protobuf" />
     </page>
     <page
       category="com.google.eclipse.protobuf.ui.preferences.pages.editor"
-      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.NumericTagPreferencePage"
-      id="com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.NumericTagPreferencePage"
+      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page.NumericTagPreferencePage"
+      id="com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page.NumericTagPreferencePage"
       name="%page.name.6">
       <keywordReference id="com.google.eclipse.protobuf.ui.keyword_Protobuf" />
     </page>
@@ -227,7 +227,7 @@
     </page>
     <page
       category="com.google.eclipse.protobuf.Protobuf"
-      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.pages.compiler.CompilerPreferencePage"
+      class="com.google.eclipse.protobuf.ui.ProtobufExecutableExtensionFactory:com.google.eclipse.protobuf.ui.preferences.compiler.page.CompilerPreferencePage"
       id="com.google.eclipse.protobuf.ui.properties.compiler.PropertyPage"
       name="%page.name.2"
       selectionFilter="single">
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
index 1ad4743..7de4f38 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
@@ -37,10 +37,10 @@
 import com.google.eclipse.protobuf.ui.internal.ProtobufActivator;
 import com.google.eclipse.protobuf.ui.outline.*;
 import com.google.eclipse.protobuf.ui.preferences.PreferenceStoreAccess;
-import com.google.eclipse.protobuf.ui.preferences.pages.compiler.CompilerPreferenceStoreInitializer;
-import com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.NumericTagPreferenceStoreInitializer;
-import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferenceStoreInitializer;
-import com.google.eclipse.protobuf.ui.preferences.pages.general.GeneralPreferenceStoreInitializer;
+import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferenceStoreInitializer;
+import com.google.eclipse.protobuf.ui.preferences.editor.numerictag.core.NumericTagPreferenceStoreInitializer;
+import com.google.eclipse.protobuf.ui.preferences.editor.save.core.SaveActionsPreferenceStoreInitializer;
+import com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferenceStoreInitializer;
 import com.google.eclipse.protobuf.ui.preferences.pages.paths.PathsPreferenceStoreInitializer;
 import com.google.eclipse.protobuf.ui.quickfix.ProtobufQuickAssistProcessor;
 import com.google.eclipse.protobuf.ui.scoping.FileUriResolver;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectories.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectories.java
index 3968f54..5956e75 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectories.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectories.java
@@ -8,65 +8,36 @@
  */
 package com.google.eclipse.protobuf.ui.builder.protoc;
 
-import static com.google.eclipse.protobuf.ui.util.Paths.segmentsOf;
-import static java.io.File.separator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
 
-import java.util.*;
-
-import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.*;
-
-import com.google.eclipse.protobuf.ui.preferences.pages.compiler.*;
+import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
 class OutputDirectories {
 
-  private static final NullProgressMonitor NO_MONITOR = new NullProgressMonitor();
+  private final OutputDirectory java;
+  private final OutputDirectory cpp;
+  private final OutputDirectory python;
 
-  private final Map<SupportedLanguage, IFolder> outputDirectories = new HashMap<SupportedLanguage, IFolder>();
-
-  static OutputDirectories findOrCreateOutputDirectories(IProject project, CodeGenerationSettings preferences)
-      throws CoreException {
-    Map<SupportedLanguage, IFolder> outputDirectories = new HashMap<SupportedLanguage, IFolder>();
-    for (CodeGenerationSetting preference : preferences.allSettings()) {
-      if (!preference.isEnabled()) {
-        continue;
-      }
-      outputDirectories.put(preference.language(), findOrCreateOutputDirectory(project, preference));
-    }
-    return new OutputDirectories(outputDirectories);
+  OutputDirectories(IProject project, CompilerPreferences preferences) throws CoreException {
+    java = new OutputDirectory(project, preferences.javaCodeGenerationEnabled(), preferences.javaOutputDirectory());
+    cpp = new OutputDirectory(project, preferences.cppCodeGenerationEnabled(), preferences.cppOutputDirectory());
+    python = new OutputDirectory(project, preferences.pythonCodeGenerationEnabled(),
+        preferences.pythonOutputDirectory());
   }
 
-  private static IFolder findOrCreateOutputDirectory(IProject project, CodeGenerationSetting preference)
-      throws CoreException {
-    return findOrCreateOutputDirectory(project, preference.outputDirectory());
+  OutputDirectory java() {
+    return java;
   }
 
-  private static IFolder findOrCreateOutputDirectory(IProject project, String outputFolderName) throws CoreException {
-    IFolder outputFolder = null;
-    StringBuilder path = new StringBuilder();
-    for (String segment : segmentsOf(outputFolderName)) {
-      path.append(segment);
-      outputFolder = project.getFolder(path.toString());
-      if (!outputFolder.exists()) {
-        outputFolder.create(true, true, NO_MONITOR);
-      }
-      path.append(separator);
-    }
-    return outputFolder;
+  OutputDirectory cpp() {
+    return cpp;
   }
 
-  private OutputDirectories(Map<SupportedLanguage, IFolder> outputDirectories) {
-    this.outputDirectories.putAll(outputDirectories);
-  }
-
-  Collection<IFolder> values() {
-    return outputDirectories.values();
-  }
-
-  IFolder outputDirectoryFor(SupportedLanguage language) {
-    return outputDirectories.get(language);
+  OutputDirectory python() {
+    return python;
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectory.java
new file mode 100644
index 0000000..67cbaf6
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.builder.protoc;
+
+import static com.google.eclipse.protobuf.ui.util.Paths.segmentsOf;
+import static java.io.File.separator;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import com.google.eclipse.protobuf.ui.preferences.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class OutputDirectory {
+  private static final NullProgressMonitor NO_MONITOR = new NullProgressMonitor();
+
+  private final boolean enabled;
+  private final IFolder location;
+
+  OutputDirectory(IProject project, BooleanPreference codeGenerationEnabled, StringPreference outputDirectory)
+      throws CoreException {
+    enabled = codeGenerationEnabled.getValue();
+    location = findOrCreateLocation(project, outputDirectory.getValue());
+  }
+
+  private IFolder findOrCreateLocation(IProject project, String directoryName) throws CoreException {
+    IFolder directory = null;
+    if (enabled) {
+      StringBuilder path = new StringBuilder();
+      for (String segment : segmentsOf(directoryName)) {
+        path.append(segment);
+        directory = project.getFolder(path.toString());
+        if (!directory.exists()) {
+          directory.create(true, true, NO_MONITOR);
+        }
+        path.append(separator);
+      }
+    }
+    return directory;
+  }
+
+  boolean isEnabled() {
+    return enabled;
+  }
+
+  IFolder getLocation() {
+    return location;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtobufBuildParticipant.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtobufBuildParticipant.java
index 91f6d67..0c8e355 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtobufBuildParticipant.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtobufBuildParticipant.java
@@ -8,10 +8,10 @@
  */
 package com.google.eclipse.protobuf.ui.builder.protoc;
 
-import static com.google.eclipse.protobuf.ui.builder.protoc.OutputDirectories.findOrCreateOutputDirectories;
 import static com.google.eclipse.protobuf.ui.exception.CoreExceptions.error;
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.PostCompilationRefreshTarget.PROJECT;
+import static com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences.compilerPreferences;
 import static com.google.eclipse.protobuf.ui.preferences.pages.paths.PathResolutionType.MULTIPLE_DIRECTORIES;
+import static com.google.eclipse.protobuf.util.Closeables.closeQuietly;
 import static java.util.Collections.*;
 import static org.eclipse.core.resources.IResource.DEPTH_INFINITE;
 
@@ -24,8 +24,9 @@
 import org.eclipse.xtext.builder.IXtextBuilderParticipant;
 import org.eclipse.xtext.resource.*;
 import org.eclipse.xtext.resource.IResourceDescription.Delta;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import com.google.eclipse.protobuf.ui.preferences.pages.compiler.*;
+import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
 import com.google.eclipse.protobuf.ui.preferences.pages.paths.*;
 import com.google.inject.Inject;
 
@@ -36,7 +37,7 @@
  */
 public class ProtobufBuildParticipant implements IXtextBuilderParticipant {
 
-  @Inject private CompilerPreferencesFactory compilerPreferencesFactory;
+  @Inject private IPreferenceStoreAccess storeAccess;
   @Inject private PathsPreferencesFactory pathsPreferencesFactory;
   @Inject private ProtocCommandFactory commandFactory;
   @Inject private ProtocOutputParser outputParser;
@@ -44,15 +45,15 @@
 
   @Override public void build(IBuildContext context, IProgressMonitor monitor) throws CoreException {
     IProject project = context.getBuiltProject();
-    CompilerPreferences preferences = compilerPreferencesFactory.preferences(project);
-    if (!preferences.shouldCompileProtoFiles()) {
+    CompilerPreferences preferences = compilerPreferences(storeAccess, project);
+    if (!preferences.compileProtoFiles().getValue()) {
       return;
     }
     List<Delta> deltas = context.getDeltas();
     if (deltas.isEmpty()) {
       return;
     }
-    OutputDirectories outputDirectories = findOrCreateOutputDirectories(project, preferences.codeGenerationSettings());
+    OutputDirectories outputDirectories = new OutputDirectories(project, preferences);
     String descriptorPath = descriptorPath(preferences);
     List<String> importRoots = importRoots(project);
     for (Delta d : deltas) {
@@ -63,15 +64,16 @@
       if (importRoots.isEmpty()) {
         importRoots = singleImportRoot(source);
       }
-      generateSingleProto(source, preferences.protocPath(), importRoots, descriptorPath, outputDirectories);
+      generateSingleProto(source, protocPath(preferences), importRoots, descriptorPath, outputDirectories);
     }
-    if (preferences.shouldRefreshResources()) {
-      refresh(project, outputDirectories, preferences.refreshTarget(), monitor);
+    if (preferences.refreshResources().getValue()) {
+      boolean refreshProject = preferences.refreshProject().getValue();
+      refresh(project, outputDirectories, refreshProject, monitor);
     }
   }
 
   private String descriptorPath(CompilerPreferences preferences) {
-    return protoDescriptorPathFinder.findRootOf(preferences.descriptorPath());
+    return protoDescriptorPathFinder.findRootOf(preferences.descriptorPath().getValue());
   }
 
   private List<String> importRoots(IProject project) {
@@ -90,16 +92,16 @@
     return emptyList();
   }
 
-  private static IFile protoFile(IResourceDescription r, IProject project) {
-    String path = filePathIfIsProtoFile(r);
+  private IFile protoFile(IResourceDescription resource, IProject project) {
+    String path = filePathIfIsProtoFile(resource);
     return (path == null) ? null : project.getWorkspace().getRoot().getFile(new Path(path));
   }
 
-  private static String filePathIfIsProtoFile(IResourceDescription r) {
-    if (r == null) {
+  private String filePathIfIsProtoFile(IResourceDescription resource) {
+    if (resource == null) {
       return null;
     }
-    URI uri = r.getURI();
+    URI uri = resource.getURI();
     if (!uri.fileExtension().equals("proto"))
     {
       return null;
@@ -126,6 +128,13 @@
     return singletonList(current.toString());
   }
 
+  String protocPath(CompilerPreferences preferences) {
+    if (preferences.useProtocInSystemPath().getValue()) {
+      return "protoc";
+    }
+    return preferences.protocPath().getValue();
+  }
+
   private void generateSingleProto(IFile source, String protocPath, List<String> importRoots, String descriptorPath,
       OutputDirectories outputDirectories) throws CoreException {
     String command = commandFactory.protocCommand(source, protocPath, importRoots, descriptorPath, outputDirectories);
@@ -151,31 +160,25 @@
         System.out.println("[protoc] " + line);
       }
     } finally {
-      close(reader);
+      closeQuietly(reader);
     }
   }
 
-  private static void close(Reader reader) {
-    if (reader == null) {
+  private void refresh(IProject project, OutputDirectories outputDirectories, boolean refreshProject,
+      IProgressMonitor monitor) throws CoreException {
+    if (refreshProject) {
+      project.refreshLocal(DEPTH_INFINITE, monitor);
       return;
     }
-    try {
-      reader.close();
-    } catch (IOException ignored) {}
+    refresh(outputDirectories.java(), monitor);
+    refresh(outputDirectories.cpp(), monitor);
+    refresh(outputDirectories.python(), monitor);
   }
 
-  private static void refresh(IProject project, OutputDirectories outputDirectories,
-      PostCompilationRefreshTarget refreshTarget, IProgressMonitor monitor) throws CoreException {
-    if (refreshTarget.equals(PROJECT)) {
-      refresh(project, monitor);
-      return;
+  private void refresh(OutputDirectory directory, IProgressMonitor monitor) throws CoreException {
+    if (directory.isEnabled()) {
+      IFolder location = directory.getLocation();
+      location.refreshLocal(DEPTH_INFINITE, monitor);
     }
-    for (IFolder outputDirectory : outputDirectories.values()) {
-      refresh(outputDirectory, monitor);
-    }
-  }
-
-  private static void refresh(IResource target, IProgressMonitor monitor) throws CoreException {
-    target.refreshLocal(DEPTH_INFINITE, monitor);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocCommandFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocCommandFactory.java
index 34211c1..6ec52d2 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocCommandFactory.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocCommandFactory.java
@@ -9,27 +9,17 @@
 package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static com.google.eclipse.protobuf.util.CommonWords.space;
+import static org.eclipse.xtext.util.Strings.isEmpty;
 
-import java.util.*;
+import java.util.List;
 
 import org.eclipse.core.resources.*;
-import org.eclipse.xtext.util.Strings;
-
-import com.google.eclipse.protobuf.ui.preferences.pages.compiler.SupportedLanguage;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
 class ProtocCommandFactory {
 
-  private static final Map<SupportedLanguage, String> LANG_OUT_FLAG = new HashMap<SupportedLanguage, String>();
-
-  static {
-    for (SupportedLanguage lang : SupportedLanguage.values()) {
-      LANG_OUT_FLAG.put(lang, "--" + lang.code() + "_out=");
-    }
-  }
-
   String protocCommand(IFile protoFile, String protocPath, List<String> importRoots, String descriptorPath,
       OutputDirectories outputDirectories) {
     StringBuilder command = new StringBuilder();
@@ -37,21 +27,22 @@
     for (String importRoot : importRoots) {
       command.append("-I=").append(importRoot).append(space());
     }
-    if (!Strings.isEmpty(descriptorPath)) {
+    if (!isEmpty(descriptorPath)) {
       command.append("--proto_path=").append(descriptorPath).append(space());
     }
-    for (SupportedLanguage language : SupportedLanguage.values()) {
-      IFolder outputDirectory = outputDirectories.outputDirectoryFor(language);
-      if (outputDirectory == null) {
-        continue;
-      }
-      command.append(langOutFlag(language)).append(outputDirectory.getLocation().toOSString()).append(space());
-    }
+    addOutputDirectory(outputDirectories.java(), "java", command);
+    addOutputDirectory(outputDirectories.cpp(), "cpp", command);
+    addOutputDirectory(outputDirectories.python(), "python", command);
     command.append(protoFile.getLocation().toOSString());
     return command.toString();
   }
 
-  private String langOutFlag(SupportedLanguage targetLanguage) {
-    return LANG_OUT_FLAG.get(targetLanguage);
+  private void addOutputDirectory(OutputDirectory outputDirectory, String code, StringBuilder command) {
+    if (!outputDirectory.isEnabled()) {
+      return;
+    }
+    command.append("--").append(code).append("_out=");
+    IFolder directory = outputDirectory.getLocation();
+    command.append(directory.getLocation().toOSString()).append(space());
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
index 3857a40..2c81292 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
@@ -24,13 +24,14 @@
 import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext;
 import org.eclipse.xtext.ui.editor.contentassist.antlr.ParserBasedContentAssistContextFactory;
 import org.eclipse.xtext.ui.editor.model.IXtextDocument;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 import org.eclipse.xtext.util.Pair;
 import org.eclipse.xtext.util.concurrent.IUnitOfWork;
 
 import com.google.eclipse.protobuf.grammar.CommonKeyword;
 import com.google.eclipse.protobuf.model.util.*;
 import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.*;
+import com.google.eclipse.protobuf.ui.preferences.editor.numerictag.core.NumericTagPreferences;
 import com.google.eclipse.protobuf.ui.util.Literals;
 import com.google.inject.Inject;
 
@@ -51,8 +52,8 @@
   @Inject private IndexedElements indexedElements;
   @Inject private Literals literals;
   @Inject private INodes nodes;
-  @Inject private NumericTagPreferencesFactory preferencesFactory;
   @Inject private ParserBasedContentAssistContextFactory contextFactory;
+  @Inject private IPreferenceStoreAccess storeAccess;
 
   private static final String SEMICOLON = CommonKeyword.SEMICOLON.toString();
 
@@ -162,8 +163,8 @@
     if (parent == null) {
       return;
     }
-    NumericTagPreferences preferences = preferencesFactory.preferences();
-    for (String pattern : preferences.patterns()) {
+    NumericTagPreferences preferences = new NumericTagPreferences(storeAccess);
+    for (String pattern : preferences.patterns().getValue()) {
       Pair<INode, Matcher> match = commentNodesFinder.matchingCommentNode(parent, pattern);
       if (match == null) {
         return;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java
index 5af5872..75a1bd1 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java
@@ -10,7 +10,6 @@
 package com.google.eclipse.protobuf.ui.editor.model;
 
 import static com.google.eclipse.protobuf.ui.exception.CoreExceptions.error;
-import static com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferences.RemoveTrailingSpace.*;
 import static com.google.eclipse.protobuf.util.Encodings.UTF_8;
 import static org.eclipse.core.filebuffers.FileBuffers.getTextFileBufferManager;
 import static org.eclipse.core.filebuffers.LocationKind.*;
@@ -24,9 +23,9 @@
 import org.eclipse.text.undo.IDocumentUndoManager;
 import org.eclipse.ui.*;
 import org.eclipse.xtext.ui.editor.model.*;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.*;
-import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferences.RemoveTrailingSpace;
+import com.google.eclipse.protobuf.ui.preferences.editor.save.core.SaveActionsPreferences;
 import com.google.eclipse.protobuf.ui.util.editor.Editors;
 import com.google.inject.Inject;
 
@@ -39,7 +38,7 @@
 
   @Inject private Editors editors;
   @Inject private DocumentContentsFactoryRegistry documentContentsFactories;
-  @Inject private SaveActionsPreferencesFactory preferencesFactory;
+  @Inject private IPreferenceStoreAccess storeAccess;
   @Inject private SaveActions saveActions;
 
   @Override protected ElementInfo createElementInfo(Object element) throws CoreException {
@@ -107,13 +106,13 @@
     }
   }
 
-  private IRegion[] changedRegions(IProgressMonitor monitor, IFileEditorInput editorInput, IDocument document) throws CoreException {
-    SaveActionsPreferences preferences = preferencesFactory.preferences();
-    RemoveTrailingSpace removeTrailingSpace = preferences.removeTrailingSpace();
-    if (removeTrailingSpace.equals(NONE)) {
+  private IRegion[] changedRegions(IProgressMonitor monitor, IFileEditorInput editorInput, IDocument document)
+      throws CoreException {
+    SaveActionsPreferences preferences = new SaveActionsPreferences(storeAccess);
+    if (!preferences.removeTrailingWhitespace().getValue()) {
       return NO_CHANGE;
     }
-    if (removeTrailingSpace.equals(IN_EDITED_LINES)) {
+    if (preferences.inEditedLines().getValue()) {
       return editors.calculateChangedLineRegions(textFileBuffer(monitor, editorInput), document, monitor);
     }
     return new IRegion[] { new Region(0, document.getLength()) };
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference.java
index 099ea37..fe44f94 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference.java
@@ -27,22 +27,22 @@
   }
 
   /** {@inheritDoc} */
-  @Override public Boolean value() {
-    return store.getBoolean(name);
+  @Override public Boolean getValue() {
+    return getPreferenceStore().getBoolean(getName());
   }
 
   /** {@inheritDoc} */
-  @Override public Boolean defaultValue() {
-    return store.getDefaultBoolean(name);
+  @Override public Boolean getDefaultValue() {
+    return getPreferenceStore().getDefaultBoolean(getName());
   }
 
   /** {@inheritDoc} */
-  @Override public void value(Boolean value) {
-    store.setValue(name, value);
+  @Override public void setValue(Boolean value) {
+    getPreferenceStore().setValue(getName(), value);
   }
 
   /** {@inheritDoc} */
-  @Override public void defaultValue(Boolean value) {
-    store.setDefault(name, value);
+  @Override public void setDefaultValue(Boolean value) {
+    getPreferenceStore().setDefault(getName(), value);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Buttons.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Buttons.java
deleted file mode 100644
index dd80b83..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Buttons.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences;
-
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Button;
-
-/**
- * Utility methods related to <code>{@link Button}</code>s.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public final class Buttons {
-
-  public static Buttons with(Button...buttons) {
-    return new Buttons(buttons);
-  }
-
-  private final Button[] buttons;
-
-  private Buttons(Button[] buttons) {
-    this.buttons = buttons;
-  }
-
-  public void add(SelectionListener l) {
-    for (Button b : buttons) {
-      b.addSelectionListener(l);
-    }
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Preference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Preference.java
index 2a8cbed..18b52f2 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Preference.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Preference.java
@@ -18,8 +18,8 @@
  */
 public abstract class Preference<T> {
 
-  protected final String name;
-  protected final IPreferenceStore store;
+  private final String name;
+  private IPreferenceStore store;
 
   /**
    * Creates a new </code>{@link Preference}</code>.
@@ -28,14 +28,14 @@
    */
   public Preference(String name, IPreferenceStore store) {
     this.name = name;
-    this.store = store;
+    setPreferenceStore(store);
   }
 
   /**
    * Returns the name of this preference.
    * @return the name of this preference.
    */
-  public final String name() {
+  public String getName() {
     return name;
   }
 
@@ -43,23 +43,39 @@
    * Returns the value of this preference.
    * @return the value of this preference.
    */
-  public abstract T value();
+  public abstract T getValue();
 
   /**
    * Returns the default value of this preference.
    * @return the default value of this preference.
    */
-  public abstract T defaultValue();
+  public abstract T getDefaultValue();
 
   /**
-   * Saves the value of this preference to the given store.
-   * @param value the value to save.
+   * Sets the value of this preference to the given store.
+   * @param value the value to set.
    */
-  public abstract void value(T value);
+  public abstract void setValue(T value);
 
   /**
-   * Saves the default value of this preference to the given store.
-   * @param value the default value to save.
+   * Sets the default value of this preference to the given store.
+   * @param value the default value to set.
    */
-  public abstract void defaultValue(T value);
+  public abstract void setDefaultValue(T value);
+
+  /**
+   * Returns the table mapping named preferences to values.
+   * @return the table mapping named preferences to values.
+   */
+  public IPreferenceStore getPreferenceStore() {
+    return store;
+  }
+
+  /**
+   * Sets the table mapping named preferences to values.
+   * @param store the new table.
+   */
+  public void setPreferenceStore(IPreferenceStore store) {
+    this.store = store;
+  }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringListPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringListPreference.java
index b2a3df4..c409b9f 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringListPreference.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringListPreference.java
@@ -35,30 +35,32 @@
   }
 
   /** {@inheritDoc} */
-  @Override public List<String> value() {
-    return doSplit(store.getString(name));
+  @Override public List<String> getValue() {
+    String value = getPreferenceStore().getString(getName());
+    return splitIntoList(value);
   }
 
   /** {@inheritDoc} */
-  @Override public List<String> defaultValue() {
-    return doSplit(store.getDefaultString(name));
+  @Override public List<String> getDefaultValue() {
+    String defaultValue = getPreferenceStore().getDefaultString(getName());
+    return splitIntoList(defaultValue);
   }
 
-  private List<String> doSplit(String value) {
+  private List<String> splitIntoList(String value) {
     return split(value, delimiter);
   }
 
   /** {@inheritDoc} */
-  @Override public void value(List<String> value) {
-    store.setValue(name, doConcat(value));
+  @Override public void setValue(List<String> value) {
+    getPreferenceStore().setValue(getName(), concatenate(value));
   }
 
   /** {@inheritDoc} */
-  @Override public void defaultValue(List<String> value) {
-    store.setDefault(name, doConcat(value));
+  @Override public void setDefaultValue(List<String> value) {
+    getPreferenceStore().setDefault(getName(), concatenate(value));
   }
 
-  private String doConcat(List<String> value) {
+  private String concatenate(List<String> value) {
     return concat(delimiter, value);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringPreference.java
index d62d429..741feb5 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringPreference.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringPreference.java
@@ -27,22 +27,22 @@
   }
 
   /** {@inheritDoc} */
-  @Override public String value() {
-    return store.getString(name);
+  @Override public String getValue() {
+    return getPreferenceStore().getString(getName());
   }
 
   /** {@inheritDoc} */
-  @Override public String defaultValue() {
-    return store.getDefaultString(name);
+  @Override public String getDefaultValue() {
+    return getPreferenceStore().getDefaultString(getName());
   }
 
   /** {@inheritDoc} */
-  @Override public void value(String value) {
-    store.setValue(name, value);
+  @Override public void setValue(String value) {
+    getPreferenceStore().setValue(getName(), value);
   }
 
   /** {@inheritDoc} */
-  @Override public void defaultValue(String value) {
-    store.setDefault(name, value);
+  @Override public void setDefaultValue(String value) {
+    getPreferenceStore().setDefault(getName(), value);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferenceStoreInitializer.java
new file mode 100644
index 0000000..a56fc2d
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferenceStoreInitializer.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.compiler.core;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * Initializes default values for the "Compiler" preferences.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CompilerPreferenceStoreInitializer implements IPreferenceStoreInitializer {
+
+  private static final String DEFAULT_OUTPUT_DIRECTORY = "src-gen";
+
+  /** {@inheritDoc} */
+  @Override public void initialize(IPreferenceStoreAccess access) {
+    IPreferenceStore store = access.getWritablePreferenceStore();
+    CompilerPreferences preferences = new CompilerPreferences(store);
+    preferences.enableProjectSettings().setDefaultValue(false);
+    preferences.useProtocInSystemPath().setDefaultValue(true);
+    preferences.javaCodeGenerationEnabled().setDefaultValue(false);
+    preferences.cppCodeGenerationEnabled().setDefaultValue(false);
+    preferences.pythonCodeGenerationEnabled().setDefaultValue(false);
+    preferences.javaOutputDirectory().setDefaultValue(DEFAULT_OUTPUT_DIRECTORY);
+    preferences.cppOutputDirectory().setDefaultValue(DEFAULT_OUTPUT_DIRECTORY);
+    preferences.pythonOutputDirectory().setDefaultValue(DEFAULT_OUTPUT_DIRECTORY);
+    preferences.refreshResources().setDefaultValue(true);
+    preferences.refreshOutputDirectory().setDefaultValue(true);
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferences.java
new file mode 100644
index 0000000..bf80188
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferences.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * License v1.0 which accompanies this distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.preferences.compiler.core;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+
+import com.google.eclipse.protobuf.ui.preferences.*;
+
+/**
+ * "Compiler" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CompilerPreferences {
+
+  public static final String ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME = "compiler.enableProjectSettings";
+
+  /**
+   * Creates a new <code>{@link CompilerPreferences}</code>.
+   * @param storeAccess simplified access to Eclipse's preferences.
+   * @param project the current project.
+   * @return the created {@code CompilerPreferences}.
+   */
+  public static CompilerPreferences compilerPreferences(IPreferenceStoreAccess storeAccess, IProject project) {
+    IPreferenceStore store = storeAccess.getWritablePreferenceStore(project);
+    boolean enableProjectSettings = store.getBoolean(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME);
+    if (!enableProjectSettings) {
+      store = storeAccess.getWritablePreferenceStore();
+    }
+    return new CompilerPreferences(store);
+  }
+
+  private final BooleanPreference enableProjectSettings;
+  private final BooleanPreference compileProtoFiles;
+  private final BooleanPreference useProtocInSystemPath;
+  private final BooleanPreference useProtocInCustomPath;
+  private final StringPreference protocPath;
+  private final StringPreference descriptorPath;
+  private final BooleanPreference javaCodeGenerationEnabled;
+  private final BooleanPreference cppCodeGenerationEnabled;
+  private final BooleanPreference pythonCodeGenerationEnabled;
+  private final StringPreference javaOutputDirectory;
+  private final StringPreference cppOutputDirectory;
+  private final StringPreference pythonOutputDirectory;
+  private final BooleanPreference refreshResources;
+  private final BooleanPreference refreshProject;
+  private final BooleanPreference refreshOutputDirectory;
+
+  /**
+   * Creates a new <code>{@link CompilerPreferences}</code>.
+   * @param store a table mapping named preferences to values.
+   */
+  public CompilerPreferences(IPreferenceStore store) {
+    enableProjectSettings = new BooleanPreference(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME, store);
+    compileProtoFiles = new BooleanPreference("compiler.compileProtoFiles", store);
+    useProtocInSystemPath = new BooleanPreference("compiler.useProtocInSystemPath", store);
+    useProtocInCustomPath = new BooleanPreference("compiler.useProtocInCustomPath", store);
+    protocPath = new StringPreference("compiler.protocFilePath", store);
+    descriptorPath = new StringPreference("compiler.descriptorFilePath", store);
+    javaCodeGenerationEnabled = new BooleanPreference("compiler.javaCodeGenerationEnabled", store);
+    cppCodeGenerationEnabled = new BooleanPreference("compiler.cppCodeGenerationEnabled", store);
+    pythonCodeGenerationEnabled = new BooleanPreference("compiler.pythonCodeGenerationEnabled", store);
+    javaOutputDirectory = new StringPreference("compiler.javaOutputDirectory", store);
+    cppOutputDirectory = new StringPreference("compiler.cppOutputDirectory", store);
+    pythonOutputDirectory = new StringPreference("compiler.pythonOutputDirectory", store);
+    refreshResources = new BooleanPreference("compiler.refreshResources", store);
+    refreshProject = new BooleanPreference("compiler.refreshProject", store);
+    refreshOutputDirectory = new BooleanPreference("compiler.refreshOutputDirectory", store);
+  }
+
+  /**
+   * Returns the setting that specifies whether project project should be used instead of workspace preferences.
+   * @return the setting that specifies whether project project should be used instead of workspace preferences.
+   */
+  public BooleanPreference enableProjectSettings() {
+    return enableProjectSettings;
+  }
+
+  /**
+   * Returns the setting that specifies whether protoc should be called after saving a file.
+   * @return the setting that specifies whether protoc should be called after saving a file.
+   */
+  public BooleanPreference compileProtoFiles() {
+    return compileProtoFiles;
+  }
+
+  /**
+   * Returns the setting that specifies whether the editor should call the version of protoc in the system path.
+   * @return the setting that specifies whether the editor should call the version of protoc in the system path.
+   */
+  public BooleanPreference useProtocInSystemPath() {
+    return useProtocInSystemPath;
+  }
+
+  /**
+   * Returns the setting that specifies whether the editor should call a version of protoc stored in a user-specified
+   * path in the file system.
+   * @return the setting that specifies whether the editor should call a version of protoc stored in a user-specified
+   * path in the file system.
+   */
+  public BooleanPreference useProtocInCustomPath() {
+    return useProtocInCustomPath;
+  }
+
+  /**
+   * Returns the setting that specifies the user-specified path of protoc.
+   * @return the setting that specifies the user-specified path of protoc.
+   */
+  public StringPreference protocPath() {
+    return protocPath;
+  }
+
+  /**
+   * Returns the setting that specifies the path of the file descriptor.proto. The path is needed by protoc only if the
+   * file to compile imports descriptor.proto.
+   * @return the setting that specifies the path of the file descriptor.proto.
+   */
+  public StringPreference descriptorPath() {
+    return descriptorPath;
+  }
+
+  /**
+   * Returns the setting that specifies whether protoc should generate Java code.
+   * @return the setting that specifies whether protoc should generate Java code.
+   */
+  public BooleanPreference javaCodeGenerationEnabled() {
+    return javaCodeGenerationEnabled;
+  }
+
+  /**
+   * Returns the setting that specifies whether protoc should generate C++ code.
+   * @return the setting that specifies whether protoc should generate C++ code.
+   */
+  public BooleanPreference cppCodeGenerationEnabled() {
+    return cppCodeGenerationEnabled;
+  }
+
+  /**
+   * Returns the setting that specifies whether protoc should generate Python code.
+   * @return the setting that specifies whether protoc should generate Python code.
+   */
+  public BooleanPreference pythonCodeGenerationEnabled() {
+    return pythonCodeGenerationEnabled;
+  }
+
+  /**
+   * Returns the setting that specifies the directory where to store the generated Java code. This setting is available
+   * only if the value of <code>{@link #javaCodeGenerationEnabled()}</code> is {@code true}.
+   * @return the setting that specifies the directory where to store the generated Java code.
+   */
+  public StringPreference javaOutputDirectory() {
+    return javaOutputDirectory;
+  }
+
+  /**
+   * Returns the setting that specifies the directory where to store the generated C++ code. This setting is available
+   * only if the value of <code>{@link #cppCodeGenerationEnabled()}</code> is {@code true}.
+   * @return the setting that specifies the directory where to store the generated C++ code.
+   */
+  public StringPreference cppOutputDirectory() {
+    return cppOutputDirectory;
+  }
+
+  /**
+   * Returns the setting that specifies the directory where to store the generated Python code. This setting is
+   * available only if the value of <code>{@link #pythonCodeGenerationEnabled()}</code> is {@code true}.
+   * @return the setting that specifies the directory where to store the generated Python code.
+   */
+  public StringPreference pythonOutputDirectory() {
+    return pythonOutputDirectory;
+  }
+
+  /**
+   * Returns the setting that specifies whether resources should be refreshed after changing the "Compiler" preference
+   * settings.
+   * @return the setting that specifies whether resources should be refreshed after changing the "Compiler" preference
+   * settings.
+   */
+  public BooleanPreference refreshResources() {
+    return refreshResources;
+  }
+
+  /**
+   * Returns the setting that specifies whether the current project should be refreshed after changing the "Compiler"
+   * preference settings. This setting is enable only if the value of <code>{@link #refreshResources()}</code> is
+   * {@code true}.
+   * @return the setting that specifies whether the current project should be refreshed after changing
+   */
+  public BooleanPreference refreshProject() {
+    return refreshProject;
+  }
+
+  /**
+   * Returns the setting that specifies whether the directory containing generated code should be refreshed after
+   * changing the "Compiler" preference settings. This setting is enable only if the value of
+   * <code>{@link #refreshResources()}</code> is {@code true}.
+   * @return the setting that specifies whether the current project should be refreshed after changing
+   */
+  public BooleanPreference refreshOutputDirectory() {
+    return refreshOutputDirectory;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/CompilerPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/CompilerPreferencePage.java
new file mode 100644
index 0000000..c543462
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/CompilerPreferencePage.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.compiler.page;
+
+import static com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences.ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME;
+import static com.google.eclipse.protobuf.ui.preferences.compiler.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.pages.ButtonGroup.with;
+import static com.google.eclipse.protobuf.ui.preferences.pages.LabelWidgets.setEnabled;
+import static com.google.eclipse.protobuf.ui.preferences.pages.TextWidgets.*;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToTextValue.bindTextOf;
+import static org.eclipse.xtext.util.Strings.isEmpty;
+
+import java.io.File;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
+import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
+
+/**
+ * Preference page for protobuf compiler.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CompilerPreferencePage extends PreferenceAndPropertyPage {
+  private static final String PREFERENCE_PAGE_ID = CompilerPreferencePage.class.getName();
+
+  private Button btnCompileProtoFiles;
+  private TabFolder tabFolder;
+  private TabItem tbtmMain;
+  private TabItem tbtmRefresh;
+  private TabItem tbtmOptions;
+  private Group grpCompilerLocation;
+  private Button btnUseProtocInSystemPath;
+  private Button btnUseProtocInCustomPath;
+  private Text txtProtocFilePath;
+  private Button btnProtocPathBrowse;
+  private Group grpDescriptorLocation;
+  private Text txtDescriptorFilePath;
+  private Button btnDescriptorPathBrowse;
+  private Button btnGenerateJava;
+  private Label lblJavaOutputDirectory;
+  private Text txtJavaOutputDirectory;
+  private Button btnGenerateCpp;
+  private Label lblCppOutputDirectory;
+  private Text txtCppOutputDirectory;
+  private Button btnGeneratePython;
+  private Label lblPythonOutputDirectory;
+  private Text txtPythonOutputDirectory;
+  private Group grpRefresh;
+  private Button btnRefreshResources;
+  private Button btnRefreshProject;
+  private Button btnRefreshOutputDirectory;
+
+  @Override protected void doCreateContents(Composite parent) {
+    btnCompileProtoFiles = new Button(parent, SWT.CHECK);
+    btnCompileProtoFiles.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
+    btnCompileProtoFiles.setText(compileOnSave);
+
+    tabFolder = new TabFolder(parent, SWT.NONE);
+    tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+
+    tbtmMain = new TabItem(tabFolder, SWT.NONE);
+    tbtmMain.setText(tabMain);
+
+    Composite cmpMain = new Composite(tabFolder, SWT.NONE);
+    tbtmMain.setControl(cmpMain);
+    cmpMain.setLayout(new GridLayout(1, false));
+
+    grpCompilerLocation = new Group(cmpMain, SWT.NONE);
+    grpCompilerLocation.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+    grpCompilerLocation.setLayout(new GridLayout(2, false));
+    grpCompilerLocation.setText(protocLocation);
+
+    btnUseProtocInSystemPath = new Button(grpCompilerLocation, SWT.RADIO);
+    btnUseProtocInSystemPath.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
+    btnUseProtocInSystemPath.setText(protocInSystemPath);
+
+    btnUseProtocInCustomPath = new Button(grpCompilerLocation, SWT.RADIO);
+    btnUseProtocInCustomPath.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
+    btnUseProtocInCustomPath.setText(protocInCustomPath);
+
+    txtProtocFilePath = new Text(grpCompilerLocation, SWT.BORDER);
+    txtProtocFilePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+    setEditable(txtProtocFilePath, false);
+
+    btnProtocPathBrowse = new Button(grpCompilerLocation, SWT.NONE);
+    btnProtocPathBrowse.setText(browseCustomPath);
+
+    grpDescriptorLocation = new Group(cmpMain, SWT.NONE);
+    grpDescriptorLocation.setText(descriptorLocation);
+    grpDescriptorLocation.setLayout(new GridLayout(2, false));
+    grpDescriptorLocation.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+    txtDescriptorFilePath = new Text(grpDescriptorLocation, SWT.BORDER);
+    txtDescriptorFilePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+    setEditable(txtDescriptorFilePath, false);
+
+    btnDescriptorPathBrowse = new Button(grpDescriptorLocation, SWT.NONE);
+    btnDescriptorPathBrowse.setText(browseCustomPath);
+
+    tbtmOptions = new TabItem(tabFolder, SWT.NONE);
+    tbtmOptions.setText("&Options");
+
+    Composite cmpOptions = new Composite(tabFolder, SWT.NONE);
+    tbtmOptions.setControl(cmpOptions);
+    cmpOptions.setLayout(new GridLayout(2, false));
+
+    btnGenerateJava = new Button(cmpOptions, SWT.CHECK);
+    btnGenerateJava.setEnabled(false);
+    btnGenerateJava.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 3, 1));
+    btnGenerateJava.setText("Generate Java");
+
+    lblJavaOutputDirectory = new Label(cmpOptions, SWT.NONE);
+    lblJavaOutputDirectory.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+    lblJavaOutputDirectory.setText("Java Output Directory:");
+
+    txtJavaOutputDirectory = new Text(cmpOptions, SWT.BORDER);
+    txtJavaOutputDirectory.setEnabled(false);
+    txtJavaOutputDirectory.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+    btnGenerateCpp = new Button(cmpOptions, SWT.CHECK);
+    btnGenerateCpp.setEnabled(false);
+    btnGenerateCpp.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
+    btnGenerateCpp.setText("Generate C++");
+
+    lblCppOutputDirectory = new Label(cmpOptions, SWT.NONE);
+    lblCppOutputDirectory.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+    lblCppOutputDirectory.setText("C++ Output Directory:");
+
+    txtCppOutputDirectory = new Text(cmpOptions, SWT.BORDER);
+    txtCppOutputDirectory.setEnabled(false);
+    txtCppOutputDirectory.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+
+    btnGeneratePython = new Button(cmpOptions, SWT.CHECK);
+    btnGeneratePython.setEnabled(false);
+    btnGeneratePython.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
+    btnGeneratePython.setText("Generate Python");
+
+    lblPythonOutputDirectory = new Label(cmpOptions, SWT.NONE);
+    lblPythonOutputDirectory.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+    lblPythonOutputDirectory.setText("Python Output Directory:");
+
+    txtPythonOutputDirectory = new Text(cmpOptions, SWT.BORDER);
+    txtPythonOutputDirectory.setEnabled(false);
+    txtPythonOutputDirectory.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+
+    tbtmRefresh = new TabItem(tabFolder, SWT.NONE);
+    tbtmRefresh.setText(tabRefresh);
+
+    Composite cmpRefresh = new Composite(tabFolder, SWT.NONE);
+    tbtmRefresh.setControl(cmpRefresh);
+    cmpRefresh.setLayout(new GridLayout(1, false));
+
+    btnRefreshResources = new Button(cmpRefresh, SWT.CHECK);
+    btnRefreshResources.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+    btnRefreshResources.setText(refreshResources);
+
+    grpRefresh = new Group(cmpRefresh, SWT.NONE);
+    grpRefresh.setLayout(new GridLayout(1, false));
+    grpRefresh.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+    btnRefreshProject = new Button(grpRefresh, SWT.RADIO);
+    btnRefreshProject.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+    btnRefreshProject.setText(refreshProject);
+
+    btnRefreshOutputDirectory = new Button(grpRefresh, SWT.RADIO);
+    btnRefreshOutputDirectory.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+    btnRefreshOutputDirectory.setText(refreshOutputProject);
+    new Label(parent, SWT.NONE);
+
+    addEventListeners();
+  }
+
+  private void addEventListeners() {
+    btnCompileProtoFiles.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        boolean selected = btnCompileProtoFiles.getSelection();
+        enableCompilerSettings(selected);
+        checkState();
+      }
+    });
+    with(btnUseProtocInCustomPath, btnUseProtocInSystemPath).add(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        boolean selected = btnUseProtocInCustomPath.getSelection();
+        enableCompilerCustomPathSettings(selected);
+        checkState();
+      }
+    });
+    btnProtocPathBrowse.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.SHEET);
+        String file = dialog.open();
+        if (file != null) {
+          txtProtocFilePath.setText(file);
+        }
+        checkState();
+      }
+    });
+    btnDescriptorPathBrowse.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.SHEET);
+        dialog.setFilterExtensions(new String[] { "*.proto" });
+        String file = dialog.open();
+        if (file != null) {
+          txtDescriptorFilePath.setText(file);
+        }
+        checkState();
+      }
+    });
+    btnGenerateJava.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        enableJavaOutputDirectory(btnGenerateJava.getSelection());
+        checkState();
+      }
+    });
+    btnGenerateCpp.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        enableCppOutputDirectory(btnGenerateCpp.getSelection());
+        checkState();
+      }
+    });
+    btnGeneratePython.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        enablePythonOutputDirectory(btnGeneratePython.getSelection());
+        checkState();
+      }
+    });
+    btnRefreshResources.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        refreshResourcesSettingsEnabled(btnRefreshResources.getSelection());
+      }
+    });
+  }
+
+  @Override protected String enableProjectSettingsPreferenceName() {
+    return ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME;
+  }
+
+  @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
+    CompilerPreferences preferences = new CompilerPreferences(getPreferenceStore());
+    preferenceBinder.addAll(
+        bindSelectionOf(btnCompileProtoFiles).to(preferences.compileProtoFiles()),
+        bindSelectionOf(btnUseProtocInSystemPath).to(preferences.useProtocInSystemPath()),
+        bindSelectionOf(btnUseProtocInCustomPath).to(preferences.useProtocInCustomPath()),
+        bindTextOf(txtProtocFilePath).to(preferences.protocPath()),
+        bindTextOf(txtDescriptorFilePath).to(preferences.descriptorPath()),
+        bindSelectionOf(btnGenerateJava).to(preferences.javaCodeGenerationEnabled()),
+        bindTextOf(txtJavaOutputDirectory).to(preferences.javaOutputDirectory()),
+        bindSelectionOf(btnGenerateCpp).to(preferences.cppCodeGenerationEnabled()),
+        bindTextOf(txtCppOutputDirectory).to(preferences.cppOutputDirectory()),
+        bindSelectionOf(btnGeneratePython).to(preferences.pythonCodeGenerationEnabled()),
+        bindTextOf(txtPythonOutputDirectory).to(preferences.pythonOutputDirectory()),
+        bindSelectionOf(btnRefreshResources).to(preferences.refreshResources()),
+        bindSelectionOf(btnRefreshProject).to(preferences.refreshProject()),
+        bindSelectionOf(btnRefreshOutputDirectory).to(preferences.refreshOutputDirectory())
+      );
+  }
+
+  @Override protected void updateContents() {
+    boolean compileProtoFiles = btnCompileProtoFiles.getSelection();
+    boolean shouldEnableCompilerOptions = compileProtoFiles;
+    if (isPropertyPage()) {
+      boolean useProjectSettings = areProjectSettingsActive();
+      activateProjectSettings(useProjectSettings);
+      enableProjectSpecificSettings(useProjectSettings);
+      shouldEnableCompilerOptions = shouldEnableCompilerOptions && useProjectSettings;
+    }
+    enableCompilerSettings(shouldEnableCompilerOptions);
+  }
+
+  @Override protected void onProjectSettingsActivation(boolean active) {
+    enableProjectSpecificSettings(active);
+    enableCompilerSettings(isEnabledAndSelected(btnCompileProtoFiles));
+    checkState();
+  }
+
+  private void enableProjectSpecificSettings(boolean enabled) {
+    btnCompileProtoFiles.setEnabled(enabled);
+  }
+
+  private void enableCompilerSettings(boolean enabled) {
+    enableCompilerPathSettings(enabled);
+    enableDescriptorPathSettings(enabled);
+    enableOptionsSettings(enabled);
+    enableRefreshSettings(enabled);
+  }
+
+  private void enableCompilerPathSettings(boolean enabled) {
+    grpCompilerLocation.setEnabled(enabled);
+    btnUseProtocInSystemPath.setEnabled(enabled);
+    btnUseProtocInCustomPath.setEnabled(enabled);
+    enableCompilerCustomPathSettings(customPathOptionSelectedAndEnabled());
+  }
+
+  private void enableCompilerCustomPathSettings(boolean enabled) {
+    txtProtocFilePath.setEnabled(enabled);
+    btnProtocPathBrowse.setEnabled(enabled);
+  }
+
+  private void enableDescriptorPathSettings(boolean enabled) {
+    grpDescriptorLocation.setEnabled(enabled);
+    txtDescriptorFilePath.setEnabled(enabled);
+    btnDescriptorPathBrowse.setEnabled(enabled);
+  }
+
+  private boolean customPathOptionSelectedAndEnabled() {
+    return isEnabledAndSelected(btnUseProtocInCustomPath);
+  }
+
+  private void enableOptionsSettings(boolean enabled) {
+    btnGenerateJava.setEnabled(enabled);
+    enableJavaOutputDirectory(isEnabledAndSelected(btnGenerateJava));
+    btnGenerateCpp.setEnabled(enabled);
+    enableCppOutputDirectory(isEnabledAndSelected(btnGenerateCpp));
+    btnGeneratePython.setEnabled(enabled);
+    enablePythonOutputDirectory(isEnabledAndSelected(btnGeneratePython));
+  }
+
+  private void enableJavaOutputDirectory(boolean enabled) {
+    setEnabled(txtJavaOutputDirectory, enabled);
+    setEnabled(lblJavaOutputDirectory, enabled);
+  }
+
+  private void enableCppOutputDirectory(boolean enabled) {
+    setEnabled(txtCppOutputDirectory, enabled);
+    setEnabled(lblCppOutputDirectory, enabled);
+  }
+
+  private void enablePythonOutputDirectory(boolean enabled) {
+    setEnabled(txtPythonOutputDirectory, enabled);
+    setEnabled(lblPythonOutputDirectory, enabled);
+  }
+
+  private void enableRefreshSettings(boolean enabled) {
+    btnRefreshResources.setEnabled(enabled);
+    refreshResourcesSettingsEnabled(isEnabledAndSelected(btnRefreshResources));
+  }
+
+  private boolean isEnabledAndSelected(Button button) {
+    return button.isEnabled() && button.getSelection();
+  }
+
+  private void refreshResourcesSettingsEnabled(boolean enabled) {
+    grpRefresh.setEnabled(enabled);
+    btnRefreshProject.setEnabled(enabled);
+    btnRefreshOutputDirectory.setEnabled(enabled);
+  }
+
+  private void checkState() {
+    if (!atLeastOneTargetLanguageIsSelected()) {
+      pageIsNowInvalid(errorNoLanguageSelected);
+      return;
+    }
+    if (customPathOptionSelectedAndEnabled()) {
+      String protocPath = txtProtocFilePath.getText();
+      if (isEmpty(protocPath)) {
+        pageIsNowInvalid(errorNoSelection);
+        return;
+      }
+      File protoc = new File(protocPath);
+      if (!protoc.isFile()) {
+        pageIsNowInvalid(errorInvalidProtoc);
+        return;
+      }
+    }
+    String descriptorPath = txtDescriptorFilePath.getText();
+    if (!isEmpty(descriptorPath) && !isFileWithName(descriptorPath, "descriptor.proto")) {
+      pageIsNowInvalid(errorInvalidDescriptor);
+      return;
+    }
+    pageIsNowValid();
+  }
+
+  private boolean atLeastOneTargetLanguageIsSelected() {
+    return btnGenerateJava.getSelection() || btnGenerateCpp.getSelection() || btnGeneratePython.getSelection();
+  }
+
+  private boolean isFileWithName(String filePath, String expectedFileName) {
+    File file = new File(filePath);
+    if (!file.isFile()) {
+      return false;
+    }
+    String fileName = file.getName();
+    return expectedFileName.equals(fileName);
+  }
+  @Override protected String preferencePageId() {
+    return PREFERENCE_PAGE_ID;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.java
similarity index 82%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.java
index 0126998..74a1f7b 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
+package com.google.eclipse.protobuf.ui.preferences.compiler.page;
 
 import org.eclipse.osgi.util.NLS;
 
@@ -21,18 +21,12 @@
   public static String descriptorLocation;
   public static String editSelected;
   public static String editCodeGenerationOptionTitle;
-  public static String enabled;
   public static String errorEnterDirectoryName;
   public static String errorInvalidProtoc;
   public static String errorInvalidDescriptor;
-  public static String errorNoLanguageEnabled;
+  public static String errorNoLanguageSelected;
   public static String errorNoOutputFolderName;
   public static String errorNoSelection;
-  public static String generateCpp;
-  public static String generateCode;
-  public static String generateJava;
-  public static String generatePython;
-  public static String language;
   public static String outputDirectory;
   public static String outputDirectoryPrompt;
   public static String outputFolderChildOfProjectFolder;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.properties
similarity index 85%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.properties
index c2b1083..c0e01ce 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/Messages.properties
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.properties
@@ -4,18 +4,12 @@
 descriptorLocation=\"descriptor.proto\" location
 editSelected=Edit selected...
 editCodeGenerationOptionTitle=Preferences for 
-enabled=Enabled
 errorEnterDirectoryName=Enter the name of the output directory
 errorInvalidProtoc=The selected file is not protoc
 errorInvalidDescriptor=The selected file is not descriptor.proto
-errorNoLanguageEnabled=Enable at least one language
+errorNoLanguageSelected=Select at least one language (Java, C++ or Python)
 errorNoSelection=Select the path of protoc
 errorNoOutputFolderName=Enter the name of the output folder
-generateCode=Generated Code
-generateCpp=&C++
-generateJava=&Java
-generatePython=&Python
-language=Language
 outputDirectory=Output Directory
 outputDirectoryPrompt=Output directory name:
 outputFolderChildOfProjectFolder=*direct child of project folder
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/EditorPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/EditorPreferencePage.java
similarity index 83%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/EditorPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/EditorPreferencePage.java
index 3a40db5..a88554d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/EditorPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/EditorPreferencePage.java
@@ -7,9 +7,9 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor;
+package com.google.eclipse.protobuf.ui.preferences.editor.general.page;
 
-import static com.google.eclipse.protobuf.ui.preferences.pages.editor.Messages.header;
+import static com.google.eclipse.protobuf.ui.preferences.editor.general.page.Messages.header;
 import static org.eclipse.ui.dialogs.PreferencesUtil.createPreferenceDialogOn;
 
 import org.eclipse.jface.preference.PreferencePage;
@@ -36,8 +36,8 @@
     link.setText(header);
     link.addListener(SWT.Selection, new Listener() {
       @Override public void handleEvent(Event event) {
-        String u = event.text;
-        createPreferenceDialogOn(getShell(), u, null, null);
+        String text = event.text;
+        createPreferenceDialogOn(getShell(), text, null, null);
       }
     });
     return contents;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.java
similarity index 89%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.java
index 128473a..95e091a 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.java
@@ -7,7 +7,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor;
+package com.google.eclipse.protobuf.ui.preferences.editor.general.page;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferenceStoreInitializer.java
new file mode 100644
index 0000000..0f19478
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferenceStoreInitializer.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.core;
+
+import static java.util.Collections.singletonList;
+
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * Initializes default values for <code>{@link NumericTagPreferences}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class NumericTagPreferenceStoreInitializer implements IPreferenceStoreInitializer {
+
+  /** {@inheritDoc} */
+  @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+    NumericTagPreferences preferences = new NumericTagPreferences(storeAccess);
+    preferences.patterns().setDefaultValue(singletonList("Next[\\s]+Id:[\\s]+[\\d]+"));
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferences.java
new file mode 100644
index 0000000..997d08e
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferences.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.core;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+
+import com.google.eclipse.protobuf.ui.preferences.StringListPreference;
+
+/**
+ * "Numeric tag" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class NumericTagPreferences {
+
+  private final StringListPreference patterns;
+
+  /**
+   * Creates a new <code>{@link NumericTagPreferences}</code>.
+   * @param storeAccess simplified access to Eclipse's preferences.
+   */
+  public NumericTagPreferences(IPreferenceStoreAccess storeAccess) {
+    this(storeAccess.getWritablePreferenceStore());
+  }
+
+  /**
+   * Creates a new <code>{@link NumericTagPreferences}</code>.
+   * @param store a table mapping named preferences to values.
+   */
+  public NumericTagPreferences(IPreferenceStore store) {
+    patterns = new StringListPreference("numericTag.patterns", "\\t", store);
+  }
+
+  /**
+   * Returns the setting that specifies the regular expression patterns to use to identify comments that track the next
+   * field index.
+   * @return the setting that specifies the regular expression patterns to use to identify comments that track the next
+   * field index.
+   */
+  public StringListPreference patterns() {
+    return patterns;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/AddOrEditPatternDialog.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/AddOrEditPatternDialog.java
similarity index 91%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/AddOrEditPatternDialog.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/AddOrEditPatternDialog.java
index 643ba56..205652e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/AddOrEditPatternDialog.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/AddOrEditPatternDialog.java
@@ -6,10 +6,10 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page;
 
-import static com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.Messages.*;
-import static com.google.eclipse.protobuf.ui.swt.Colors.widgetBackground;
+import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.pages.SystemColors.widgetBackgroundColor;
 import static java.util.regex.Pattern.CASE_INSENSITIVE;
 import static org.eclipse.jface.dialogs.IDialogConstants.OK_ID;
 import static org.eclipse.swt.layout.GridData.*;
@@ -22,7 +22,7 @@
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.*;
 
-import com.google.eclipse.protobuf.ui.preferences.InputDialog;
+import com.google.eclipse.protobuf.ui.preferences.pages.InputDialog;
 
 /**
  * Dialog where users can enter a new pattern or edit an existing one.
@@ -69,7 +69,7 @@
 
     txtPatternError = new Text(cmpDialogArea, SWT.READ_ONLY | SWT.WRAP);
     txtPatternError.setLayoutData(new GridData(GRAB_HORIZONTAL | HORIZONTAL_ALIGN_FILL));
-    txtPatternError.setBackground(widgetBackground());
+    txtPatternError.setBackground(widgetBackgroundColor());
 
     Label lblSeparator = new Label(cmpDialogArea, SWT.SEPARATOR | SWT.HORIZONTAL);
     lblSeparator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
@@ -85,7 +85,7 @@
     GridData gd_txtTestError = new GridData(GRAB_HORIZONTAL | HORIZONTAL_ALIGN_FILL);
     gd_txtTestError.verticalAlignment = SWT.FILL;
     txtTestError.setLayoutData(gd_txtTestError);
-    txtTestError.setBackground(widgetBackground());
+    txtTestError.setBackground(widgetBackgroundColor());
 
     addEventListeners();
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.java
similarity index 91%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.java
index 5b2b307..5ed74dc 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/NumericTagPreferencePage.java
similarity index 84%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/NumericTagPreferencePage.java
index 2a7e150..cef0657 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/NumericTagPreferencePage.java
@@ -6,23 +6,23 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page;
 
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToListItems.bindItemsOf;
-import static com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.AddOrEditPatternDialog.*;
-import static com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page.AddOrEditPatternDialog.*;
+import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToListItems.bindItemsOf;
 import static org.eclipse.jface.window.Window.OK;
 
-import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.viewers.ListViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
-import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.StringListPreference;
+import com.google.eclipse.protobuf.ui.preferences.editor.numerictag.core.NumericTagPreferences;
 import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
 
 /**
  * Preference page where users can specify the patterns to use to match comments where "the next id" is being tracked.
@@ -115,12 +115,12 @@
     btnRemove.setEnabled(hasSelection);
   }
 
-  @Override protected BooleanPreference enableProjectSettingsPreference(IPreferenceStore store) {
+  @Override protected String enableProjectSettingsPreferenceName() {
     return null;
   }
 
   @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
-    RawPreferences preferences = new RawPreferences(getPreferenceStore());
+    NumericTagPreferences preferences = new NumericTagPreferences(getPreferenceStore());
     StringListPreference patterns = preferences.patterns();
     preferenceBinder.add(bindItemsOf(lstPaths).to(patterns));
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferenceStoreInitializer.java
new file mode 100644
index 0000000..a9b9538
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferenceStoreInitializer.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.editor.save.core;
+
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * Initializes default values for <code>{@link SaveActionsPreferences}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class SaveActionsPreferenceStoreInitializer implements IPreferenceStoreInitializer {
+
+  /** {@inheritDoc} */
+  @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+    SaveActionsPreferences preferences = new SaveActionsPreferences(storeAccess);
+    preferences.removeTrailingWhitespace().setDefaultValue(true);
+    preferences.inAllLines().setDefaultValue(false);
+    preferences.inEditedLines().setDefaultValue(true);
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferences.java
new file mode 100644
index 0000000..2c5206a
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferences.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.editor.save.core;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+
+import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
+
+/**
+ * "Save actions" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class SaveActionsPreferences {
+
+  private final BooleanPreference removeTrailingWhitespace;
+  private final BooleanPreference inAllLines;
+  private final BooleanPreference inEditedLines;
+
+  /**
+   * Creates a new <code>{@link SaveActionsPreferences}</code>.
+   * @param storeAccess simplified access to Eclipse's preferences.
+   */
+  public SaveActionsPreferences(IPreferenceStoreAccess storeAccess) {
+    this(storeAccess.getWritablePreferenceStore());
+  }
+
+  /**
+   * Creates a new <code>{@link SaveActionsPreferences}</code>.
+   * @param store a table mapping named preferences to values.
+   */
+  public SaveActionsPreferences(IPreferenceStore store) {
+    removeTrailingWhitespace = new BooleanPreference("saveActions.removeTrailingWhitespace", store);
+    inAllLines = new BooleanPreference("saveActions.inAllLines", store);
+    inEditedLines = new BooleanPreference("saveActions.inEditedLines", store);
+  }
+
+  /**
+   * Returns the setting that specifies whether trailing whitespace should be removed.
+   * @return the setting that specifies whether trailing whitespace should be removed.
+   */
+  public BooleanPreference removeTrailingWhitespace() {
+    return removeTrailingWhitespace;
+  }
+
+  /**
+   * Returns the setting that specifies whether trailing whitespace should be removed from all the lines of a file.
+   * @return the setting that specifies whether trailing whitespace should be removed from all the lines of a file.
+   */
+  public BooleanPreference inAllLines() {
+    return inAllLines;
+  }
+
+  /**
+   * Returns the setting that specifies whether trailing whitespace should be removed from edited lines only.
+   * @return the setting that specifies whether trailing whitespace should be removed from edited lines only.
+   */
+  public BooleanPreference inEditedLines() {
+    return inEditedLines;
+  }
+}
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.java
similarity index 89%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.java
index bb07e69..a3c84aa 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.save;
+package com.google.eclipse.protobuf.ui.preferences.editor.save.page;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/SaveActionsPreferencePage.java
similarity index 84%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/SaveActionsPreferencePage.java
index ef3bc24..fd94950 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/SaveActionsPreferencePage.java
@@ -7,10 +7,10 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.save;
+package com.google.eclipse.protobuf.ui.preferences.editor.save.page;
 
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToButtonSelection.bindSelectionOf;
-import static com.google.eclipse.protobuf.ui.preferences.pages.editor.save.Messages.removeTrailingWhitespace;
+import static com.google.eclipse.protobuf.ui.preferences.editor.save.page.Messages.removeTrailingWhitespace;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 
 import org.eclipse.jface.preference.*;
 import org.eclipse.swt.SWT;
@@ -20,7 +20,8 @@
 import org.eclipse.ui.*;
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import com.google.eclipse.protobuf.ui.preferences.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.editor.save.core.SaveActionsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
 import com.google.inject.Inject;
 
 /**
@@ -35,9 +36,7 @@
   private final PreferenceBinder preferenceBinder = new PreferenceBinder();
 
   private Button btnRemoveTrailingwhitespace;
-
   private Button btnInEditedLines;
-
   private Button btnInAllLines;
 
   /** {@inheritDoc} */
@@ -68,7 +67,7 @@
   }
 
   private void setUpBinding() {
-    RawPreferences preferences = new RawPreferences(getPreferenceStore());
+    SaveActionsPreferences preferences = new SaveActionsPreferences(getPreferenceStore());
     preferenceBinder.addAll(
         bindSelectionOf(btnRemoveTrailingwhitespace).to(preferences.removeTrailingWhitespace()),
         bindSelectionOf(btnInAllLines).to(preferences.inAllLines()),
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferenceStoreInitializer.java
new file mode 100644
index 0000000..51e26e0
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferenceStoreInitializer.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.general.core;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * Initializes default values for the "Paths" preferences.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class GeneralPreferenceStoreInitializer implements IPreferenceStoreInitializer {
+
+  /** {@inheritDoc} */
+  @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+    IPreferenceStore store = storeAccess.getWritablePreferenceStore();
+    GeneralPreferences preferences = new GeneralPreferences(store);
+    preferences.enableProjectSettings().setDefaultValue(false);
+    preferences.validateFilesOnActivation().setDefaultValue(true);
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferences.java
new file mode 100644
index 0000000..bb08303
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferences.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.general.core;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+
+import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
+
+/**
+ * General preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class GeneralPreferences {
+
+  public static final String ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME = "general.enableProjectSettings";
+
+  /**
+   * Creates a new <code>{@link GeneralPreferences}</code>.
+   * @param storeAccess simplified access to Eclipse's preferences.
+   * @param project the current project.
+   * @return the created {@code GeneralPreferences}.
+   */
+  public static GeneralPreferences generalPreferences(IPreferenceStoreAccess storeAccess, IProject project) {
+    IPreferenceStore store = storeAccess.getWritablePreferenceStore(project);
+    boolean enableProjectSettings = store.getBoolean(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME);
+    if (!enableProjectSettings) {
+      store = storeAccess.getWritablePreferenceStore();
+    }
+    return new GeneralPreferences(store);
+  }
+
+  private final BooleanPreference enableProjectSettings;
+  private final BooleanPreference validateFilesOnActivation;
+
+  /**
+   * Creates a new <code>{@link GeneralPreferences}</code>.
+   * @param store a table mapping named preferences to values.
+   */
+  public GeneralPreferences(IPreferenceStore store) {
+    enableProjectSettings = new BooleanPreference(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME, store);
+    validateFilesOnActivation = new BooleanPreference("general.validateFilesOnActivation", store);
+  }
+
+  /**
+   * Returns the setting that specifies whether project project should be used instead of workspace preferences.
+   * @return the setting that specifies whether project project should be used instead of workspace preferences.
+   */
+  public BooleanPreference enableProjectSettings() {
+    return enableProjectSettings;
+  }
+
+  /**
+   * Returns the setting that specifies whether files should be validated when activated.
+   * @return the setting that specifies whether files should be validated when activated.
+   */
+  public BooleanPreference validateFilesOnActivation() {
+    return validateFilesOnActivation;
+  }
+}
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/GeneralPreferencePage.java
similarity index 66%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/GeneralPreferencePage.java
index a6ceeae..0e9aecd 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/GeneralPreferencePage.java
@@ -6,20 +6,19 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.general;
+package com.google.eclipse.protobuf.ui.preferences.general.page;
 
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToButtonSelection.bindSelectionOf;
-import static com.google.eclipse.protobuf.ui.preferences.pages.general.EnableProjectSettingsPreference.enableProjectSettings;
-import static com.google.eclipse.protobuf.ui.preferences.pages.general.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferences.ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME;
+import static com.google.eclipse.protobuf.ui.preferences.general.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 
-import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-import com.google.eclipse.protobuf.ui.preferences.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferences;
 import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
@@ -42,12 +41,12 @@
     new Label(parent, SWT.NONE);
   }
 
-  @Override protected BooleanPreference enableProjectSettingsPreference(IPreferenceStore store) {
-    return enableProjectSettings(store);
+  @Override protected String enableProjectSettingsPreferenceName() {
+    return ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME;
   }
 
   @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
-    RawPreferences preferences = new RawPreferences(getPreferenceStore());
+    GeneralPreferences preferences = new GeneralPreferences(getPreferenceStore());
     preferenceBinder.addAll(
         bindSelectionOf(btnValidateOnActivation).to(preferences.validateFilesOnActivation())
       );
@@ -65,9 +64,9 @@
     enableProjectSpecificOptions(active);
   }
 
-  private void enableProjectSpecificOptions(boolean isEnabled) {
-    grpValidation.setEnabled(isEnabled);
-    btnValidateOnActivation.setEnabled(isEnabled);
+  private void enableProjectSpecificOptions(boolean enabled) {
+    grpValidation.setEnabled(enabled);
+    btnValidateOnActivation.setEnabled(enabled);
   }
 
   @Override protected String preferencePageId() {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.java
similarity index 90%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.java
index cfba0ba..74d9b38 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.pages.general;
+package com.google.eclipse.protobuf.ui.preferences.general.page;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/ButtonGroup.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/ButtonGroup.java
new file mode 100644
index 0000000..bfe5f0b
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/ButtonGroup.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.pages;
+
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+
+/**
+ * Group of <code>{@link Button}</code>s.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ButtonGroup {
+
+  /**
+   * Creates a new <code>{@link ButtonGroup}</code>.
+   * @param buttons the buttons to group.
+   * @return the created group of buttons.
+   */
+  public static ButtonGroup with(Button...buttons) {
+    return new ButtonGroup(buttons);
+  }
+
+  private final Button[] buttons;
+
+  private ButtonGroup(Button[] buttons) {
+    this.buttons = buttons;
+  }
+
+  /**
+   * Adds the given <code>{@link SelectionListener}</code> to all the buttons in this group.
+   * @param listener the {@code SelectionListener} to add.
+   */
+  public void add(SelectionListener listener) {
+    for (Button b : buttons) {
+      b.addSelectionListener(listener);
+    }
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/DataChangedListener.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/DataChangedListener.java
similarity index 88%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/DataChangedListener.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/DataChangedListener.java
index 9412a0c..d10af2c 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/DataChangedListener.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/DataChangedListener.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences;
+package com.google.eclipse.protobuf.ui.preferences.pages;
 
 /**
  * Listener notified when data in a preference page changes.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/InputDialog.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/InputDialog.java
similarity index 94%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/InputDialog.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/InputDialog.java
index d7306cd..6313139 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/InputDialog.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/InputDialog.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences;
+package com.google.eclipse.protobuf.ui.preferences.pages;
 
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.swt.SWT;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/LabelWidgets.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/LabelWidgets.java
new file mode 100644
index 0000000..fa07622
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/LabelWidgets.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.pages;
+
+import static com.google.eclipse.protobuf.ui.preferences.pages.SystemColors.getSystemColor;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Utility methods related to <code>{@link Label}</code> widgets.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public final class LabelWidgets {
+
+  /**
+   * Enables the given label widget if the given "enabled" state is {@code true}, and disables it otherwise. This method
+   * also sets the foreground of the widget to the system color with id <code>{@link SWT#COLOR_WIDGET_FOREGROUND}</code>
+   * if the given "enabled" state is {@code true}, otherwise it sets the foreground of the widget to the system color
+   * with id <code>{@link SWT#COLOR_TITLE_INACTIVE_FOREGROUND}</code>.
+   * @param label the given label widget.
+   * @param editable the new "enabled" state.
+   * @throws SWTException if the given label widget has been disposed or if this method is not called from the thread
+   * that created the label widget.
+   */
+  public static void setEnabled(Label label, boolean enabled) {
+    label.setEnabled(enabled);
+    updateForegroundColor(label);
+  }
+
+  private static void updateForegroundColor(Label label) {
+    int colorId = label.isEnabled() ? SWT.COLOR_WIDGET_FOREGROUND : SWT.COLOR_TITLE_INACTIVE_FOREGROUND;
+    label.setForeground(getSystemColor(colorId));
+  }
+
+  private LabelWidgets() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java
index c8cbf10..9705c99 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java
@@ -8,9 +8,10 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.pages;
 
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToButtonSelection.bindSelectionOf;
 import static com.google.eclipse.protobuf.ui.preferences.pages.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 import static org.eclipse.ui.dialogs.PreferencesUtil.createPreferenceDialogOn;
+import static org.eclipse.xtext.util.Strings.isEmpty;
 
 import java.util.Map;
 
@@ -25,7 +26,7 @@
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
 import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-import com.google.eclipse.protobuf.ui.preferences.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
 import com.google.inject.Inject;
 
 /**
@@ -33,7 +34,8 @@
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
-public abstract class PreferenceAndPropertyPage extends PreferencePage implements IWorkbenchPreferencePage, IWorkbenchPropertyPage {
+public abstract class PreferenceAndPropertyPage extends PreferencePage implements IWorkbenchPreferencePage,
+    IWorkbenchPropertyPage {
 
   private Button btnEnableProjectSettings;
 
@@ -123,21 +125,21 @@
   protected abstract void doCreateContents(Composite parent);
 
   private void setupBindingOfBtnEnabledProjectSettings() {
-    BooleanPreference preference = enableProjectSettingsPreference(getPreferenceStore());
-    if (preference == null) {
+    String preferenceName = enableProjectSettingsPreferenceName();
+    if (isEmpty(preferenceName)) {
       return;
     }
+    BooleanPreference preference = new BooleanPreference(preferenceName, getPreferenceStore());
     preferenceBinder.add(bindSelectionOf(btnEnableProjectSettings).to(preference));
   }
 
   /**
-   * Returns the preference that indicates whether this page is a "Project Properties" or a "Workspace Preferences"
-   * page.
-   * @param store the store where the preference value is stored.
-   * @return the preference that indicates whether this page is a "Project Properties" or a "Workspace Preferences"
-   * page.
+   * Returns the name of the preference that specifies whether this page is a "Project Properties" or a "Workspace
+   * Preferences" page.
+   * @return the name of the preference that specifies whether this page is a "Project Properties" or a "Workspace
+   * Preferences" page.
    */
-  protected abstract BooleanPreference enableProjectSettingsPreference(IPreferenceStore store);
+  protected abstract String enableProjectSettingsPreferenceName();
 
   /**
    * Sets up data binding.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/SystemColors.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/SystemColors.java
new file mode 100644
index 0000000..58fce42
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/SystemColors.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.pages;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Utility methods related to system colors.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public final class SystemColors {
+
+  /**
+   * Returns the system color with id <code>{@link SWT#COLOR_WIDGET_BACKGROUND}</code>.
+   * @return the system color with id {@code COLOR_WIDGET_BACKGROUND}.
+   */
+  public static Color widgetBackgroundColor() {
+    return getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+  }
+
+  /**
+   * Returns the matching standard color for the given constant, which should one of the color constants specified in
+   * <code>{@link SWT}</code>. Any value other than one of the SWT color constants which is passed in will result in the
+   * color black. This color should not be free'd because it was allocated by the system, not the application.
+   * @param colorId the color constant.
+   * @return the matching color.
+   * @throws SWTException if this method is not called from the thread that created the receiver or if the receiver has
+   * been disposed.
+   */
+  public static Color getSystemColor(int colorId) {
+    return Display.getCurrent().getSystemColor(colorId);
+  }
+
+  private SystemColors() {
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/TextWidgets.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/TextWidgets.java
new file mode 100644
index 0000000..0cde79d
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/TextWidgets.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.pages;
+
+import static com.google.eclipse.protobuf.ui.preferences.pages.SystemColors.getSystemColor;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Utility methods related to <code>{@link Text}</code> widgets.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public final class TextWidgets {
+
+  /**
+   * Sets the "editable" state of the given text widget. This method also sets the background of the widget to
+   * the system color with id <code>{@link SWT#COLOR_LIST_BACKGROUND}</code> if the given "editable" state is
+   * {@code true}, otherwise it sets the background of the widget to the system color with id
+   * <code>{@link SWT#COLOR_WIDGET_BACKGROUND}</code>.
+   * @param text the given text widget.
+   * @param editable the new "editable" state.
+   * @throws SWTException if the given text widget has been disposed or if this method is not called from the thread
+   * that created the text widget.
+   */
+  public static void setEditable(Text text, boolean editable) {
+    text.setEditable(editable);
+    updateBackgroundColor(text);
+  }
+
+  /**
+   * Enables the given text widget if the given "enabled" state is {@code true}, and disables it otherwise. This method
+   * also sets the background of the widget to the system color with id <code>{@link SWT#COLOR_LIST_BACKGROUND}</code>
+   * if the given "enabled" state is {@code true}, otherwise it sets the background of the widget to the system color
+   * with id <code>{@link SWT#COLOR_WIDGET_BACKGROUND}</code>.
+   * @param text the given text widget.
+   * @param editable the new "enabled" state.
+   * @throws SWTException if the given text widget has been disposed or if this method is not called from the thread
+   * that created the text widget.
+   */
+  public static void setEnabled(Text text, boolean enabled) {
+    text.setEnabled(enabled);
+    updateBackgroundColor(text);
+  }
+
+  private static void updateBackgroundColor(Text text) {
+    int colorId = (text.isEnabled() && text.getEditable()) ? SWT.COLOR_LIST_BACKGROUND : SWT.COLOR_WIDGET_BACKGROUND;
+    text.setBackground(getSystemColor(colorId));
+  }
+
+  private TextWidgets() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/Binding.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/Binding.java
similarity index 92%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/Binding.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/Binding.java
index feffdfb..d9c662c 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/Binding.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/Binding.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.binding;
+package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection.java
similarity index 91%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection.java
index f415648..39153e6 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.binding;
+package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.Button;
@@ -40,12 +40,12 @@
 
   /** {@inheritDoc} */
   @Override public void applyPreferenceValueToTarget() {
-    apply(preference.value());
+    apply(preference.getValue());
   }
 
   /** {@inheritDoc} */
   @Override public void applyDefaultPreferenceValueToTarget() {
-    apply(preference.defaultValue());
+    apply(preference.getDefaultValue());
   }
 
   private void apply(boolean value) {
@@ -54,7 +54,7 @@
 
   /** {@inheritDoc} */
   @Override public void savePreferenceValue() {
-    preference.value(button.getSelection());
+    preference.setValue(button.getSelection());
   }
 
   public static class BindingBuilder {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems.java
similarity index 91%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems.java
index 9deab97..6289f2d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.binding;
+package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
 import static java.util.Arrays.asList;
 
@@ -44,12 +44,12 @@
 
   /** {@inheritDoc} */
   @Override public void applyPreferenceValueToTarget() {
-    apply(preference.value());
+    apply(preference.getValue());
   }
 
   /** {@inheritDoc} */
   @Override public void applyDefaultPreferenceValueToTarget() {
-    apply(preference.defaultValue());
+    apply(preference.getDefaultValue());
   }
 
   private void apply(Collection<String> value) {
@@ -61,7 +61,7 @@
 
   /** {@inheritDoc} */
   @Override public void savePreferenceValue() {
-    preference.value(asList(list.getItems()));
+    preference.setValue(asList(list.getItems()));
   }
 
   public static class BindingBuilder {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue.java
similarity index 91%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue.java
index 170b0a1..64143d9 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.binding;
+package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.Text;
@@ -40,12 +40,12 @@
 
   /** {@inheritDoc} */
   @Override public void applyPreferenceValueToTarget() {
-    apply(preference.value());
+    apply(preference.getValue());
   }
 
   /** {@inheritDoc} */
   @Override public void applyDefaultPreferenceValueToTarget() {
-    apply(preference.defaultValue());
+    apply(preference.getDefaultValue());
   }
 
   private void apply(String value) {
@@ -54,7 +54,7 @@
 
   /** {@inheritDoc} */
   @Override public void savePreferenceValue() {
-    preference.value(text.getText());
+    preference.setValue(text.getText());
   }
 
   public static class BindingBuilder {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/PreferenceBinder.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/PreferenceBinder.java
index 523eb85..2b7d548 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/PreferenceBinder.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.binding;
+package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
 import java.util.*;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/BindingToCodeGeneration.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/BindingToCodeGeneration.java
deleted file mode 100644
index 65fe246..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/BindingToCodeGeneration.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.binding.Binding;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class BindingToCodeGeneration implements Binding {
-
-  private final CodeGenerationSetting codeGeneration;
-  private final BooleanPreference enabled;
-  private final StringPreference outputDirectory;
-
-  static BindingBuilder bindCodeGeneration(CodeGenerationSetting codeGeneration) {
-    return new BindingBuilder(codeGeneration);
-  }
-
-  private BindingToCodeGeneration(CodeGenerationSetting codeGeneration, BooleanPreference enabled, StringPreference outputDirectory) {
-    this.codeGeneration = codeGeneration;
-    this.enabled = enabled;
-    this.outputDirectory = outputDirectory;
-  }
-
-  /** {@inheritDoc} */
-  @Override public void applyPreferenceValueToTarget() {
-    codeGeneration.enabled(enabled.value());
-    codeGeneration.outputDirectory(outputDirectory.value());
-  }
-
-  /** {@inheritDoc} */
-  @Override public void applyDefaultPreferenceValueToTarget() {
-    codeGeneration.enabled(enabled.defaultValue());
-    codeGeneration.outputDirectory(outputDirectory.defaultValue());
-  }
-
-  /** {@inheritDoc} */
-  @Override public void savePreferenceValue() {
-    enabled.value(codeGeneration.isEnabled());
-    outputDirectory.value(codeGeneration.outputDirectory());
-  }
-
-  static class BindingBuilder {
-    private final CodeGenerationSetting codeGeneration;
-
-    BindingBuilder(CodeGenerationSetting codeGeneration) {
-      this.codeGeneration = codeGeneration;
-    }
-
-    BindingToCodeGeneration to(BooleanPreference enabled, StringPreference outputDirectory) {
-      return new BindingToCodeGeneration(codeGeneration, enabled, outputDirectory);
-    }
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationEditor.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationEditor.java
deleted file mode 100644
index 086924f..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationEditor.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.Messages.*;
-import static org.eclipse.jface.window.Window.OK;
-
-import java.util.*;
-import java.util.List;
-
-import org.eclipse.jface.viewers.*;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.xtext.ui.PluginImageHelper;
-
-import com.google.eclipse.protobuf.ui.preferences.DataChangedListener;
-
-/**
- * Editor where users can specify which are the target languages for protoc and the location of the output folders for
- * each language.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class CodeGenerationEditor extends Composite {
-
-  private final Table tblCodeGenerationOptions;
-  private final TableViewer tblVwrCodeGenerationOptions;
-  private final Button btnEdit;
-
-  private final List<CodeGenerationSetting> settings = new ArrayList<CodeGenerationSetting>();
-
-  private DataChangedListener dataChangedListener;
-
-  public CodeGenerationEditor(Composite parent, final PluginImageHelper imageHelper) {
-    super(parent, SWT.NONE);
-    setLayout(new GridLayout(1, false));
-
-    tblVwrCodeGenerationOptions = new TableViewer(this, SWT.BORDER | SWT.FULL_SELECTION);
-
-    tblCodeGenerationOptions = tblVwrCodeGenerationOptions.getTable();
-    tblCodeGenerationOptions.setHeaderVisible(true);
-    tblCodeGenerationOptions.setLinesVisible(true);
-    tblCodeGenerationOptions.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
-
-    TableViewerColumn tblclmnVwrEnabled = new TableViewerColumn(tblVwrCodeGenerationOptions, SWT.NONE);
-    TableColumn tblclmnEnabled = tblclmnVwrEnabled.getColumn();
-    tblclmnEnabled.setResizable(false);
-    tblclmnEnabled.setWidth(27);
-    tblclmnVwrEnabled.setLabelProvider(new ColumnLabelProvider() {
-      @Override public String getText(Object element) {
-        return "";
-      }
-
-      @Override public Image getImage(Object element) {
-        boolean optionEnabled = ((CodeGenerationSetting)element).isEnabled();
-        return imageHelper.getImage(optionEnabled ? "checked.gif" : "unchecked.gif");
-      }
-    });
-
-    TableViewerColumn tblclmnVwrLanguage = new TableViewerColumn(tblVwrCodeGenerationOptions, SWT.NONE);
-    TableColumn tblclmnLanguage = tblclmnVwrLanguage.getColumn();
-    tblclmnLanguage.setResizable(false);
-    tblclmnLanguage.setWidth(100);
-    tblclmnLanguage.setText(language);
-    tblclmnVwrLanguage.setLabelProvider(new ColumnLabelProvider() {
-      @Override public String getText(Object element) {
-        return ((CodeGenerationSetting)element).language().name();
-      }
-    });
-
-    TableViewerColumn tblclmnVwrOutputDirectory = new TableViewerColumn(tblVwrCodeGenerationOptions, SWT.NONE);
-    TableColumn tblclmnOutputDirectory = tblclmnVwrOutputDirectory.getColumn();
-    tblclmnOutputDirectory.setResizable(false);
-    tblclmnOutputDirectory.setWidth(100);
-    tblclmnOutputDirectory.setText(outputDirectory);
-    tblclmnVwrOutputDirectory.setLabelProvider(new ColumnLabelProvider() {
-      @Override public String getText(Object element) {
-        return ((CodeGenerationSetting)element).outputDirectory();
-      }
-    });
-
-    btnEdit = new Button(this, SWT.NONE);
-    btnEdit.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-    btnEdit.setText(editSelected);
-
-    tblVwrCodeGenerationOptions.setContentProvider(ArrayContentProvider.getInstance());
-
-    addEventListeners();
-    updateTable();
-  }
-
-  private void addEventListeners() {
-    tblCodeGenerationOptions.addSelectionListener(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        btnEdit.setEnabled(tblCodeGenerationOptions.getSelectionIndex() > -1);
-      }
-    });
-    btnEdit.addSelectionListener(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        int selectionIndex = tblCodeGenerationOptions.getSelectionIndex();
-        CodeGenerationSetting option = settings.get(selectionIndex);
-        EditCodeGenerationDialog dialog = new EditCodeGenerationDialog(getShell(), option);
-        if (dialog.open() == OK) {
-          tblVwrCodeGenerationOptions.refresh();
-          if (dataChangedListener != null) {
-            dataChangedListener.dataChanged();
-          }
-        }
-      }
-    });
-  }
-
-  public void codeGenerationSettings(CodeGenerationSettings newSettings) {
-    settings.clear();
-    settings.addAll(newSettings.allSettings());
-    updateTable();
-  }
-
-  private void updateTable() {
-    tblVwrCodeGenerationOptions.setInput(settings);
-    if (!settings.isEmpty()) {
-      tblCodeGenerationOptions.setSelection(0);
-    }
-  }
-
-  /** {@inheritDoc} */
-  @Override public void setEnabled(boolean enabled) {
-    tblCodeGenerationOptions.setEnabled(enabled);
-    btnEdit.setEnabled(enabled);
-    super.setEnabled(enabled);
-  }
-
-  public void setDataChangedListener(DataChangedListener listener) {
-    dataChangedListener = listener;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationSetting.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationSetting.java
deleted file mode 100644
index f945352..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationSetting.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-/**
- * Indicates whether code generation for a specific language is enabled and where the generated code should be placed.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class CodeGenerationSetting {
-
-  private final SupportedLanguage language;
-
-  private String outputDirectory;
-  private boolean enabled;
-
-  CodeGenerationSetting(SupportedLanguage language) {
-    this.language = language;
-  }
-
-  /**
-   * Returns the supported language.
-   * @return the supported language.
-   */
-  public SupportedLanguage language() {
-    return language;
-  }
-
-  /**
-   * Returns the name of the output directory.
-   * @return the name of the output directory.
-   */
-  public String outputDirectory() {
-    return outputDirectory;
-  }
-
-  /**
-   * Indicates whether the language in this preference is enabled or not.
-   * @return {@code true} if the language is enabled; {@code false} otherwise.
-   */
-  public boolean isEnabled() {
-    return enabled;
-  }
-
-  /**
-   * Updates the name of the output directory.
-   * @param newVal the new name.
-   */
-  public void outputDirectory(String newVal) {
-    outputDirectory = newVal;
-  }
-
-  /**
-   * Enables or disables the language in this preference.
-   * @param newVal indicates whether the language is enabled or not.
-   */
-  public void enabled(boolean newVal) {
-    enabled = newVal;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationSettings.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationSettings.java
deleted file mode 100644
index 30415e5..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationSettings.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.SupportedLanguage.*;
-import static java.util.Arrays.asList;
-import static java.util.Collections.unmodifiableList;
-
-import java.util.List;
-
-/**
- * All the supported <code>{@link CodeGenerationSetting}</code>s.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class CodeGenerationSettings {
-
-  private final CodeGenerationSetting java;
-  private final CodeGenerationSetting cpp;
-  private final CodeGenerationSetting python;
-
-  private final List<CodeGenerationSetting> allSettings;
-
-  CodeGenerationSettings() {
-    java = new CodeGenerationSetting(JAVA);
-    cpp = new CodeGenerationSetting(CPP);
-    python = new CodeGenerationSetting(PYTHON);
-    allSettings = unmodifiableList(asList(java, cpp, python));
-  }
-
-  /**
-   * Returns the settings for code generation using Java.
-   * @return the settings for code generation using Java.
-   */
-  public CodeGenerationSetting java() {
-    return java;
-  }
-
-  /**
-   * Returns the settings for code generation using C++.
-   * @return the settings for code generation using C++.
-   */
-  public CodeGenerationSetting cpp() {
-    return cpp;
-  }
-
-  /**
-   * Returns the settings for code generation using Python.
-   * @return the settings for code generation using Python.
-   */
-  public CodeGenerationSetting python() {
-    return python;
-  }
-
-  /**
-   * Returns all the settings for code generation using all supported languages.
-   * @return all the settings for code generation using all supported languages.
-   */
-  public List<CodeGenerationSetting> allSettings() {
-    return allSettings;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencePage.java
deleted file mode 100644
index 88ea122..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencePage.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import static com.google.eclipse.protobuf.ui.preferences.Buttons.with;
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToButtonSelection.bindSelectionOf;
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToTextValue.bindTextOf;
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.BindingToCodeGeneration.bindCodeGeneration;
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.EnableProjectSettingsPreference.enableProjectSettings;
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.Messages.*;
-import static com.google.eclipse.protobuf.ui.swt.Colors.widgetBackground;
-import static org.eclipse.xtext.util.Strings.isEmpty;
-
-import java.io.File;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.xtext.ui.PluginImageHelper;
-
-import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.binding.PreferenceBinder;
-import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
-import com.google.inject.Inject;
-
-/**
- * Preference page for protobuf compiler.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class CompilerPreferencePage extends PreferenceAndPropertyPage {
-
-  private static final String PREFERENCE_PAGE_ID = CompilerPreferencePage.class.getName();
-
-  private Button btnCompileProtoFiles;
-  private TabFolder tabFolder;
-  private TabItem tbtmMain;
-  private TabItem tbtmRefresh;
-  private Group grpCompilerLocation;
-  private Button btnUseProtocInSystemPath;
-  private Button btnUseProtocInCustomPath;
-  private Text txtProtocFilePath;
-  private Button btnProtocPathBrowse;
-  private Group grpCodeGeneration;
-  private CodeGenerationEditor codeGenerationEditor;
-  private Button btnRefreshResources;
-  private Group grpRefresh;
-  private Button btnRefreshProject;
-  private Button btnRefreshOutputDirectory;
-  private Group grpDescriptorLocation;
-  private Text txtDescriptorFilePath;
-  private Button btnDescriptorPathBrowse;
-
-  @Inject private PluginImageHelper imageHelper;
-
-  private final CodeGenerationSettings codeGenerationSettings = new CodeGenerationSettings();
-
-  @Override protected void doCreateContents(Composite parent) {
-    btnCompileProtoFiles = new Button(parent, SWT.CHECK);
-    btnCompileProtoFiles.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
-    btnCompileProtoFiles.setText(compileOnSave);
-
-    tabFolder = new TabFolder(parent, SWT.NONE);
-    tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
-
-    tbtmMain = new TabItem(tabFolder, SWT.NONE);
-    tbtmMain.setText(tabMain);
-
-    Composite cmpMain = new Composite(tabFolder, SWT.NONE);
-    tbtmMain.setControl(cmpMain);
-    cmpMain.setLayout(new GridLayout(1, false));
-
-    grpCompilerLocation = new Group(cmpMain, SWT.NONE);
-    grpCompilerLocation.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-    grpCompilerLocation.setLayout(new GridLayout(2, false));
-    grpCompilerLocation.setText(protocLocation);
-
-    btnUseProtocInSystemPath = new Button(grpCompilerLocation, SWT.RADIO);
-    btnUseProtocInSystemPath.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
-    btnUseProtocInSystemPath.setText(protocInSystemPath);
-
-    btnUseProtocInCustomPath = new Button(grpCompilerLocation, SWT.RADIO);
-    btnUseProtocInCustomPath.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
-    btnUseProtocInCustomPath.setText(protocInCustomPath);
-
-    txtProtocFilePath = new Text(grpCompilerLocation, SWT.BORDER);
-    txtProtocFilePath.setBackground(widgetBackground());
-    txtProtocFilePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-    txtProtocFilePath.setEditable(false);
-
-    btnProtocPathBrowse = new Button(grpCompilerLocation, SWT.NONE);
-    btnProtocPathBrowse.setText(browseCustomPath);
-
-    grpDescriptorLocation = new Group(cmpMain, SWT.NONE);
-    grpDescriptorLocation.setText(descriptorLocation);
-    grpDescriptorLocation.setLayout(new GridLayout(2, false));
-    grpDescriptorLocation.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-
-    txtDescriptorFilePath = new Text(grpDescriptorLocation, SWT.BORDER);
-    txtDescriptorFilePath.setBackground(widgetBackground());
-    txtDescriptorFilePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-    txtDescriptorFilePath.setEditable(false);
-
-    btnDescriptorPathBrowse = new Button(grpDescriptorLocation, SWT.NONE);
-    btnDescriptorPathBrowse.setText(browseCustomPath);
-
-    grpCodeGeneration = new Group(cmpMain, SWT.NONE);
-    grpCodeGeneration.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-    grpCodeGeneration.setText(codeGeneration);
-    grpCodeGeneration.setLayout(new GridLayout(1, false));
-
-    codeGenerationEditor = new CodeGenerationEditor(grpCodeGeneration, imageHelper);
-    codeGenerationEditor.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
-
-    tbtmRefresh = new TabItem(tabFolder, SWT.NONE);
-    tbtmRefresh.setText(tabRefresh);
-
-    Composite cmpRefresh = new Composite(tabFolder, SWT.NONE);
-    tbtmRefresh.setControl(cmpRefresh);
-    cmpRefresh.setLayout(new GridLayout(1, false));
-
-    btnRefreshResources = new Button(cmpRefresh, SWT.CHECK);
-    btnRefreshResources.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-    btnRefreshResources.setText(refreshResources);
-
-    grpRefresh = new Group(cmpRefresh, SWT.NONE);
-    grpRefresh.setLayout(new GridLayout(1, false));
-    grpRefresh.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-
-    btnRefreshProject = new Button(grpRefresh, SWT.RADIO);
-    btnRefreshProject.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-    btnRefreshProject.setText(refreshProject);
-
-    btnRefreshOutputDirectory = new Button(grpRefresh, SWT.RADIO);
-    btnRefreshOutputDirectory.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-    btnRefreshOutputDirectory.setText(refreshOutputProject);
-    new Label(parent, SWT.NONE);
-
-    addEventListeners();
-  }
-
-  private void addEventListeners() {
-    btnCompileProtoFiles.addSelectionListener(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        boolean selected = btnCompileProtoFiles.getSelection();
-        enableCompilerOptions(selected);
-        checkState();
-      }
-    });
-    with(btnUseProtocInCustomPath, btnUseProtocInSystemPath).add(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        boolean selected = btnUseProtocInCustomPath.getSelection();
-        enableCompilerCustomPathOptions(selected);
-        checkState();
-      }
-    });
-    btnProtocPathBrowse.addSelectionListener(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.SHEET);
-        String file = dialog.open();
-        if (file != null) {
-          txtProtocFilePath.setText(file);
-        }
-        checkState();
-      }
-    });
-    btnDescriptorPathBrowse.addSelectionListener(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.SHEET);
-        dialog.setFilterExtensions(new String[] { "*.proto" });
-        String file = dialog.open();
-        if (file != null) {
-          txtDescriptorFilePath.setText(file);
-        }
-        checkState();
-      }
-    });
-    btnRefreshResources.addSelectionListener(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        refreshResourcesOptionsEnabled(btnRefreshResources.getSelection());
-      }
-    });
-    codeGenerationEditor.setDataChangedListener(new DataChangedListener() {
-      @Override public void dataChanged() {
-        checkState();
-      }
-    });
-  }
-
-  private void checkState() {
-    boolean atLeastOneLanguageEnabled = false;
-    for (CodeGenerationSetting option : codeGenerationSettings.allSettings()) {
-      if (option.isEnabled()) {
-        atLeastOneLanguageEnabled = true;
-        break;
-      }
-    }
-    if (!atLeastOneLanguageEnabled) {
-      pageIsNowInvalid(errorNoLanguageEnabled);
-      return;
-    }
-    if (customPathOptionSelectedAndEnabled()) {
-      String protocPath = txtProtocFilePath.getText();
-      if (isEmpty(protocPath)) {
-        pageIsNowInvalid(errorNoSelection);
-        return;
-      }
-      File protoc = new File(protocPath);
-      if (!protoc.isFile()) {
-        pageIsNowInvalid(errorInvalidProtoc);
-        return;
-      }
-    }
-    String descriptorPath = txtDescriptorFilePath.getText();
-    if (!isEmpty(descriptorPath) && !isFileWithName(descriptorPath, "descriptor.proto")) {
-      pageIsNowInvalid(errorInvalidDescriptor);
-      return;
-    }
-    pageIsNowValid();
-  }
-
-  private boolean isFileWithName(String filePath, String expectedFileName) {
-    File file = new File(filePath);
-    if (!file.isFile()) {
-      return false;
-    }
-    String fileName = file.getName();
-    return expectedFileName.equals(fileName);
-  }
-
-  @Override protected BooleanPreference enableProjectSettingsPreference(IPreferenceStore store) {
-    return enableProjectSettings(store);
-  }
-
-  @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
-    RawPreferences preferences = new RawPreferences(getPreferenceStore());
-    preferenceBinder.addAll(
-        bindSelectionOf(btnCompileProtoFiles).to(preferences.compileProtoFiles()),
-        bindSelectionOf(btnUseProtocInSystemPath).to(preferences.useProtocInSystemPath()),
-        bindSelectionOf(btnUseProtocInCustomPath).to(preferences.useProtocInCustomPath()),
-        bindTextOf(txtProtocFilePath).to(preferences.protocPath()),
-        bindTextOf(txtDescriptorFilePath).to(preferences.descriptorPath()),
-        bindSelectionOf(btnRefreshResources).to(preferences.refreshResources()),
-        bindSelectionOf(btnRefreshProject).to(preferences.refreshProject()),
-        bindSelectionOf(btnRefreshOutputDirectory).to(preferences.refreshOutputDirectory()),
-        bindCodeGeneration(codeGenerationSettings.java())
-          .to(preferences.javaCodeGenerationEnabled(), preferences.javaOutputDirectory()),
-        bindCodeGeneration(codeGenerationSettings.cpp())
-          .to(preferences.cppCodeGenerationEnabled(), preferences.cppOutputDirectory()),
-        bindCodeGeneration(codeGenerationSettings.python())
-          .to(preferences.pythonCodeGenerationEnabled(), preferences.pythonOutputDirectory())
-      );
-  }
-
-  @Override protected void updateContents() {
-    boolean compileProtoFiles = btnCompileProtoFiles.getSelection();
-    boolean shouldEnableCompilerOptions = compileProtoFiles;
-    if (isPropertyPage()) {
-      boolean useProjectSettings = areProjectSettingsActive();
-      activateProjectSettings(useProjectSettings);
-      enableProjectSpecificOptions(useProjectSettings);
-      shouldEnableCompilerOptions = shouldEnableCompilerOptions && useProjectSettings;
-    }
-    enableCompilerOptions(shouldEnableCompilerOptions);
-    codeGenerationEditor.codeGenerationSettings(codeGenerationSettings);
-  }
-
-  @Override protected void onProjectSettingsActivation(boolean active) {
-    enableProjectSpecificOptions(active);
-    enableCompilerOptions(isEnabledAndSelected(btnCompileProtoFiles));
-  }
-
-  private void enableProjectSpecificOptions(boolean isEnabled) {
-    btnCompileProtoFiles.setEnabled(isEnabled);
-  }
-
-  private void enableCompilerOptions(boolean isEnabled) {
-    tabFolder.setEnabled(isEnabled);
-    enableCompilerPathOptions(isEnabled);
-    enableDescriptorPathOptions(isEnabled);
-    enableOutputOptions(isEnabled);
-    enableRefreshOptions(isEnabled);
-  }
-
-  private void enableCompilerPathOptions(boolean isEnabled) {
-    grpCompilerLocation.setEnabled(isEnabled);
-    btnUseProtocInSystemPath.setEnabled(isEnabled);
-    btnUseProtocInCustomPath.setEnabled(isEnabled);
-    enableCompilerCustomPathOptions(customPathOptionSelectedAndEnabled());
-  }
-
-  private void enableCompilerCustomPathOptions(boolean isEnabled) {
-    txtProtocFilePath.setEnabled(isEnabled);
-    btnProtocPathBrowse.setEnabled(isEnabled);
-  }
-
-  private void enableDescriptorPathOptions(boolean isEnabled) {
-    grpDescriptorLocation.setEnabled(isEnabled);
-    txtDescriptorFilePath.setEnabled(isEnabled);
-    btnDescriptorPathBrowse.setEnabled(isEnabled);
-  }
-
-  private boolean customPathOptionSelectedAndEnabled() {
-    return isEnabledAndSelected(btnUseProtocInCustomPath);
-  }
-
-  private boolean isEnabledAndSelected(Button b) {
-    return b.isEnabled() && b.getSelection();
-  }
-
-  private void enableOutputOptions(boolean isEnabled) {
-    grpCodeGeneration.setEnabled(isEnabled);
-    codeGenerationEditor.setEnabled(isEnabled);
-  }
-
-  private void enableRefreshOptions(boolean isEnabled) {
-    btnRefreshResources.setEnabled(isEnabled);
-    refreshResourcesOptionsEnabled(isEnabledAndSelected(btnRefreshResources));
-  }
-
-  private void refreshResourcesOptionsEnabled(boolean isEnabled) {
-    grpRefresh.setEnabled(isEnabled);
-    btnRefreshProject.setEnabled(isEnabled);
-    btnRefreshOutputDirectory.setEnabled(isEnabled);
-  }
-
-  @Override protected String preferencePageId() {
-    return PREFERENCE_PAGE_ID;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferenceStoreInitializer.java
deleted file mode 100644
index f54e452..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferenceStoreInitializer.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.EnableProjectSettingsPreference.enableProjectSettings;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.*;
-
-/**
- * Initializes default values for the "Compiler" preferences.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class CompilerPreferenceStoreInitializer implements IPreferenceStoreInitializer {
-
-  private static final String DEFAULT_OUTPUT_DIRECTORY = "src-gen";
-
-  /** {@inheritDoc} */
-  @Override public void initialize(IPreferenceStoreAccess access) {
-    IPreferenceStore store = access.getWritablePreferenceStore();
-    enableProjectSettings(store).defaultValue(false);
-    RawPreferences preferences = new RawPreferences(store);
-    preferences.useProtocInSystemPath().defaultValue(true);
-    preferences.javaCodeGenerationEnabled().defaultValue(false);
-    preferences.cppCodeGenerationEnabled().defaultValue(false);
-    preferences.pythonCodeGenerationEnabled().defaultValue(false);
-    preferences.javaOutputDirectory().defaultValue(DEFAULT_OUTPUT_DIRECTORY);
-    preferences.cppOutputDirectory().defaultValue(DEFAULT_OUTPUT_DIRECTORY);
-    preferences.pythonOutputDirectory().defaultValue(DEFAULT_OUTPUT_DIRECTORY);
-    preferences.refreshResources().defaultValue(true);
-    preferences.refreshOutputDirectory().defaultValue(true);
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferences.java
deleted file mode 100644
index ed01b7a..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferences.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.PostCompilationRefreshTarget.*;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * Compiler preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class CompilerPreferences {
-
-  private final boolean compileProtoFiles;
-  private final String protocPath;
-  private final String descriptorPath;
-  private final CodeGenerationSettings codeGenerationSettings;
-  private final boolean refreshResources;
-  private final PostCompilationRefreshTarget refreshTarget;
-
-  CompilerPreferences(RawPreferences preferences) {
-    compileProtoFiles = preferences.compileProtoFiles().value();
-    boolean useProtocInSystemPath = preferences.useProtocInSystemPath().value();
-    protocPath = (useProtocInSystemPath) ? "protoc" : preferences.protocPath().value();
-    descriptorPath = preferences.descriptorPath().value();
-    codeGenerationSettings = new CodeGenerationSettings();
-    codeGenerationSettings.java().enabled(preferences.javaCodeGenerationEnabled().value());
-    codeGenerationSettings.java().outputDirectory(preferences.javaOutputDirectory().value());
-    codeGenerationSettings.cpp().enabled(preferences.cppCodeGenerationEnabled().value());
-    codeGenerationSettings.cpp().outputDirectory(preferences.cppOutputDirectory().value());
-    codeGenerationSettings.python().enabled(preferences.pythonCodeGenerationEnabled().value());
-    codeGenerationSettings.python().outputDirectory(preferences.pythonOutputDirectory().value());
-    refreshResources = preferences.refreshResources().value();
-    boolean refreshProject = preferences.refreshProject().value();
-    refreshTarget = refreshProject ? PROJECT : OUTPUT_DIRECTORIES;
-  }
-
-  public boolean shouldCompileProtoFiles() {
-    return compileProtoFiles;
-  }
-
-  public String protocPath() {
-    return protocPath;
-  }
-
-  public String descriptorPath() {
-    return descriptorPath;
-  }
-
-  public CodeGenerationSettings codeGenerationSettings() {
-    return codeGenerationSettings;
-  }
-
-  public boolean shouldRefreshResources() {
-    return refreshResources;
-  }
-
-  public PostCompilationRefreshTarget refreshTarget() {
-    return refreshTarget;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencesFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencesFactory.java
deleted file mode 100644
index dbb8d67..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencesFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.EnableProjectSettingsPreference.enableProjectSettings;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-
-import com.google.inject.Inject;
-
-/**
- * Factory of <code>{@link CompilerPreferences}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class CompilerPreferencesFactory {
-
-  @Inject private IPreferenceStoreAccess storeAccess;
-
-  public CompilerPreferences preferences(IProject project) {
-    IPreferenceStore store = storeAccess.getWritablePreferenceStore(project);
-    boolean useProjectPreferences = enableProjectSettings(store).value();
-    if (!useProjectPreferences) {
-      store = storeAccess.getWritablePreferenceStore();
-    }
-    return new CompilerPreferences(new RawPreferences(store));
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/EditCodeGenerationDialog.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/EditCodeGenerationDialog.java
deleted file mode 100644
index 4dee583..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/EditCodeGenerationDialog.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.Messages.*;
-import static com.google.eclipse.protobuf.ui.swt.Colors.widgetBackground;
-import static com.google.eclipse.protobuf.ui.util.Paths.segmentsOf;
-import static org.eclipse.core.resources.IResource.FOLDER;
-import static org.eclipse.jface.dialogs.IDialogConstants.OK_ID;
-import static org.eclipse.swt.layout.GridData.*;
-import static org.eclipse.xtext.util.Strings.isEmpty;
-
-import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.*;
-
-import com.google.eclipse.protobuf.ui.preferences.InputDialog;
-
-/**
- * Dialog where users can edit a single code generation option.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class EditCodeGenerationDialog extends InputDialog {
-
-  private final CodeGenerationSetting option;
-
-  private Text txtOutputDirectory;
-  private Button btnEnabled;
-  private Text txtError;
-
-  /**
-   * Creates a new </code>{@link EditCodeGenerationDialog}</code>.
-   * @param parent a shell which will be the parent of the new instance.
-   * @param option the code generation option to edit.
-   */
-  public EditCodeGenerationDialog(Shell parent, CodeGenerationSetting option) {
-    super(parent, editCodeGenerationOptionTitle + option.language().name());
-    this.option = option;
-  }
-
-  /** {@inheritDoc} */
-  @Override protected Control createDialogArea(Composite parent) {
-    Composite cmpDialogArea = (Composite) super.createDialogArea(parent);
-
-    btnEnabled = new Button(cmpDialogArea, SWT.CHECK);
-    btnEnabled.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
-    btnEnabled.setText(enabled);
-    btnEnabled.setSelection(option.isEnabled());
-
-    Label lblOutputDirectoryName = new Label(cmpDialogArea, SWT.NONE);
-    lblOutputDirectoryName.setText(outputDirectoryPrompt);
-
-    txtOutputDirectory = new Text(cmpDialogArea, SWT.BORDER);
-    txtOutputDirectory.setEnabled(option.isEnabled());
-
-    GridData gd_txtOutputDirectory = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1);
-    gd_txtOutputDirectory.widthHint = 200;
-    txtOutputDirectory.setLayoutData(gd_txtOutputDirectory);
-    txtOutputDirectory.setText(option.outputDirectory());
-
-    txtError = new Text(cmpDialogArea, SWT.READ_ONLY | SWT.WRAP);
-    GridData gridData = new GridData(GRAB_HORIZONTAL | HORIZONTAL_ALIGN_FILL);
-    gridData.horizontalSpan = 2;
-    txtError.setLayoutData(gridData);
-    txtError.setBackground(widgetBackground());
-
-    addEventListeners();
-
-    applyDialogFont(cmpDialogArea);
-    return cmpDialogArea;
-  }
-
-  private void addEventListeners() {
-    btnEnabled.addSelectionListener(new SelectionAdapter() {
-      @Override public void widgetSelected(SelectionEvent e) {
-        txtOutputDirectory.setEnabled(btnEnabled.getSelection());
-        checkState();
-      }
-    });
-    txtOutputDirectory.addModifyListener(new ModifyListener() {
-      @Override public void modifyText(ModifyEvent e) {
-        checkState();
-      }
-    });
-  }
-
-  private void checkState() {
-    if (btnEnabled.getSelection()) {
-      if (!outputDirectoryEntered()) {
-        pageIsNowInvalid(errorEnterDirectoryName);
-        return;
-      }
-      String errorMessage = validateDirectoryName(enteredOuptutDirectory());
-      if (errorMessage != null) {
-        pageIsNowInvalid(errorMessage);
-        return;
-      }
-    }
-    pageIsNowValid();
-  }
-
-  private String validateDirectoryName(String directoryName) {
-    IWorkspace workspace = ResourcesPlugin.getWorkspace();
-    for (String segment : segmentsOf(directoryName)) {
-      IStatus isValid = workspace.validateName(segment, FOLDER);
-      if (isValid.getCode() == OK) {
-        continue;
-      }
-      return isValid.getMessage();
-    }
-    return null;
-  }
-
-  private void pageIsNowInvalid(String errorMessage) {
-    txtError.setText(errorMessage);
-    getButton(OK_ID).setEnabled(false);
-  }
-
-  private void pageIsNowValid() {
-    txtError.setText("");
-    getButton(OK_ID).setEnabled(true);
-  }
-
-  /** {@inheritDoc} */
-  @Override protected void okPressed() {
-    option.enabled(btnEnabled.getSelection());
-    option.outputDirectory(enteredOuptutDirectory());
-    super.okPressed();
-  }
-
-  private boolean outputDirectoryEntered() {
-    return !isEmpty(enteredOuptutDirectory());
-  }
-
-  private String enteredOuptutDirectory() {
-    return txtOutputDirectory.getText().trim();
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/EnableProjectSettingsPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/EnableProjectSettingsPreference.java
deleted file mode 100644
index a21d9a8..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/EnableProjectSettingsPreference.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class EnableProjectSettingsPreference {
-
-  static BooleanPreference enableProjectSettings(IPreferenceStore store) {
-    return new BooleanPreference("compiler.enableProjectSettings", store);
-  }
-
-  private EnableProjectSettingsPreference() {}
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/PostCompilationRefreshTarget.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/PostCompilationRefreshTarget.java
deleted file mode 100644
index 2fb2cbf..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/PostCompilationRefreshTarget.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-/**
- * The type of resource to refresh after calling protoc.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public enum PostCompilationRefreshTarget {
-
-  PROJECT, OUTPUT_DIRECTORIES;
-
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/RawPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/RawPreferences.java
deleted file mode 100644
index 81945d0..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/RawPreferences.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
- * License v1.0 which accompanies this distribution, and is available at
- *
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import com.google.eclipse.protobuf.ui.preferences.*;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class RawPreferences {
-
-  private final BooleanPreference compileProtoFiles;
-  private final BooleanPreference useProtocInSystemPath;
-  private final BooleanPreference useProtocInCustomPath;
-  private final StringPreference protocPath;
-  private final StringPreference descriptorPath;
-  private final BooleanPreference javaCodeGenerationEnabled;
-  private final BooleanPreference cppCodeGenerationEnabled;
-  private final BooleanPreference pythonCodeGenerationEnabled;
-  private final StringPreference javaOutputDirectory;
-  private final StringPreference cppOutputDirectory;
-  private final StringPreference pythonOutputDirectory;
-  private final BooleanPreference refreshResources;
-  private final BooleanPreference refreshProject;
-  private final BooleanPreference refreshOutputDirectory;
-
-  RawPreferences(IPreferenceStore store) {
-    compileProtoFiles = new BooleanPreference("compiler.compileProtoFiles", store);
-    useProtocInSystemPath = new BooleanPreference("compiler.useProtocInSystemPath", store);
-    useProtocInCustomPath = new BooleanPreference("compiler.useProtocInCustomPath", store);
-    protocPath = new StringPreference("compiler.protocFilePath", store);
-    descriptorPath = new StringPreference("compiler.descriptorFilePath", store);
-    javaCodeGenerationEnabled = new BooleanPreference("compiler.javaCodeGenerationEnabled", store);
-    cppCodeGenerationEnabled = new BooleanPreference("compiler.cppCodeGenerationEnabled", store);
-    pythonCodeGenerationEnabled = new BooleanPreference("compiler.pythonCodeGenerationEnabled", store);
-    javaOutputDirectory = new StringPreference("compiler.javaOutputDirectory", store);
-    cppOutputDirectory = new StringPreference("compiler.cppOutputDirectory", store);
-    pythonOutputDirectory = new StringPreference("compiler.pythonOutputDirectory", store);
-    refreshResources = new BooleanPreference("compiler.refreshResources", store);
-    refreshProject = new BooleanPreference("compiler.refreshProject", store);
-    refreshOutputDirectory = new BooleanPreference("compiler.refreshOutputDirectory", store);
-  }
-
-  BooleanPreference compileProtoFiles() {
-    return compileProtoFiles;
-  }
-
-  BooleanPreference useProtocInSystemPath() {
-    return useProtocInSystemPath;
-  }
-
-  BooleanPreference useProtocInCustomPath() {
-    return useProtocInCustomPath;
-  }
-
-  StringPreference protocPath() {
-    return protocPath;
-  }
-
-  StringPreference descriptorPath() {
-    return descriptorPath;
-  }
-
-  BooleanPreference javaCodeGenerationEnabled() {
-    return javaCodeGenerationEnabled;
-  }
-
-  BooleanPreference cppCodeGenerationEnabled() {
-    return cppCodeGenerationEnabled;
-  }
-
-  BooleanPreference pythonCodeGenerationEnabled() {
-    return pythonCodeGenerationEnabled;
-  }
-
-  StringPreference javaOutputDirectory() {
-    return javaOutputDirectory;
-  }
-
-  StringPreference cppOutputDirectory() {
-    return cppOutputDirectory;
-  }
-
-  StringPreference pythonOutputDirectory() {
-    return pythonOutputDirectory;
-  }
-
-  BooleanPreference refreshResources() {
-    return refreshResources;
-  }
-
-  BooleanPreference refreshProject() {
-    return refreshProject;
-  }
-
-  BooleanPreference refreshOutputDirectory() {
-    return refreshOutputDirectory;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/SupportedLanguage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/SupportedLanguage.java
deleted file mode 100644
index 365f94b..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/SupportedLanguage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
-
-
-/**
- * Languages supported by protoc.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class SupportedLanguage {
-
-  public static final SupportedLanguage JAVA = new SupportedLanguage("Java", "java");
-  public static final SupportedLanguage CPP = new SupportedLanguage("C++", "cpp");
-  public static final SupportedLanguage PYTHON = new SupportedLanguage("Python", "python");
-
-  private final String name;
-  private final String code;
-
-  private SupportedLanguage(String name, String code) {
-    this.name = name;
-    this.code = code;
-  }
-
-  /**
-   * Returns this language's name.
-   * @return this language's name.
-   */
-  public String name() {
-    return name;
-  }
-
-  /**
-   * Returns this language's code.
-   * @return this language's code.
-   */
-  public String code() {
-    return code;
-  }
-
-  /**
-   * Returns all the supported languages.
-   * @return all the supported languages.
-   */
-  public static SupportedLanguage[] values() {
-    return new SupportedLanguage[] { JAVA, CPP, PYTHON };
-  }
-}
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferenceStoreInitializer.java
deleted file mode 100644
index add22e0..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferenceStoreInitializer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
-
-import static java.util.Collections.singletonList;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.*;
-
-/**
- * Initializes default values for the "Paths" preferences.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class NumericTagPreferenceStoreInitializer implements IPreferenceStoreInitializer {
-
-  /** {@inheritDoc} */
-  @Override public void initialize(IPreferenceStoreAccess access) {
-    IPreferenceStore store = access.getWritablePreferenceStore();
-    RawPreferences preferences = new RawPreferences(store);
-    preferences.patterns().defaultValue(singletonList("Next[\\s]+Id:[\\s]+[\\d]+"));
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferences.java
deleted file mode 100644
index 2113421..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferences.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
-
-import java.util.List;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * "Numeric tag" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class NumericTagPreferences {
-
-  private final List<String> patterns;
-
-  NumericTagPreferences(RawPreferences preferences) {
-    patterns = preferences.patterns().value();
-  }
-
-  public List<String> patterns() {
-    return patterns;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencesFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencesFactory.java
deleted file mode 100644
index f7163a9..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencesFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-
-import com.google.inject.Inject;
-
-/**
- * Factory of <code>{@link NumericTagPreferences}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class NumericTagPreferencesFactory {
-
-  @Inject private IPreferenceStoreAccess storeAccess;
-
-  public NumericTagPreferences preferences() {
-    IPreferenceStore store = storeAccess.getWritablePreferenceStore();
-    return new NumericTagPreferences(new RawPreferences(store));
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/RawPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/RawPreferences.java
deleted file mode 100644
index f414aab..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/RawPreferences.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * All rights reserved. This program and the accompanying materials are made
- * available under the terms of the Eclipse License v1.0 which accompanies this
- * distribution, and is available at
- *
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import com.google.eclipse.protobuf.ui.preferences.StringListPreference;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class RawPreferences {
-
-  private final StringListPreference patterns;
-
-  RawPreferences(IPreferenceStore store) {
-    patterns = new StringListPreference("numericTag.patterns", "\\t", store);
-  }
-
-  StringListPreference patterns() {
-    return patterns;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/RawPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/RawPreferences.java
deleted file mode 100644
index ad731dc..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/RawPreferences.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * All rights reserved. This program and the accompanying materials are made
- * available under the terms of the Eclipse License v1.0 which accompanies this
- * distribution, and is available at
- *
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.save;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class RawPreferences {
-
-  private final BooleanPreference removeTrailingWhitespace;
-  private final BooleanPreference inAllLines;
-  private final BooleanPreference inEditedLines;
-
-  RawPreferences(IPreferenceStore store) {
-    removeTrailingWhitespace = new BooleanPreference("saveActions.removeTrailingWhitespace", store);
-    inAllLines = new BooleanPreference("saveActions.inAllLines", store);
-    inEditedLines = new BooleanPreference("saveActions.inEditedLines", store);
-  }
-
-  BooleanPreference removeTrailingWhitespace() {
-    return removeTrailingWhitespace;
-  }
-
-  BooleanPreference inAllLines() {
-    return inAllLines;
-  }
-
-  BooleanPreference inEditedLines() {
-    return inEditedLines;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferenceStoreInitializer.java
deleted file mode 100644
index 62f71c3..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferenceStoreInitializer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.save;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.*;
-
-/**
- * Initializes default values for the "Paths" preferences.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class SaveActionsPreferenceStoreInitializer implements IPreferenceStoreInitializer {
-
-  /** {@inheritDoc} */
-  @Override public void initialize(IPreferenceStoreAccess access) {
-    IPreferenceStore store = access.getWritablePreferenceStore();
-    RawPreferences preferences = new RawPreferences(store);
-    preferences.removeTrailingWhitespace().defaultValue(true);
-    preferences.inAllLines().defaultValue(false);
-    preferences.inEditedLines().defaultValue(true);
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferences.java
deleted file mode 100644
index e82434b..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferences.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.save;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * "Save actions" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class SaveActionsPreferences {
-
-  private final RemoveTrailingSpace removeTrailingSpace;
-
-  SaveActionsPreferences(RawPreferences preferences) {
-    removeTrailingSpace = RemoveTrailingSpace.valueFrom(preferences);
-  }
-
-  public RemoveTrailingSpace removeTrailingSpace() {
-    return removeTrailingSpace;
-  }
-
-  public static enum RemoveTrailingSpace {
-    NONE, IN_EDITED_LINES, IN_ALL_LINES;
-
-    static RemoveTrailingSpace valueFrom(RawPreferences preferences) {
-      if (!preferences.removeTrailingWhitespace().value()) {
-        return NONE;
-      }
-      return preferences.inEditedLines().value() ? IN_EDITED_LINES : IN_ALL_LINES;
-    }
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencesFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencesFactory.java
deleted file mode 100644
index 768c7c9..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencesFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.editor.save;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-
-import com.google.inject.Inject;
-
-/**
- * Factory of <code>{@link SaveActionsPreferences}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class SaveActionsPreferencesFactory {
-
-  @Inject private IPreferenceStoreAccess storeAccess;
-
-  public SaveActionsPreferences preferences() {
-    IPreferenceStore store = storeAccess.getWritablePreferenceStore();
-    return new SaveActionsPreferences(new RawPreferences(store));
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/EnableProjectSettingsPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/EnableProjectSettingsPreference.java
deleted file mode 100644
index 729f3b4..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/EnableProjectSettingsPreference.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.general;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class EnableProjectSettingsPreference {
-
-  static BooleanPreference enableProjectSettings(IPreferenceStore store) {
-    return new BooleanPreference("general.enableProjectSettings", store);
-  }
-
-  private EnableProjectSettingsPreference() {}
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferenceStoreInitializer.java
deleted file mode 100644
index 887192e..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferenceStoreInitializer.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.general;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.general.EnableProjectSettingsPreference.enableProjectSettings;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.*;
-
-/**
- * Initializes default values for the "Paths" preferences.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class GeneralPreferenceStoreInitializer implements IPreferenceStoreInitializer {
-
-  /** {@inheritDoc} */
-  @Override public void initialize(IPreferenceStoreAccess access) {
-    IPreferenceStore store = access.getWritablePreferenceStore();
-    enableProjectSettings(store).defaultValue(false);
-    RawPreferences preferences = new RawPreferences(store);
-    preferences.validateFilesOnActivation().defaultValue(true);
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferences.java
deleted file mode 100644
index fa96a0c..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferences.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.general;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * General preferences, retrieved from an <code>{@link IPreferenceStore}</code>. To create a new instance invoke
- * <code>{@link GeneralPreferencesFactory#preferences(IProject)}</code>
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class GeneralPreferences {
-
-  private final boolean validateFilesOnActivation;
-
-  GeneralPreferences(RawPreferences preferences) {
-    validateFilesOnActivation = preferences.validateFilesOnActivation().value();
-  }
-
-  public boolean validateFilesOnActivation() {
-    return validateFilesOnActivation;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferencesFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferencesFactory.java
deleted file mode 100644
index 51a1f73..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/GeneralPreferencesFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.general;
-
-import static com.google.eclipse.protobuf.ui.preferences.pages.general.EnableProjectSettingsPreference.enableProjectSettings;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-
-import com.google.inject.Inject;
-
-/**
- * Factory of <code>{@link GeneralPreferences}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class GeneralPreferencesFactory {
-
-  @Inject private IPreferenceStoreAccess storeAccess;
-
-  public GeneralPreferences preferences(IProject project) {
-    IPreferenceStore store = storeAccess.getWritablePreferenceStore(project);
-    boolean useProjectPreferences = enableProjectSettings(store).value();
-    if (!useProjectPreferences) {
-      store = storeAccess.getWritablePreferenceStore();
-    }
-    return new GeneralPreferences(new RawPreferences(store));
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/RawPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/RawPreferences.java
deleted file mode 100644
index 1297dfc..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/general/RawPreferences.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.preferences.pages.general;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class RawPreferences {
-
-  private final BooleanPreference validateFilesOnActivation;
-
-  RawPreferences(IPreferenceStore store) {
-    validateFilesOnActivation = new BooleanPreference("validation.validateFilesOnActivation", store);
-  }
-
-  BooleanPreference validateFilesOnActivation() {
-    return validateFilesOnActivation;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/AddDirectoryDialog.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/AddDirectoryDialog.java
index 1749c5c..b60de32 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/AddDirectoryDialog.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/AddDirectoryDialog.java
@@ -8,10 +8,10 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.pages.paths;
 
+import static com.google.eclipse.protobuf.ui.preferences.pages.TextWidgets.setEditable;
 import static com.google.eclipse.protobuf.ui.preferences.pages.paths.DirectorySelectionDialogs.*;
 import static com.google.eclipse.protobuf.ui.preferences.pages.paths.Messages.*;
 import static com.google.eclipse.protobuf.ui.preferences.pages.paths.ProjectVariable.useProjectVariable;
-import static com.google.eclipse.protobuf.ui.swt.Colors.widgetBackground;
 import static org.eclipse.jface.dialogs.IDialogConstants.OK_ID;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
@@ -22,7 +22,7 @@
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
-import com.google.eclipse.protobuf.ui.preferences.InputDialog;
+import com.google.eclipse.protobuf.ui.preferences.pages.InputDialog;
 
 /**
  * Dialog where users can select a path (in the workspace or file system) to be included in resolution of imports.
@@ -62,9 +62,8 @@
     label.setText(directory);
 
     txtPath = new Text(cmpDialogArea, SWT.BORDER);
-    txtPath.setBackground(widgetBackground());
     txtPath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
-    txtPath.setEditable(false);
+    setEditable(txtPath, false);
 
     Composite cmpCheckBox = new Composite(cmpDialogArea, SWT.NONE);
     cmpCheckBox.setEnabled(false);
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/DirectoryPathsEditor.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/DirectoryPathsEditor.java
index 46c8c94..f263259 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/DirectoryPathsEditor.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/DirectoryPathsEditor.java
@@ -24,7 +24,7 @@
 import org.eclipse.swt.widgets.*;
 import org.eclipse.xtext.ui.PluginImageHelper;
 
-import com.google.eclipse.protobuf.ui.preferences.DataChangedListener;
+import com.google.eclipse.protobuf.ui.preferences.pages.DataChangedListener;
 
 /**
  * Editor where users can add/remove the directories to be used for URI resolution.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java
index 4d95894..37d9954 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java
@@ -9,8 +9,8 @@
 package com.google.eclipse.protobuf.ui.preferences.pages.paths;
 
 import static com.google.eclipse.protobuf.ui.ProtobufUiModule.PLUGIN_ID;
-import static com.google.eclipse.protobuf.ui.preferences.Buttons.with;
-import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToButtonSelection.bindSelectionOf;
+import static com.google.eclipse.protobuf.ui.preferences.pages.ButtonGroup.with;
+import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 import static com.google.eclipse.protobuf.ui.preferences.pages.paths.Messages.*;
 import static java.util.Collections.unmodifiableList;
 import static org.eclipse.core.resources.IncrementalProjectBuilder.FULL_BUILD;
@@ -24,7 +24,6 @@
 import org.apache.log4j.Logger;
 import org.eclipse.core.runtime.*;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.layout.*;
@@ -32,8 +31,8 @@
 import org.eclipse.xtext.ui.PluginImageHelper;
 
 import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.binding.*;
-import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
+import com.google.eclipse.protobuf.ui.preferences.pages.*;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
 import com.google.eclipse.protobuf.ui.validation.ValidationTrigger;
 import com.google.inject.Inject;
 
@@ -110,7 +109,9 @@
     pageIsNowValid();
   }
 
-  @Override protected BooleanPreference enableProjectSettingsPreference(IPreferenceStore store) {
+
+
+  @Override protected String enableProjectSettingsPreferenceName() {
     return null; // this page is always a "Project Properties" page
   }
 
@@ -121,15 +122,15 @@
     final StringPreference directoryPaths = preferences.directoryPaths();
     preferenceBinder.add(new Binding() {
       @Override public void applyPreferenceValueToTarget() {
-        setDirectoryPaths(directoryPaths.value());
+        setDirectoryPaths(directoryPaths.getValue());
       }
 
       @Override public void applyDefaultPreferenceValueToTarget() {
-        setDirectoryPaths(directoryPaths.defaultValue());
+        setDirectoryPaths(directoryPaths.getDefaultValue());
       }
 
       @Override public void savePreferenceValue() {
-        directoryPaths.value(directoryNames());
+        directoryPaths.setValue(directoryNames());
       }
     });
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferenceStoreInitializer.java
index 5957532..3ffa066 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferenceStoreInitializer.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferenceStoreInitializer.java
@@ -22,8 +22,8 @@
   @Override public void initialize(IPreferenceStoreAccess access) {
     IPreferenceStore store = access.getWritablePreferenceStore();
     RawPreferences preferences = new RawPreferences(store);
-    preferences.filesInOneDirectoryOnly().defaultValue(true);
-    preferences.filesInMultipleDirectories().defaultValue(false);
-    preferences.directoryPaths().defaultValue("");
+    preferences.filesInOneDirectoryOnly().setDefaultValue(true);
+    preferences.filesInMultipleDirectories().setDefaultValue(false);
+    preferences.directoryPaths().setDefaultValue("");
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferences.java
index f50530b..bb2b556 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferences.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferences.java
@@ -29,7 +29,7 @@
   private static final String CSV_PATTERN = "[\\s]*,[\\s]*";
 
   PathsPreferences(RawPreferences preferences, IProject project) {
-    boolean filesInOneDirectoryOnly = preferences.filesInOneDirectoryOnly().value();
+    boolean filesInOneDirectoryOnly = preferences.filesInOneDirectoryOnly().getValue();
     pathResolutionType = filesInOneDirectoryOnly ? SINGLE_DIRECTORY : MULTIPLE_DIRECTORIES;
     importRoots = importRoots(preferences, project);
   }
@@ -39,7 +39,7 @@
       return emptyList();
     }
     List<DirectoryPath> roots = new ArrayList<DirectoryPath>();
-    for (String root : preferences.directoryPaths().value().split(CSV_PATTERN)) {
+    for (String root : preferences.directoryPaths().getValue().split(CSV_PATTERN)) {
       roots.add(DirectoryPath.parse(root, project));
     }
     return unmodifiableList(roots);
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/parser/Proto2OnlyCheckPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/parser/Proto2OnlyCheckPreferenceStoreInitializer.java
index 2ba96d3..d0ba538 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/parser/Proto2OnlyCheckPreferenceStoreInitializer.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/parser/Proto2OnlyCheckPreferenceStoreInitializer.java
@@ -22,6 +22,6 @@
   @Override public void initialize(IPreferenceStoreAccess access) {
     IPreferenceStore store = access.getWritablePreferenceStore();
     RawPreferences preferences = new RawPreferences(store);
-    preferences.enableProto2OnlyChecks().defaultValue(false);
+    preferences.enableProto2OnlyChecks().setDefaultValue(false);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferences.java
new file mode 100644
index 0000000..1e4fa56
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferences.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.paths.core;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import com.google.eclipse.protobuf.ui.preferences.*;
+import com.google.eclipse.protobuf.ui.preferences.editor.save.core.SaveActionsPreferences;
+
+/**
+ * "Paths" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class PathsPreferences {
+
+  private final BooleanPreference filesInOneDirectoryOnly;
+  private final BooleanPreference filesInMultipleDirectories;
+  private final StringPreference directoryPaths;
+
+  /**
+   * Creates a new <code>{@link SaveActionsPreferences}</code>.
+   * @param store a table mapping named preferences to values.
+   */
+  public PathsPreferences(IPreferenceStore store) {
+    filesInOneDirectoryOnly = new BooleanPreference("paths.filesInOneDirectoryOnly", store);
+    filesInMultipleDirectories = new BooleanPreference("paths.filesInMultipleDirectories", store);
+    directoryPaths = new StringPreference("paths.directoryPaths", store);
+  }
+
+  /**
+   * Returns the setting that specifies whether all the .proto files are stored in one directory.
+   * @return the setting that specifies whether all the .proto files are stored in one directory.
+   */
+  public BooleanPreference filesInOneDirectoryOnly() {
+    return filesInOneDirectoryOnly;
+  }
+
+  /**
+   * Returns the setting that specifies whether all the .proto files are stored in multiple directories.
+   * @return the setting that specifies whether all the .proto files are stored in multiple directories.
+   */
+  public BooleanPreference filesInMultipleDirectories() {
+    return filesInMultipleDirectories;
+  }
+
+  /**
+   * Returns the setting that specifies a CSV {@code String} containing the paths of the directories that store .proto
+   * files.
+   * @return the setting that specifies a CSV {@code String} containing the paths of the directories that store .proto
+   * files.
+   */
+  public StringPreference directoryPaths() {
+    return directoryPaths;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/swt/Colors.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/swt/Colors.java
deleted file mode 100644
index 48caa23..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/swt/Colors.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2011 Google Inc.
- *
- * 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
- */
-package com.google.eclipse.protobuf.ui.swt;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * Utility methods related to colors.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public final class Colors {
-
-  public static Color widgetBackground() {
-    return getColor(SWT.COLOR_WIDGET_BACKGROUND);
-  }
-
-  public static Color getColor(int systemColorID) {
-    return Display.getCurrent().getSystemColor(systemColorID);
-  }
-
-  private Colors() {}
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
index 6b5a4b8..1acbff0 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
@@ -10,12 +10,14 @@
 package com.google.eclipse.protobuf.ui.validation;
 
 import static com.google.eclipse.protobuf.ui.Internals.injector;
+import static com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferences.generalPreferences;
 import static com.google.eclipse.protobuf.ui.validation.Validation.validate;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.ui.*;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import com.google.eclipse.protobuf.ui.preferences.pages.general.*;
+import com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferences;
 import com.google.eclipse.protobuf.ui.util.Resources;
 
 /**
@@ -49,12 +51,9 @@
   }
 
   private boolean shouldValidateEditor(IProject project) {
-    GeneralPreferencesFactory factory = injector().getInstance(GeneralPreferencesFactory.class);
-    if (factory == null) {
-      return false;
-    }
-    GeneralPreferences preferences = factory.preferences(project);
-    return preferences.validateFilesOnActivation();
+    IPreferenceStoreAccess storeAccess = injector().getInstance(IPreferenceStoreAccess.class);
+    GeneralPreferences preferences = generalPreferences(storeAccess, project);
+    return preferences.validateFilesOnActivation().getValue();
   }
 
   /**
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java
index 407970c..e167625 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java
@@ -19,8 +19,9 @@
 import com.google.inject.*;
 
 /**
- * @author alruiz@google.com (Alex Ruiz)
+ * Utility methods related to <code>{@link Option}</code>s.
  *
+ * @author alruiz@google.com (Alex Ruiz)
  */
 @Singleton public class Options {