Simplified and cleaned up preferences-related code.
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/ButtonGroup_add_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/ButtonGroup_add_Test.java
similarity index 94%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/ButtonGroup_add_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/ButtonGroup_add_Test.java
index fdf5571..4d1b3b4 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/ButtonGroup_add_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/ButtonGroup_add_Test.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 static org.mockito.Mockito.*;
 
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/pages/binding/BindingToButtonSelection_Test.java
similarity index 76%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToButtonSelection_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection_Test.java
index 866792c..a8907c9 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/pages/binding/BindingToButtonSelection_Test.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 com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 import static org.mockito.Mockito.*;
@@ -14,9 +14,6 @@
 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 +32,16 @@
   }
 
   @Test public void should_apply_preference_value_to_selection_in_Button() {
-    when(preference.getValue()).thenReturn(true);
+    when(preference.value()).thenReturn(true);
     binding.applyPreferenceValueToTarget();
-    verify(preference).getValue();
+    verify(preference).value();
     verify(button).setSelection(true);
   }
 
   @Test public void should_apply_preference_default_value_to_selection_in_Button() {
-    when(preference.getDefaultValue()).thenReturn(true);
+    when(preference.defaultValue()).thenReturn(true);
     binding.applyDefaultPreferenceValueToTarget();
-    verify(preference).getDefaultValue();
+    verify(preference).defaultValue();
     verify(button).setSelection(true);
   }
 
@@ -52,6 +49,6 @@
     when(button.getSelection()).thenReturn(true);
     binding.savePreferenceValue();
     verify(button).getSelection();
-    verify(preference).setValue(true);
+    verify(preference).updateValue(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/pages/binding/BindingToListItems_Test.java
similarity index 75%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToListItems_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems_Test.java
index 8f6fa05..9ea7aed 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/pages/binding/BindingToListItems_Test.java
@@ -6,17 +6,15 @@
  *
  * 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 com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToListItems.bindItemsOf;
-import static java.util.Arrays.asList;
 import static org.mockito.Mockito.*;
 
 import org.eclipse.swt.widgets.List;
 import org.junit.*;
 
-import com.google.eclipse.protobuf.ui.preferences.StringListPreference;
-import com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToListItems;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Tests for <code>{@link BindingToListItems}</code>.
@@ -36,18 +34,18 @@
   }
 
   @Test public void should_apply_preference_value_to_selection_in_Button() {
-    when(preference.getValue()).thenReturn(asList("One" , "Two"));
+    when(preference.value()).thenReturn(ImmutableList.of("One" , "Two"));
     binding.applyPreferenceValueToTarget();
-    verify(preference).getValue();
+    verify(preference).value();
     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.getDefaultValue()).thenReturn(asList("One" , "Two"));
+    when(preference.defaultValue()).thenReturn(ImmutableList.of("One" , "Two"));
     binding.applyDefaultPreferenceValueToTarget();
-    verify(preference).getDefaultValue();
+    verify(preference).defaultValue();
     verify(list).removeAll();
     verify(list).add("One");
     verify(list).add("Two");
@@ -57,6 +55,6 @@
     when(list.getItems()).thenReturn(new String[] { "One", "Two" });
     binding.savePreferenceValue();
     verify(list).getItems();
-    verify(preference).setValue(asList("One" , "Two"));
+    verify(preference).updateValue(ImmutableList.of("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/pages/binding/BindingToTextValue_Test.java
similarity index 75%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/BindingToTextValue_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue_Test.java
index b0b95ec..c650a2b 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/pages/binding/BindingToTextValue_Test.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 com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToTextValue.bindTextOf;
 import static org.mockito.Mockito.*;
@@ -14,9 +14,6 @@
 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 +32,16 @@
   }
 
   @Test public void should_apply_preference_value_to_selection_in_Button() {
-    when(preference.getValue()).thenReturn("Hello World");
+    when(preference.value()).thenReturn("Hello World");
     binding.applyPreferenceValueToTarget();
-    verify(preference).getValue();
+    verify(preference).value();
     verify(text).setText("Hello World");
   }
 
   @Test public void should_apply_preference_default_value_to_selection_in_Button() {
-    when(preference.getDefaultValue()).thenReturn("Hello World");
+    when(preference.defaultValue()).thenReturn("Hello World");
     binding.applyDefaultPreferenceValueToTarget();
-    verify(preference).getDefaultValue();
+    verify(preference).defaultValue();
     verify(text).setText("Hello World");
   }
 
@@ -52,6 +49,6 @@
     when(text.getText()).thenReturn("Hello World");
     binding.savePreferenceValue();
     verify(text).getText();
-    verify(preference).setValue("Hello World");
+    verify(preference).updateValue("Hello World");
   }
 }
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/pages/binding/BooleanPreference_Test.java
similarity index 79%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BooleanPreference_Test.java
index 32e2149..ffd6399 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/pages/binding/BooleanPreference_Test.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.binding;
 
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.*;
@@ -33,23 +33,18 @@
 
   @Test public void should_read_value_from_IPreferenceStore() {
     when(store.getBoolean(name)).thenReturn(true);
-    assertTrue(preference.getValue());
+    assertTrue(preference.value());
     verify(store).getBoolean(name);
   }
 
   @Test public void should_read_default_value_from_IPreferenceStore() {
     when(store.getDefaultBoolean(name)).thenReturn(true);
-    assertTrue(preference.getDefaultValue());
+    assertTrue(preference.defaultValue());
     verify(store).getDefaultBoolean(name);
   }
 
   @Test public void should_update_value_in_IPreferenceStore() {
-    preference.setValue(true);
+    preference.updateValue(true);
     verify(store).setValue(name, true);
   }
-
-  @Test public void should_update_default_value_in_IPreferenceStore() {
-    preference.setDefaultValue(true);
-    verify(store).setDefault(name, true);
-  }
 }
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/pages/binding/PreferenceBinder_Test.java
similarity index 91%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/binding/PreferenceBinder_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/PreferenceBinder_Test.java
index a7a33cf..0225fd9 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/pages/binding/PreferenceBinder_Test.java
@@ -6,14 +6,12 @@
  *
  * 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 org.mockito.Mockito.*;
 
 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.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/DirectoryPath_parse_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/DirectoryPath_parse_Test.java
index 79dcbe2..ba82760 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/DirectoryPath_parse_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/DirectoryPath_parse_Test.java
@@ -15,6 +15,8 @@
 import org.eclipse.core.resources.IProject;
 import org.junit.*;
 
+import com.google.eclipse.protobuf.ui.preferences.paths.DirectoryPath;
+
 /**
  * Tests for <code>{@link DirectoryPath#parse(String, IProject)}</code>
  *
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectNameWithProjectVariable_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectNameWithProjectVariable_Test.java
index 5ca7a53..ecc1cf0 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectNameWithProjectVariable_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectNameWithProjectVariable_Test.java
@@ -16,6 +16,8 @@
 import org.eclipse.core.runtime.*;
 import org.junit.*;
 
+import com.google.eclipse.protobuf.ui.preferences.paths.ProjectVariable;
+
 /**
  * Tests for <code>{@link ProjectVariable#replaceProjectNameWithProjectVariable(IPath, IProject)}</code>.
  *
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectVariableWithProjectName_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectVariableWithProjectName_Test.java
index 76cd633..fb56dec 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectVariableWithProjectName_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable_replaceProjectVariableWithProjectName_Test.java
@@ -16,6 +16,8 @@
 import org.eclipse.core.runtime.*;
 import org.junit.*;
 
+import com.google.eclipse.protobuf.ui.preferences.paths.ProjectVariable;
+
 /**
  * Tests for <code>{@link ProjectVariable#replaceProjectVariableWithProjectName(IPath, IProject)}</code>.
  *
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/AbstractOutputDirectoryProtocOption_segmentsOf_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/AbstractOutputDirectoryProtocOption_segmentsOf_Test.java
index 529ba21..c2a3b2b 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/AbstractOutputDirectoryProtocOption_segmentsOf_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/AbstractOutputDirectoryProtocOption_segmentsOf_Test.java
@@ -17,27 +17,27 @@
 import org.junit.Test;
 
 /**
- * Tests for <code>{@link AbstractOutputDirectoryProtocOption#segmentsOf(String)}</code>.
+ * Tests for <code>{@link CodeGenerationProtocOption#segmentsOf(String)}</code>.
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
 public class AbstractOutputDirectoryProtocOption_segmentsOf_Test {
   @Test(expected = NullPointerException.class)
   public void should_throw_error_if_path_is_null() {
-    AbstractOutputDirectoryProtocOption.segmentsOf(null);
+    CodeGenerationProtocOption.segmentsOf(null);
   }
 
   @Test public void should_separate_segments_using_system_file_separator() {
     String[] expected = { "folder1" , "folder1_1", "folder1_1_1" };
     String path = pathFrom(expected);
-    String[] segments = AbstractOutputDirectoryProtocOption.segmentsOf(path);
+    String[] segments = CodeGenerationProtocOption.segmentsOf(path);
     assertThat(segments, equalTo(expected));
   }
 
   @Test public void should_separate_segments_for_path_ending_with_system_file_separator() {
     String[] expected = { "folder1" , "folder1_1" };
     String path = pathFrom(expected);
-    String[] segments = AbstractOutputDirectoryProtocOption.segmentsOf(path);
+    String[] segments = CodeGenerationProtocOption.segmentsOf(path);
     assertThat(segments, equalTo(expected));
   }
 
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption_appendOptionToCommand_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption_appendOptionToCommand_Test.java
index 096d297..1a0590e 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption_appendOptionToCommand_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption_appendOptionToCommand_Test.java
@@ -16,8 +16,7 @@
 import org.junit.*;
 import org.junit.rules.ExpectedException;
 
-import com.google.eclipse.protobuf.ui.preferences.StringPreference;
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
+import com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferences;
 
 /**
  * Tests for <code>{@link DescriptorPathProtocOption#addOptionTo(ProtocCommand)}</code>.
@@ -28,25 +27,23 @@
   @Rule public ExpectedException thrown = none();
 
   private CompilerPreferences preferences;
-  private StringPreference descriptorPathPreference;
   private ProtocCommand command;
   private DescriptorPathProtocOption option;
 
   @Before public void setUp() {
     preferences = mock(CompilerPreferences.class);
-    descriptorPathPreference = mock(StringPreference.class);
     command = new ProtocCommand("protoc");
     option = new DescriptorPathProtocOption(preferences, "/");
   }
 
   @Test public void should_not_append_to_command_if_descriptor_path_is_null() {
-    expectDescriptorPathToBeEqualTo(null);
+    when(preferences.descriptorPath()).thenReturn(null);
     option.addOptionTo(command);
     assertThat(command.toString(), equalTo("protoc"));
   }
 
   @Test public void should_not_append_to_command_if_descriptor_path_is_empty() {
-    expectDescriptorPathToBeEqualTo("");
+    when(preferences.descriptorPath()).thenReturn("");
     option.addOptionTo(command);
     assertThat(command.toString(), equalTo("protoc"));
   }
@@ -54,19 +51,14 @@
   @Test public void should_throw_error_if_descriptor_path_does_not_contain_descriptor_FQN() {
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("Path '/usr/local/include' does not contain '/google/protobuf/descriptor.proto'");
-    expectDescriptorPathToBeEqualTo("/usr/local/include");
+    when(preferences.descriptorPath()).thenReturn("/usr/local/include");
     option.addOptionTo(command);
     assertThat(command.toString(), equalTo("protoc"));
   }
 
   @Test public void should_append_path_of_descriptor_to_command() {
-    expectDescriptorPathToBeEqualTo("/usr/local/include/google/protobuf/descriptor.proto");
+    when(preferences.descriptorPath()).thenReturn("/usr/local/include/google/protobuf/descriptor.proto");
     option.addOptionTo(command);
     assertThat(command.toString(), equalTo("protoc --proto_path=/usr/local/include"));
   }
-
-  private void expectDescriptorPathToBeEqualTo(String value) {
-    when(preferences.descriptorPath()).thenReturn(descriptorPathPreference);
-    when(descriptorPathPreference.getValue()).thenReturn(value);
-  }
 }
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java
index 41c085a..ff2cebb 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java
@@ -13,19 +13,19 @@
 import static java.util.Collections.singletonList;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.*;
-import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.*;
 import static org.mockito.Mockito.*;
 
 import java.io.*;
 
 import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 import org.junit.*;
 import org.junit.rules.TemporaryFolder;
 
 import com.google.eclipse.protobuf.junit.core.*;
-import com.google.eclipse.protobuf.ui.preferences.StringPreference;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferences;
-import com.google.eclipse.protobuf.ui.util.Uris;
+import com.google.eclipse.protobuf.ui.preferences.paths.*;
 import com.google.inject.Inject;
 
 /**
@@ -44,60 +44,67 @@
   @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
 
   @Inject private ResourceLocations locations;
-  @Inject private Uris uris;
-  @Inject private MultipleDirectoriesFileResolverStrategy resolver;
+  @Inject private UriResolver uriResolver;
 
-  private StringPreference directoryPaths;
+  @Inject private MultipleDirectoriesFileResolverStrategy strategy;
+
+  private IPreferenceStore store;
   private PathsPreferences preferences;
   private Iterable<PathsPreferences> allPreferences;
 
   @Before public void setUp() {
-    directoryPaths = mock(StringPreference.class);
-    preferences = mock(PathsPreferences.class);
+    IPreferenceStoreAccess storeAccess = mock(IPreferenceStoreAccess.class);
+    store = mock(IPreferenceStore.class);
+    when(storeAccess.getWritablePreferenceStore(null)).thenReturn(store);
+    preferences = new PathsPreferences(storeAccess , null);
     allPreferences = singletonList(preferences);
-    when(preferences.directoryPaths()).thenReturn(directoryPaths);
   }
 
   @Test public void should_resolve_platform_resource_URI() {
-    String expected = "platform:/resource/src/protos/imported.proto";
-    when(directoryPaths.getValue()).thenReturn("${workspace_loc:/src/protos}");
-    when(uris.referredResourceExists(URI.createURI(expected))).thenReturn(true);
-    String resolved = resolver.resolveUri("imported.proto", declaringResourceUri, allPreferences);
+    String importUri = "imported.proto";
+    String expected = "platform:/resource/src/protos/" + importUri;
+    when(store.getString("paths.directoryPaths")).thenReturn("${workspace_loc:/src/protos}");
+    when(uriResolver.resolveUri(eq(importUri), any(DirectoryPath.class))).thenReturn(expected);
+    String resolved = strategy.resolveUri(importUri, declaringResourceUri, allPreferences);
     assertThat(resolved, equalTo(expected));
   }
 
   @Test public void should_resolve_file_URI() throws IOException {
-    File file = temporaryFolder.newFile("imported.proto");
+    String importUri = "imported.proto";
+    File file = temporaryFolder.newFile(importUri);
     String expected = file.toURI().toString();
-    when(directoryPaths.getValue()).thenReturn(temporaryFolder.getRoot().toString());
-    when(uris.referredResourceExists(URI.createURI(expected))).thenReturn(true);
-    String resolved = resolver.resolveUri(file.getName(), declaringResourceUri, allPreferences);
+    when(store.getString("paths.directoryPaths")).thenReturn(temporaryFolder.getRoot().toString());
+    when(uriResolver.resolveUri(eq(importUri), any(DirectoryPath.class))).thenReturn(expected);
+    String resolved = strategy.resolveUri(importUri, declaringResourceUri, allPreferences);
     assertThat(resolved, equalTo(expected));
   }
 
   @Test public void should_fall_back_to_file_system_if_platform_resource_URI_cannot_be_resolved() throws IOException {
-    File file = temporaryFolder.newFile("imported.proto");
+    String importUri = "imported.proto";
+    File file = temporaryFolder.newFile(importUri);
     String expected = file.toURI().toString();
-    when(directoryPaths.getValue()).thenReturn("${workspace_loc:/src/protos}");
+    when(store.getString("paths.directoryPaths")).thenReturn("${workspace_loc:/src/protos}");
     // try the first time as resource platform
-    when(uris.referredResourceExists(URI.createURI("platform:/resource/src/protos/imported.proto"))).thenReturn(false);
+    when(uriResolver.resolveUri(eq(importUri), any(DirectoryPath.class))).thenReturn(null);
     // try again, but in the file system this time
-    when(locations.directoryLocation("/src/protos")).thenReturn(temporaryFolder.getRoot().toString());
-    when(uris.referredResourceExists(URI.createURI(expected))).thenReturn(true);
-    String resolved = resolver.resolveUri(file.getName(), declaringResourceUri, allPreferences);
+    String directoryLocation = temporaryFolder.getRoot().toString();
+    when(locations.directoryLocation("/src/protos")).thenReturn(directoryLocation);
+    when(uriResolver.resolveUriInFileSystem(importUri, directoryLocation)).thenReturn(expected);
+    String resolved = strategy.resolveUri(importUri, declaringResourceUri, allPreferences);
     assertThat(resolved, equalTo(expected));
   }
 
   @Test public void should_return_null_if_URI_cannot_be_resolved() {
-    when(directoryPaths.getValue()).thenReturn("${workspace_loc:/src/protos}");
-    when(uris.referredResourceExists(any(URI.class))).thenReturn(false);
-    String resolved = resolver.resolveUri("imported.proto", declaringResourceUri, allPreferences);
+    when(store.getString("paths.directoryPaths")).thenReturn("${workspace_loc:/src/protos}");
+    String importUri = "imported.proto";
+    when(uriResolver.resolveUri(eq(importUri), any(DirectoryPath.class))).thenReturn(null);
+    String resolved = strategy.resolveUri(importUri, declaringResourceUri, allPreferences);
     assertNull(resolved);
   }
 
   private static class TestModule extends AbstractTestModule {
     @Override protected void configure() {
-      mockAndBind(Uris.class);
+      mockAndBind(UriResolver.class);
       mockAndBind(ResourceLocations.class);
     }
   }
diff --git a/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF
index 768fff7..c618942 100644
--- a/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF
@@ -29,6 +29,6 @@
  com.google.eclipse.protobuf.ui.editor,

  com.google.eclipse.protobuf.ui.plugin,

  com.google.eclipse.protobuf.ui.preferences,

- com.google.eclipse.protobuf.ui.preferences.compiler.core,

+ com.google.eclipse.protobuf.ui.preferences.compiler,

  com.google.eclipse.protobuf.ui.util

 Bundle-Activator: com.google.eclipse.protobuf.ui.internal.ProtobufActivator

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 ddbcb3d..c99cd33 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
@@ -12,28 +12,6 @@
 import static com.google.inject.name.Names.named;
 import static org.eclipse.ui.PlatformUI.isWorkbenchRunning;
 
-import com.google.eclipse.protobuf.scoping.IFileUriResolver;
-import com.google.eclipse.protobuf.ui.builder.nature.AutoAddNatureEditorCallback;
-import com.google.eclipse.protobuf.ui.documentation.ProtobufDocumentationProvider;
-import com.google.eclipse.protobuf.ui.editor.*;
-import com.google.eclipse.protobuf.ui.editor.hyperlinking.ProtobufHyperlinkDetector;
-import com.google.eclipse.protobuf.ui.editor.model.ProtobufDocumentProvider;
-import com.google.eclipse.protobuf.ui.editor.spelling.ProtobufReconciler;
-import com.google.eclipse.protobuf.ui.editor.syntaxcoloring.*;
-import com.google.eclipse.protobuf.ui.internal.ProtobufActivator;
-import com.google.eclipse.protobuf.ui.outline.*;
-import com.google.eclipse.protobuf.ui.parser.PreferenceDrivenProtobufParser;
-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.misc.core.MiscellaneousPreferenceStoreInitializer;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferenceStoreInitializer;
-import com.google.eclipse.protobuf.ui.quickfix.ProtobufQuickAssistProcessor;
-import com.google.eclipse.protobuf.ui.scoping.FileUriResolver;
-import com.google.eclipse.protobuf.ui.validation.*;
-import com.google.inject.Binder;
-
 import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
 import org.eclipse.jface.text.reconciler.IReconciler;
 import org.eclipse.ui.IWorkbenchWindow;
@@ -50,6 +28,28 @@
 import org.eclipse.xtext.ui.editor.syntaxcoloring.*;
 import org.eclipse.xtext.ui.validation.IResourceUIValidatorExtension;
 
+import com.google.eclipse.protobuf.scoping.IFileUriResolver;
+import com.google.eclipse.protobuf.ui.builder.nature.AutoAddNatureEditorCallback;
+import com.google.eclipse.protobuf.ui.documentation.ProtobufDocumentationProvider;
+import com.google.eclipse.protobuf.ui.editor.*;
+import com.google.eclipse.protobuf.ui.editor.hyperlinking.ProtobufHyperlinkDetector;
+import com.google.eclipse.protobuf.ui.editor.model.ProtobufDocumentProvider;
+import com.google.eclipse.protobuf.ui.editor.spelling.ProtobufReconciler;
+import com.google.eclipse.protobuf.ui.editor.syntaxcoloring.*;
+import com.google.eclipse.protobuf.ui.internal.ProtobufActivator;
+import com.google.eclipse.protobuf.ui.outline.*;
+import com.google.eclipse.protobuf.ui.parser.PreferenceDrivenProtobufParser;
+import com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferences;
+import com.google.eclipse.protobuf.ui.preferences.editor.numerictag.NumericTagPreferences;
+import com.google.eclipse.protobuf.ui.preferences.editor.save.SaveActionsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.general.GeneralPreferences;
+import com.google.eclipse.protobuf.ui.preferences.misc.MiscellaneousPreferences;
+import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
+import com.google.eclipse.protobuf.ui.quickfix.ProtobufQuickAssistProcessor;
+import com.google.eclipse.protobuf.ui.scoping.FileUriResolver;
+import com.google.eclipse.protobuf.ui.validation.*;
+import com.google.inject.Binder;
+
 /**
  * Registers components to be used within the IDE.
  *
@@ -127,12 +127,12 @@
   }
 
   public void configurePreferencesInitializers(Binder binder) {
-    configurePreferenceInitializer(binder, "compilerPreferences", CompilerPreferenceStoreInitializer.class);
-    configurePreferenceInitializer(binder, "generalPreferences", GeneralPreferenceStoreInitializer.class);
-    configurePreferenceInitializer(binder, "numericTagPreferences", NumericTagPreferenceStoreInitializer.class);
-    configurePreferenceInitializer(binder, "parserChecksPreferences", MiscellaneousPreferenceStoreInitializer.class);
-    configurePreferenceInitializer(binder, "pathsPreferences", PathsPreferenceStoreInitializer.class);
-    configurePreferenceInitializer(binder, "saveActionsPreferences", SaveActionsPreferenceStoreInitializer.class);
+    configurePreferenceInitializer(binder, "compilerPreferences", CompilerPreferences.Initializer.class);
+    configurePreferenceInitializer(binder, "generalPreferences", GeneralPreferences.Initializer.class);
+    configurePreferenceInitializer(binder, "numericTagPreferences", NumericTagPreferences.Initializer.class);
+    configurePreferenceInitializer(binder, "miscellaneousPreferences", MiscellaneousPreferences.Initializer.class);
+    configurePreferenceInitializer(binder, "pathsPreferences", PathsPreferences.Initializer.class);
+    configurePreferenceInitializer(binder, "saveActionsPreferences", SaveActionsPreferences.Initializer.class);
   }
 
   private void configurePreferenceInitializer(Binder binder, String name,
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 a9f533a..5f29cea 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
@@ -11,7 +11,7 @@
 import static com.google.common.io.Closeables.closeQuietly;
 import static com.google.eclipse.protobuf.ui.builder.protoc.ConsolePrinter.createAndDisplayConsole;
 import static com.google.eclipse.protobuf.ui.exception.CoreExceptions.error;
-import static com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences.compilerPreferences;
+import static com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferences.compilerPreferences;
 import static com.google.eclipse.protobuf.ui.util.Workspaces.workspaceRoot;
 import static org.eclipse.core.resources.IResource.DEPTH_INFINITE;
 
@@ -26,8 +26,8 @@
 import org.eclipse.xtext.resource.IResourceDescription.Delta;
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferences;
+import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
 import com.google.eclipse.protobuf.ui.protoc.command.ProtocCommandBuilder;
 import com.google.eclipse.protobuf.ui.protoc.output.*;
 import com.google.inject.Inject;
@@ -48,7 +48,7 @@
     }
     IProject project = context.getBuiltProject();
     CompilerPreferences compilerPreferences = compilerPreferences(storeAccess, project);
-    if (!compilerPreferences.compileProtoFiles().getValue()) {
+    if (!compilerPreferences.shouldCompileProtoFiles()) {
       return;
     }
     PathsPreferences pathsPreferences = new PathsPreferences(storeAccess, project);
@@ -60,9 +60,8 @@
       }
       generateSingleProto(commandBuilder.buildCommand(protoFile), protoFile);
     }
-    if (compilerPreferences.refreshResources().getValue()) {
-      boolean refreshProject = compilerPreferences.refreshProject().getValue();
-      refresh(project, commandBuilder.outputDirectories(), refreshProject, monitor);
+    if (compilerPreferences.refreshResources()) {
+      refresh(project, commandBuilder.outputDirectories(), compilerPreferences.refreshProject(), monitor);
     }
   }
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java
index 7d2155d..7fca119 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/SmartSemicolonHandler.java
@@ -33,7 +33,7 @@
 import com.google.eclipse.protobuf.model.util.*;
 import com.google.eclipse.protobuf.protobuf.*;
 import com.google.eclipse.protobuf.ui.commands.SmartInsertHandler;
-import com.google.eclipse.protobuf.ui.preferences.editor.numerictag.core.NumericTagPreferences;
+import com.google.eclipse.protobuf.ui.preferences.editor.numerictag.NumericTagPreferences;
 import com.google.inject.Inject;
 
 /**
@@ -142,7 +142,7 @@
       return;
     }
     NumericTagPreferences preferences = new NumericTagPreferences(storeAccess);
-    for (String pattern : preferences.patterns().getValue()) {
+    for (String pattern : preferences.patterns()) {
       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 d6ffe95..a826144 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
@@ -16,9 +16,7 @@
 import static org.eclipse.core.filebuffers.LocationKind.*;
 import static org.eclipse.text.undo.DocumentUndoManagerRegistry.getDocumentUndoManager;
 
-import com.google.eclipse.protobuf.ui.preferences.editor.save.core.SaveActionsPreferences;
-import com.google.eclipse.protobuf.ui.util.editor.ChangedLineRegionCalculator;
-import com.google.inject.Inject;
+import java.util.List;
 
 import org.eclipse.core.filebuffers.*;
 import org.eclipse.core.runtime.*;
@@ -30,7 +28,9 @@
 import org.eclipse.xtext.ui.editor.model.*;
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import java.util.List;
+import com.google.eclipse.protobuf.ui.preferences.editor.save.SaveActionsPreferences;
+import com.google.eclipse.protobuf.ui.util.editor.ChangedLineRegionCalculator;
+import com.google.inject.Inject;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
@@ -127,13 +127,13 @@
   private IRegion[] changedRegions(IProgressMonitor monitor, IFileEditorInput editorInput, IDocument document)
       throws CoreException {
     SaveActionsPreferences preferences = new SaveActionsPreferences(storeAccess);
-    if (!preferences.removeTrailingWhitespace().getValue()) {
+    if (!preferences.shouldRemoveTrailingWhitespace()) {
       return NO_CHANGE;
     }
-    if (preferences.inEditedLines().getValue()) {
-      return calculator.calculateChangedLineRegions(textFileBuffer(monitor, editorInput), document, monitor);
+    if (preferences.shouldRemoveTrailingWhitespaceInAllLines()) {
+      return new IRegion[] { new Region(0, document.getLength()) };
     }
-    return new IRegion[] { new Region(0, document.getLength()) };
+    return calculator.calculateChangedLineRegions(textFileBuffer(monitor, editorInput), document, monitor);
   }
 
   private ITextFileBuffer textFileBuffer(IProgressMonitor monitor, IFileEditorInput editorInput) throws CoreException {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/parser/PreferenceDrivenProtobufParser.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/parser/PreferenceDrivenProtobufParser.java
index bc32bf4..99f617e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/parser/PreferenceDrivenProtobufParser.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/parser/PreferenceDrivenProtobufParser.java
@@ -8,17 +8,17 @@
  */
 package com.google.eclipse.protobuf.ui.parser;
 
-import com.google.eclipse.protobuf.parser.NonProto2Protobuf;
-import com.google.eclipse.protobuf.parser.antlr.ProtobufParser;
-import com.google.eclipse.protobuf.protobuf.Protobuf;
-import com.google.eclipse.protobuf.ui.preferences.misc.core.MiscellaneousPreferences;
-import com.google.inject.Inject;
-
 import org.antlr.runtime.CharStream;
 import org.eclipse.xtext.nodemodel.impl.NodeModelBuilder;
 import org.eclipse.xtext.parser.*;
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
+import com.google.eclipse.protobuf.parser.NonProto2Protobuf;
+import com.google.eclipse.protobuf.parser.antlr.ProtobufParser;
+import com.google.eclipse.protobuf.protobuf.Protobuf;
+import com.google.eclipse.protobuf.ui.preferences.misc.MiscellaneousPreferences;
+import com.google.inject.Inject;
+
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
@@ -29,7 +29,7 @@
       int initialLookAhead) {
     IParseResult result = super.doParse(ruleName, in, builder, initialLookAhead);
     MiscellaneousPreferences preferences = new MiscellaneousPreferences(storeAccess);
-    if (preferences.isGoogleInternal().getValue() && isNotProto2(result)) {
+    if (preferences.isGoogleInternal() && isNotProto2(result)) {
       return new ParseResult(new NonProto2Protobuf(), result.getRootNode(), false);
     }
     return result;
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
deleted file mode 100644
index 28510d9..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/BooleanPreference.java
+++ /dev/null
@@ -1,47 +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.jface.preference.IPreferenceStore;
-
-/**
- * A preference that stores a {@code boolean} value.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class BooleanPreference extends Preference<Boolean> {
-  /**
-   * Creates a new </code>{@link BooleanPreference}</code>.
-   * @param name the name of this preference.
-   * @param store the store for this preference.
-   */
-  public BooleanPreference(String name, IPreferenceStore store) {
-    super(name, store);
-  }
-
-  /** {@inheritDoc} */
-  @Override public Boolean getValue() {
-    return getPreferenceStore().getBoolean(getName());
-  }
-
-  /** {@inheritDoc} */
-  @Override public Boolean getDefaultValue() {
-    return getPreferenceStore().getDefaultBoolean(getName());
-  }
-
-  /** {@inheritDoc} */
-  @Override public void setValue(Boolean value) {
-    getPreferenceStore().setValue(getName(), value);
-  }
-
-  /** {@inheritDoc} */
-  @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/Preference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Preference.java
deleted file mode 100644
index b184e9d..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/Preference.java
+++ /dev/null
@@ -1,80 +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.jface.preference.IPreferenceStore;
-
-/**
- * A single preference value.
- * @param <T> the type of value this preference handles.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public abstract class Preference<T> {
-  private final String name;
-  private IPreferenceStore store;
-
-  /**
-   * Creates a new </code>{@link Preference}</code>.
-   * @param name the name of this preference.
-   * @param store the store for this preference.
-   */
-  public Preference(String name, IPreferenceStore store) {
-    this.name = name;
-    setPreferenceStore(store);
-  }
-
-  /**
-   * Returns the name of this preference.
-   * @return the name of this preference.
-   */
-  public String getName() {
-    return name;
-  }
-
-  /**
-   * Returns the value of this preference.
-   * @return the value of this preference.
-   */
-  public abstract T getValue();
-
-  /**
-   * Returns the default value of this preference.
-   * @return the default value of this preference.
-   */
-  public abstract T getDefaultValue();
-
-  /**
-   * Sets the value of this preference to the given store.
-   * @param value the value to set.
-   */
-  public abstract void setValue(T value);
-
-  /**
-   * Sets the default value of this preference to the given store.
-   * @param value the default value to set.
-   */
-  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
deleted file mode 100644
index 5db8aac..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringListPreference.java
+++ /dev/null
@@ -1,65 +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 static org.eclipse.xtext.util.Strings.*;
-
-import java.util.List;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * A preference that stores a list of {@code String} values.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class StringListPreference extends Preference<List<String>> {
-  private final String delimiter;
-
-  /**
-   * Creates a new </code>{@link StringListPreference}</code>.
-   * @param name the name of this preference.
-   * @param delimiter the delimiter to split a single {@code String} into a list.
-   * @param store the store for this preference.
-   */
-  public StringListPreference(String name, String delimiter, IPreferenceStore store) {
-    super(name, store);
-    this.delimiter = delimiter;
-  }
-
-  /** {@inheritDoc} */
-  @Override public List<String> getValue() {
-    String value = getPreferenceStore().getString(getName());
-    return splitIntoList(value);
-  }
-
-  /** {@inheritDoc} */
-  @Override public List<String> getDefaultValue() {
-    String defaultValue = getPreferenceStore().getDefaultString(getName());
-    return splitIntoList(defaultValue);
-  }
-
-  private List<String> splitIntoList(String value) {
-    return split(value, delimiter);
-  }
-
-  /** {@inheritDoc} */
-  @Override public void setValue(List<String> value) {
-    getPreferenceStore().setValue(getName(), concatenate(value));
-  }
-
-  /** {@inheritDoc} */
-  @Override public void setDefaultValue(List<String> value) {
-    getPreferenceStore().setDefault(getName(), concatenate(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
deleted file mode 100644
index 3d5c45f..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringPreference.java
+++ /dev/null
@@ -1,47 +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.jface.preference.IPreferenceStore;
-
-/**
- * A preference that stores a {@code String} value.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class StringPreference extends Preference<String> {
-  /**
-   * Creates a new </code>{@link StringPreference}</code>.
-   * @param name the name of this preference.
-   * @param store the store for this preference.
-   */
-  public StringPreference(String name, IPreferenceStore store) {
-    super(name, store);
-  }
-
-  /** {@inheritDoc} */
-  @Override public String getValue() {
-    return getPreferenceStore().getString(getName());
-  }
-
-  /** {@inheritDoc} */
-  @Override public String getDefaultValue() {
-    return getPreferenceStore().getDefaultString(getName());
-  }
-
-  /** {@inheritDoc} */
-  @Override public void setValue(String value) {
-    getPreferenceStore().setValue(getName(), value);
-  }
-
-  /** {@inheritDoc} */
-  @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/StringSplitter.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringSplitter.java
new file mode 100644
index 0000000..27f964b
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/StringSplitter.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 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 static com.google.common.collect.ImmutableList.copyOf;
+import static org.eclipse.xtext.util.Strings.split;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class StringSplitter {
+  private final String delimiter;
+
+  public StringSplitter(String delimiter) {
+    this.delimiter = delimiter;
+  }
+
+  public ImmutableList<String> splitIntoList(String value) {
+    return copyOf(split(value, delimiter));
+  }
+
+  public String delimiter() {
+    return delimiter;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CodeGenerationPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CodeGenerationPreference.java
new file mode 100644
index 0000000..40699ad
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CodeGenerationPreference.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 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;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CodeGenerationPreference {
+  private final IPreferenceStore store;
+  private final String enabledPreferenceName;
+  private final String outputDirectoryPreferenceName;
+
+  CodeGenerationPreference(IPreferenceStore store, String enabledPreferenceName, String outputDirectoryPreferenceName) {
+    this.store = store;
+    this.enabledPreferenceName = enabledPreferenceName;
+    this.outputDirectoryPreferenceName = outputDirectoryPreferenceName;
+  }
+
+  public boolean isEnabled() {
+    return store.getBoolean(enabledPreferenceName);
+  }
+
+  public String outputDirectory() {
+    return store.getString(outputDirectoryPreferenceName);
+  }
+}
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/CompilerPreferencePage.java
similarity index 90%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/CompilerPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferencePage.java
index 819b984..5ddd0a8 100644
--- 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/CompilerPreferencePage.java
@@ -6,10 +6,10 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.compiler.page;
+package com.google.eclipse.protobuf.ui.preferences.compiler;
 
-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.compiler.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.compiler.PreferenceNames.*;
 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.*;
@@ -24,9 +24,8 @@
 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;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
 
 /**
  * Preference page for protobuf compiler.
@@ -248,23 +247,22 @@
     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 setupBinding(PreferenceBinder binder, PreferenceFactory factory) {
+    binder.addAll(
+        bindSelectionOf(btnCompileProtoFiles).to(factory.newBooleanPreference(COMPILE_PROTO_FILES)),
+        bindSelectionOf(btnUseProtocInSystemPath).to(factory.newBooleanPreference(USE_PROTOC_IN_SYSTEM_PATH)),
+        bindSelectionOf(btnUseProtocInCustomPath).to(factory.newBooleanPreference(USE_PROTOC_IN_CUSTOM_PATH)),
+        bindTextOf(txtProtocFilePath).to(factory.newStringPreference(PROTOC_FILE_PATH)),
+        bindTextOf(txtDescriptorFilePath).to(factory.newStringPreference(DESCRIPTOR_FILE_PATH)),
+        bindSelectionOf(btnGenerateJava).to(factory.newBooleanPreference(JAVA_CODE_GENERATION_ENABLED)),
+        bindTextOf(txtJavaOutputDirectory).to(factory.newStringPreference(JAVA_OUTPUT_DIRECTORY)),
+        bindSelectionOf(btnGenerateCpp).to(factory.newBooleanPreference(CPP_CODE_GENERATION_ENABLED)),
+        bindTextOf(txtCppOutputDirectory).to(factory.newStringPreference(CPP_OUTPUT_DIRECTORY)),
+        bindSelectionOf(btnGeneratePython).to(factory.newBooleanPreference(PYTHON_CODE_GENERATION_ENABLED)),
+        bindTextOf(txtPythonOutputDirectory).to(factory.newStringPreference(PYTHON_OUTPUT_DIRECTORY)),
+        bindSelectionOf(btnRefreshResources).to(factory.newBooleanPreference(REFRESH_RESOURCES)),
+        bindSelectionOf(btnRefreshProject).to(factory.newBooleanPreference(REFRESH_PROJECT)),
+        bindSelectionOf(btnRefreshOutputDirectory).to(factory.newBooleanPreference(REFRESH_OUTPUT_DIRECTORY))
       );
   }
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferences.java
new file mode 100644
index 0000000..c00f3a3
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferences.java
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import static com.google.eclipse.protobuf.ui.preferences.compiler.PreferenceNames.*;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class 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 IPreferenceStore store;
+  private final CodeGenerationPreference java;
+  private final CodeGenerationPreference cpp;
+  private final CodeGenerationPreference python;
+
+  private CompilerPreferences(IPreferenceStore store) {
+    this.store = store;
+    java = new CodeGenerationPreference(store, JAVA_CODE_GENERATION_ENABLED, JAVA_OUTPUT_DIRECTORY);
+    cpp = new CodeGenerationPreference(store, CPP_CODE_GENERATION_ENABLED, CPP_OUTPUT_DIRECTORY);
+    python = new CodeGenerationPreference(store, PYTHON_CODE_GENERATION_ENABLED, PYTHON_OUTPUT_DIRECTORY);
+  }
+
+  public boolean shouldCompileProtoFiles() {
+    return store.getBoolean(COMPILE_PROTO_FILES);
+  }
+
+  public String protocPath() {
+    return (useProtocInSystemPath()) ? "protoc" : store.getString(PROTOC_FILE_PATH);
+  }
+
+  private boolean useProtocInSystemPath() {
+    return store.getBoolean(USE_PROTOC_IN_SYSTEM_PATH);
+  }
+
+  public String descriptorPath() {
+    return store.getString(DESCRIPTOR_FILE_PATH);
+  }
+
+  public CodeGenerationPreference javaCodeGeneration() {
+    return java;
+  }
+
+  public CodeGenerationPreference cppCodeGeneration() {
+    return cpp;
+  }
+
+  public CodeGenerationPreference pythonCodeGeneration() {
+    return python;
+  }
+
+  public boolean refreshResources() {
+    return store.getBoolean(REFRESH_RESOURCES);
+  }
+
+  public boolean refreshProject() {
+    return store.getBoolean(REFRESH_PROJECT);
+  }
+
+  public static class Initializer implements IPreferenceStoreInitializer {
+    private static final String DEFAULT_OUTPUT_DIRECTORY = "src-gen";
+
+    @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+      IPreferenceStore store = storeAccess.getWritablePreferenceStore();
+      store.setDefault(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME, false);
+      store.setDefault(USE_PROTOC_IN_SYSTEM_PATH, true);
+      store.setDefault(USE_PROTOC_IN_CUSTOM_PATH, false);
+      store.setDefault(JAVA_CODE_GENERATION_ENABLED, false);
+      store.setDefault(CPP_CODE_GENERATION_ENABLED, false);
+      store.setDefault(PYTHON_CODE_GENERATION_ENABLED, false);
+      store.setDefault(JAVA_OUTPUT_DIRECTORY, DEFAULT_OUTPUT_DIRECTORY);
+      store.setDefault(CPP_OUTPUT_DIRECTORY, DEFAULT_OUTPUT_DIRECTORY);
+      store.setDefault(PYTHON_OUTPUT_DIRECTORY, DEFAULT_OUTPUT_DIRECTORY);
+      store.setDefault(REFRESH_RESOURCES, true);
+      store.setDefault(REFRESH_PROJECT, true);
+      store.setDefault(REFRESH_OUTPUT_DIRECTORY, false);
+    }
+ }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/Messages.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/Messages.java
index 4ad7e33..a15a713 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.compiler.page;
+package com.google.eclipse.protobuf.ui.preferences.compiler;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/page/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/PreferenceNames.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/PreferenceNames.java
new file mode 100644
index 0000000..319876b
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/PreferenceNames.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 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;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+final class PreferenceNames {
+  static final String ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME = "compiler.enableProjectSettings";
+  static final String COMPILE_PROTO_FILES = "compiler.compileProtoFiles";
+  static final String USE_PROTOC_IN_SYSTEM_PATH = "compiler.useProtocInSystemPath";
+  static final String USE_PROTOC_IN_CUSTOM_PATH = "compiler.useProtocInCustomPath";
+  static final String PROTOC_FILE_PATH = "compiler.protocFilePath";
+  static final String DESCRIPTOR_FILE_PATH = "compiler.descriptorFilePath";
+  static final String JAVA_CODE_GENERATION_ENABLED = "compiler.javaCodeGenerationEnabled";
+  static final String CPP_CODE_GENERATION_ENABLED = "compiler.cppCodeGenerationEnabled";
+  static final String PYTHON_CODE_GENERATION_ENABLED = "compiler.pythonCodeGenerationEnabled";
+  static final String JAVA_OUTPUT_DIRECTORY = "compiler.javaOutputDirectory";
+  static final String CPP_OUTPUT_DIRECTORY = "compiler.cppOutputDirectory";
+  static final String PYTHON_OUTPUT_DIRECTORY = "compiler.pythonOutputDirectory";
+  static final String REFRESH_RESOURCES = "compiler.refreshResources";
+  static final String REFRESH_PROJECT = "compiler.refreshProject";
+  static final String REFRESH_OUTPUT_DIRECTORY = "compiler.refreshOutputDirectory";
+
+  private PreferenceNames() {}
+}
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
deleted file mode 100644
index 631de1c..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferenceStoreInitializer.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.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";
-
-  @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
deleted file mode 100644
index ad9aab2..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/core/CompilerPreferences.java
+++ /dev/null
@@ -1,209 +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.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/editor/general/page/EditorPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/EditorPreferencePage.java
similarity index 97%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/EditorPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/EditorPreferencePage.java
index 3d886fa..d909dea 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/EditorPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/EditorPreferencePage.java
@@ -7,9 +7,9 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.editor.general.page;
+package com.google.eclipse.protobuf.ui.preferences.editor.general;
 
-import static com.google.eclipse.protobuf.ui.preferences.editor.general.page.Messages.header;
+import static com.google.eclipse.protobuf.ui.preferences.editor.general.Messages.header;
 import static org.eclipse.ui.dialogs.PreferencesUtil.createPreferenceDialogOn;
 
 import org.eclipse.jface.preference.PreferencePage;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/Messages.java
similarity index 98%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/Messages.java
index 2a8be64..c7f4c2e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/Messages.java
@@ -7,7 +7,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.editor.general.page;
+package com.google.eclipse.protobuf.ui.preferences.editor.general;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/page/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/general/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/AddOrEditPatternDialog.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/AddOrEditPatternDialog.java
similarity index 98%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/AddOrEditPatternDialog.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/AddOrEditPatternDialog.java
index e64780f..bb667a1 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/AddOrEditPatternDialog.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/AddOrEditPatternDialog.java
@@ -6,9 +6,9 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page;
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag;
 
-import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.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;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.java
similarity index 98%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.java
index 91e6f8c..4e7c8fa 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page;
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPatternSplitter.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPatternSplitter.java
new file mode 100644
index 0000000..a70943f
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPatternSplitter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 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;
+
+import com.google.eclipse.protobuf.ui.preferences.StringSplitter;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class NumericTagPatternSplitter extends StringSplitter {
+  private static final StringSplitter INSTANCE = new NumericTagPatternSplitter();
+
+  static StringSplitter instance() {
+    return INSTANCE;
+  }
+
+  private NumericTagPatternSplitter() {
+    super("\\t");
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/NumericTagPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferencePage.java
similarity index 89%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/NumericTagPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferencePage.java
index 2b1d38d..5326644 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/page/NumericTagPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferencePage.java
@@ -6,10 +6,10 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.editor.numerictag.page;
+package com.google.eclipse.protobuf.ui.preferences.editor.numerictag;
 
-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.editor.numerictag.AddOrEditPatternDialog.*;
+import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.Messages.*;
 import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToListItems.bindItemsOf;
 import static org.eclipse.jface.window.Window.OK;
 
@@ -19,10 +19,9 @@
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
-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.*;
 import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
-import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
 
 /**
  * Preference page where users can specify the patterns to use to match comments where "the next id" is being tracked.
@@ -118,10 +117,9 @@
     return null;
   }
 
-  @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
-    NumericTagPreferences preferences = new NumericTagPreferences(getPreferenceStore());
-    StringListPreference patterns = preferences.patterns();
-    preferenceBinder.add(bindItemsOf(lstPaths).to(patterns));
+  @Override protected void setupBinding(PreferenceBinder binder, PreferenceFactory factory) {
+    StringSplitter splitter = NumericTagPatternSplitter.instance();
+    binder.add(bindItemsOf(lstPaths).to(factory.newStringListPreference(PREFERENCE_PAGE_ID, splitter)));
   }
 
   @Override protected void onProjectSettingsActivation(boolean projectSettingsActive) {}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferences.java
new file mode 100644
index 0000000..b354a7e
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/NumericTagPreferences.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+import static com.google.eclipse.protobuf.ui.preferences.editor.numerictag.PreferenceNames.NUMERIC_TAG_PATTERNS;
+
+import java.util.List;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class NumericTagPreferences {
+  private final IPreferenceStore store;
+
+  public NumericTagPreferences(IPreferenceStoreAccess storeAccess) {
+    store = storeAccess.getWritablePreferenceStore();
+  }
+
+  public List<String> patterns() {
+    String value = store.getString(NUMERIC_TAG_PATTERNS);
+    return NumericTagPatternSplitter.instance().splitIntoList(value);
+  }
+
+  public static class Initializer implements IPreferenceStoreInitializer {
+    @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+      IPreferenceStore store = storeAccess.getWritablePreferenceStore();
+      store.setDefault(NUMERIC_TAG_PATTERNS, "Next[\\s]+Id:[\\s]+[\\d]+");
+    }
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/PreferenceNames.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/PreferenceNames.java
new file mode 100644
index 0000000..43ebd1b
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/PreferenceNames.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2012 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;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+final class PreferenceNames {
+  static final String NUMERIC_TAG_PATTERNS = "numericTag.patterns";
+
+  private PreferenceNames() {}
+}
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
deleted file mode 100644
index 21cc3b0..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferenceStoreInitializer.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.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 {
-  @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
deleted file mode 100644
index 7f3ff27..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/numerictag/core/NumericTagPreferences.java
+++ /dev/null
@@ -1,49 +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.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/editor/save/page/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/Messages.java
similarity index 89%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/Messages.java
index 91509a6..6bf5ef8 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.editor.save.page;
+package com.google.eclipse.protobuf.ui.preferences.editor.save;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/PreferenceNames.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/PreferenceNames.java
new file mode 100644
index 0000000..8603d36
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/PreferenceNames.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 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;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+final class PreferenceNames {
+  static final String REMOVE_TRAILING_WHITESPACE = "saveActions.removeTrailingWhitespace";
+  static final String IN_ALL_LINES = "saveActions.inAllLines";
+  static final String IN_EDITED_LINES = "saveActions.inEditedLines";
+
+  private PreferenceNames() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/SaveActionsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/SaveActionsPreferencePage.java
similarity index 84%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/SaveActionsPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/SaveActionsPreferencePage.java
index 0e4b1d9..69d6013 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/page/SaveActionsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/SaveActionsPreferencePage.java
@@ -7,9 +7,10 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.editor.save.page;
+package com.google.eclipse.protobuf.ui.preferences.editor.save;
 
-import static com.google.eclipse.protobuf.ui.preferences.editor.save.page.Messages.removeTrailingWhitespace;
+import static com.google.eclipse.protobuf.ui.preferences.editor.save.Messages.removeTrailingWhitespace;
+import static com.google.eclipse.protobuf.ui.preferences.editor.save.PreferenceNames.*;
 import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 
 import org.eclipse.jface.preference.*;
@@ -20,8 +21,7 @@
 import org.eclipse.ui.*;
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import com.google.eclipse.protobuf.ui.preferences.editor.save.core.SaveActionsPreferences;
-import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
 import com.google.inject.Inject;
 
 /**
@@ -38,7 +38,6 @@
   private Button btnInEditedLines;
   private Button btnInAllLines;
 
-  /** {@inheritDoc} */
   @Override public void init(IWorkbench workbench) {}
 
   @Override protected Control createContents(Composite parent) {
@@ -66,11 +65,11 @@
   }
 
   private void setUpBinding() {
-    SaveActionsPreferences preferences = new SaveActionsPreferences(getPreferenceStore());
+    PreferenceFactory factory = new PreferenceFactory(getPreferenceStore());
     preferenceBinder.addAll(
-        bindSelectionOf(btnRemoveTrailingwhitespace).to(preferences.removeTrailingWhitespace()),
-        bindSelectionOf(btnInAllLines).to(preferences.inAllLines()),
-        bindSelectionOf(btnInEditedLines).to(preferences.inEditedLines())
+        bindSelectionOf(btnRemoveTrailingwhitespace).to(factory.newBooleanPreference(REMOVE_TRAILING_WHITESPACE)),
+        bindSelectionOf(btnInAllLines).to(factory.newBooleanPreference(IN_ALL_LINES)),
+        bindSelectionOf(btnInEditedLines).to(factory.newBooleanPreference(IN_EDITED_LINES))
     );
   }
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/SaveActionsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/SaveActionsPreferences.java
new file mode 100644
index 0000000..d714606
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/SaveActionsPreferences.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import static com.google.eclipse.protobuf.ui.preferences.editor.save.PreferenceNames.*;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class SaveActionsPreferences {
+  private final IPreferenceStore store;
+
+  public SaveActionsPreferences(IPreferenceStoreAccess storeAccess) {
+    this.store = storeAccess.getWritablePreferenceStore();
+  }
+
+  public boolean shouldRemoveTrailingWhitespace() {
+    return store.getBoolean(REMOVE_TRAILING_WHITESPACE);
+  }
+
+  public boolean shouldRemoveTrailingWhitespaceInAllLines() {
+    return store.getBoolean(IN_ALL_LINES);
+  }
+
+  public static class Initializer implements IPreferenceStoreInitializer {
+    @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+      IPreferenceStore store = storeAccess.getWritablePreferenceStore();
+      store.setDefault(REMOVE_TRAILING_WHITESPACE, true);
+      store.setDefault(IN_ALL_LINES, false);
+      store.setDefault(IN_EDITED_LINES, true);
+    }
+  }
+}
\ No newline at end of file
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
deleted file mode 100644
index 99f15b3..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferenceStoreInitializer.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.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 {
-  @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
deleted file mode 100644
index 35af812..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/editor/save/core/SaveActionsPreferences.java
+++ /dev/null
@@ -1,67 +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.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/general/page/GeneralPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/GeneralPreferencePage.java
similarity index 81%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/GeneralPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/GeneralPreferencePage.java
index c44796f..23c361c 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/GeneralPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/GeneralPreferencePage.java
@@ -6,19 +6,18 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.general.page;
+package com.google.eclipse.protobuf.ui.preferences.general;
 
-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.general.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.general.PreferenceNames.*;
 import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
-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;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
@@ -44,10 +43,9 @@
     return ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME;
   }
 
-  @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
-    GeneralPreferences preferences = new GeneralPreferences(getPreferenceStore());
-    preferenceBinder.addAll(
-        bindSelectionOf(btnValidateOnActivation).to(preferences.validateFilesOnActivation())
+  @Override protected void setupBinding(PreferenceBinder binder, PreferenceFactory factory) {
+    binder.addAll(
+        bindSelectionOf(btnValidateOnActivation).to(factory.newBooleanPreference(VALIDATE_FILES_ON_ACTIVATION))
       );
   }
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/GeneralPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/GeneralPreferences.java
new file mode 100644
index 0000000..b9a3300
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/GeneralPreferences.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import static com.google.eclipse.protobuf.ui.preferences.general.PreferenceNames.*;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class GeneralPreferences {
+  private final IPreferenceStore store;
+
+  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 GeneralPreferences(IPreferenceStore store) {
+    this.store = store;
+  }
+
+  public boolean shouldValidateFilesOnActivation() {
+    return store.getBoolean(VALIDATE_FILES_ON_ACTIVATION);
+  }
+
+  public static class Initializer implements IPreferenceStoreInitializer {
+    @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+      IPreferenceStore store = storeAccess.getWritablePreferenceStore();
+      store.setDefault(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME, false);
+      store.setDefault(VALIDATE_FILES_ON_ACTIVATION, true);
+    }
+  }
+}
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/Messages.java
similarity index 90%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/Messages.java
index 5fa0043..6685356 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.general.page;
+package com.google.eclipse.protobuf.ui.preferences.general;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/page/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/PreferenceNames.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/PreferenceNames.java
new file mode 100644
index 0000000..2987ec4
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/PreferenceNames.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 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;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ *
+ */
+final class PreferenceNames {
+  static final String ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME = "general.enableProjectSettings";
+  static final String VALIDATE_FILES_ON_ACTIVATION = "general.validateFilesOnActivation";
+
+  private PreferenceNames() {}
+}
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
deleted file mode 100644
index 364b26b..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferenceStoreInitializer.java
+++ /dev/null
@@ -1,26 +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.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 {
-  @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
deleted file mode 100644
index 23488a0..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/general/core/GeneralPreferences.java
+++ /dev/null
@@ -1,67 +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.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/misc/MiscellaneousPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/MiscellaneousPreferences.java
new file mode 100644
index 0000000..7dc6de3
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/MiscellaneousPreferences.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.misc;
+
+import static com.google.eclipse.protobuf.ui.preferences.misc.PreferenceNames.IS_GOOGLE_INTERNAL;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * "Miscellaneous" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class MiscellaneousPreferences {
+  private final IPreferenceStore store;
+
+  public MiscellaneousPreferences(IPreferenceStoreAccess storeAccess) {
+    this.store = storeAccess.getWritablePreferenceStore();
+  }
+
+  public boolean isGoogleInternal() {
+    return store.getBoolean(IS_GOOGLE_INTERNAL);
+  }
+
+  public static class Initializer implements IPreferenceStoreInitializer {
+    @Override public void initialize(IPreferenceStoreAccess storeAccess) {
+      IPreferenceStore store = storeAccess.getWritablePreferenceStore();
+      store.setDefault(IS_GOOGLE_INTERNAL, false);
+    }
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/PreferenceNames.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/PreferenceNames.java
new file mode 100644
index 0000000..fad4e48
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/PreferenceNames.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2012 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.misc;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+final class PreferenceNames {
+
+  static final String IS_GOOGLE_INTERNAL = "misc.googleInternal";
+
+  private PreferenceNames() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferenceStoreInitializer.java
deleted file mode 100644
index 0d394fe..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferenceStoreInitializer.java
+++ /dev/null
@@ -1,23 +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.misc.core;
-
-import org.eclipse.xtext.ui.editor.preferences.*;
-
-/**
- * Initializes default values for the "parser checks" preferences.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class MiscellaneousPreferenceStoreInitializer implements IPreferenceStoreInitializer {
-  @Override public void initialize(IPreferenceStoreAccess storeAccess) {
-    MiscellaneousPreferences preferences = new MiscellaneousPreferences(storeAccess);
-    preferences.isGoogleInternal().setDefaultValue(false);
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferences.java
deleted file mode 100644
index a4f2aed..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferences.java
+++ /dev/null
@@ -1,47 +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.misc.core;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-
-/**
- * "Miscellaneous" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class MiscellaneousPreferences {
-  private final BooleanPreference googleInternal;
-
-  /**
-   * Creates a new <code>{@link MiscellaneousPreferences}</code>.
-   * @param storeAccess simplified access to Eclipse's preferences.
-   */
-  public MiscellaneousPreferences(IPreferenceStoreAccess storeAccess) {
-    this(storeAccess.getWritablePreferenceStore());
-  }
-
-  /**
-   * Creates a new <code>{@link MiscellaneousPreferences}</code>.
-   * @param store a table mapping named preferences to values.
-   */
-  public MiscellaneousPreferences(IPreferenceStore store) {
-    googleInternal = new BooleanPreference("misc.googleInternal", store);
-  }
-
-  /**
-   * Returns the setting that specifies whether the editor is being used inside Google.
-   * @return the setting that specifies whether the editor is being used inside Google.
-   */
-  public BooleanPreference isGoogleInternal() {
-    return googleInternal;
-  }
-}
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 27e7736..c799f1c 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
@@ -25,8 +25,7 @@
 import org.eclipse.ui.*;
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
 import com.google.inject.Inject;
 
 /**
@@ -49,10 +48,11 @@
   @Override protected Control createContents(Composite parent) {
     Composite contents = contentParent(parent);
     doCreateContents(contents);
+    PreferenceFactory preferenceFactory = new PreferenceFactory(getPreferenceStore());
     if (isPropertyPage()) {
-      setupBindingOfBtnEnabledProjectSettings();
+      setupBindingOfBtnEnabledProjectSettings(preferenceFactory);
     }
-    setupBinding(preferenceBinder);
+    setupBinding(preferenceBinder, preferenceFactory);
     preferenceBinder.applyValues();
     updateContents();
     return contents;
@@ -122,12 +122,12 @@
    */
   protected abstract void doCreateContents(Composite parent);
 
-  private void setupBindingOfBtnEnabledProjectSettings() {
+  private void setupBindingOfBtnEnabledProjectSettings(PreferenceFactory factory) {
     String preferenceName = enableProjectSettingsPreferenceName();
     if (isEmpty(preferenceName)) {
       return;
     }
-    BooleanPreference preference = new BooleanPreference(preferenceName, getPreferenceStore());
+    Preference<Boolean> preference = factory.newBooleanPreference(preferenceName);
     preferenceBinder.add(bindSelectionOf(btnEnableProjectSettings).to(preference));
   }
 
@@ -141,9 +141,10 @@
 
   /**
    * Sets up data binding.
-   * @param preferenceBinder the preference binder;
+   * @param binder binds preferences to widgets.
+   * @param factory factory of preferences.
    */
-  protected abstract void setupBinding(PreferenceBinder preferenceBinder);
+  protected abstract void setupBinding(PreferenceBinder binder, PreferenceFactory factory);
 
   /**
    * Returns the id of this preference page.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/AbstractPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/AbstractPreference.java
new file mode 100644
index 0000000..19c1c19
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/AbstractPreference.java
@@ -0,0 +1,35 @@
+/*
+ * 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.binding;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Base class for implementations of <code>{@link Preference}</code>.
+ * @param <T> the type of value this preference handles.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public abstract class AbstractPreference<T> implements Preference<T> {
+  private final String name;
+  private final IPreferenceStore store;
+
+  public AbstractPreference(String name, IPreferenceStore store) {
+    this.name = name;
+    this.store = store;
+  }
+
+  @Override public String name() {
+    return name;
+  }
+
+  protected IPreferenceStore getPreferenceStore() {
+    return store;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection.java
index 1627341..3054184 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToButtonSelection.java
@@ -8,71 +8,49 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
-import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.Button;
 
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
 
 /**
- * Binds a {@code boolean} value from a <code>{@link IPreferenceStore}</code> to the selection of a
- * <code>{@link Button}</code>.
- *
  * @author alruiz@google.com (Alex Ruiz)
  */
 public class BindingToButtonSelection implements Binding {
   private final Button button;
-  private final BooleanPreference preference;
+  private final Preference<Boolean> preference;
 
   public static BindingBuilder bindSelectionOf(Button button) {
     return new BindingBuilder(button);
   }
 
-  /**
-   * Creates a new </code>{@link BindingToButtonSelection}</code>.
-   * @param button the control to bind to the preference.
-   * @param preference the given preference.
-   */
-  private BindingToButtonSelection(Button button, BooleanPreference preference) {
+  private BindingToButtonSelection(Button button, Preference<Boolean> preference) {
     this.preference = preference;
     this.button = button;
   }
 
-  /** {@inheritDoc} */
   @Override public void applyPreferenceValueToTarget() {
-    apply(preference.getValue());
+    apply(preference.value());
   }
 
-  /** {@inheritDoc} */
   @Override public void applyDefaultPreferenceValueToTarget() {
-    apply(preference.getDefaultValue());
+    apply(preference.defaultValue());
   }
 
   private void apply(boolean value) {
     button.setSelection(value);
   }
 
-  /** {@inheritDoc} */
   @Override public void savePreferenceValue() {
-    preference.setValue(button.getSelection());
+    preference.updateValue(button.getSelection());
   }
 
   public static class BindingBuilder {
     private final Button button;
 
-    /**
-     * Creates a new </code>{@link BindingBuilder}</code>.
-     * @param button the button whose selection will be bound to a preference value.
-     */
-    public BindingBuilder(Button button) {
+    BindingBuilder(Button button) {
       this.button = button;
     }
 
-    /**
-     * Creates a new <code>{@link BindingToButtonSelection}</code>.
-     * @param preference the preference to bind to the selection of this builder's button.
-     * @return the created binding.
-     */
-    public BindingToButtonSelection to(BooleanPreference preference) {
+    public BindingToButtonSelection to(Preference<Boolean> preference) {
       return new BindingToButtonSelection(button, preference);
     }
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems.java
index d39fabb..7a7e02c 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToListItems.java
@@ -8,47 +8,36 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
-import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.ImmutableList.copyOf;
 
 import java.util.Collection;
 
-import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.List;
 
-import com.google.eclipse.protobuf.ui.preferences.StringListPreference;
+import com.google.common.collect.ImmutableList;
 
 /**
- * Binds a {@code String} value from a <code>{@link IPreferenceStore}</code> to a list of items of a
- * <code>{@link List}</code>.
- *
  * @author alruiz@google.com (Alex Ruiz)
  */
 public class BindingToListItems implements Binding {
   private final List list;
-  private final StringListPreference preference;
+  private final Preference<ImmutableList<String>> preference;
 
   public static BindingBuilder bindItemsOf(List list) {
     return new BindingBuilder(list);
   }
 
-  /**
-   * Creates a new </code>{@link BindingToListItems}</code>.
-   * @param list the control to bind to the preference.
-   * @param preference the given preference.
-   */
-  private BindingToListItems(List list, StringListPreference preference) {
+  private BindingToListItems(List list, Preference<ImmutableList<String>> preference) {
     this.list = list;
     this.preference = preference;
   }
 
-  /** {@inheritDoc} */
   @Override public void applyPreferenceValueToTarget() {
-    apply(preference.getValue());
+    apply(preference.value());
   }
 
-  /** {@inheritDoc} */
   @Override public void applyDefaultPreferenceValueToTarget() {
-    apply(preference.getDefaultValue());
+    apply(preference.defaultValue());
   }
 
   private void apply(Collection<String> value) {
@@ -58,28 +47,18 @@
     }
   }
 
-  /** {@inheritDoc} */
   @Override public void savePreferenceValue() {
-    preference.setValue(newArrayList(list.getItems()));
+    preference.updateValue(copyOf(list.getItems()));
   }
 
   public static class BindingBuilder {
     private final List list;
 
-    /**
-     * Creates a new </code>{@link BindingBuilder}</code>.
-     * @param list the list whose items will be bound to a preference value.
-     */
-    public BindingBuilder(List list) {
+    BindingBuilder(List list) {
       this.list = list;
     }
 
-    /**
-     * Creates a new <code>{@link BindingToListItems}</code>.
-     * @param preference the preference to bind to the value of this builder's list.
-     * @return the created binding.
-     */
-    public BindingToListItems to(StringListPreference preference) {
+    public BindingToListItems to(Preference<ImmutableList<String>> preference) {
       return new BindingToListItems(list, preference);
     }
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue.java
index aa0538e..c1783ef 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BindingToTextValue.java
@@ -8,71 +8,49 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.pages.binding;
 
-import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.Text;
 
-import com.google.eclipse.protobuf.ui.preferences.StringPreference;
 
 /**
- * Binds a {@code String} value from a <code>{@link IPreferenceStore}</code> to the value of a
- * <code>{@link Text}</code>.
- *
  * @author alruiz@google.com (Alex Ruiz)
  */
 public class BindingToTextValue implements Binding {
   private final Text text;
-  private final StringPreference preference;
+  private final Preference<String> preference;
 
   public static BindingBuilder bindTextOf(Text text) {
     return new BindingBuilder(text);
   }
 
-  /**
-   * Creates a new </code>{@link BindingToTextValue}</code>.
-   * @param text the control to bind to the preference.
-   * @param preference the given preference.
-   */
-  private BindingToTextValue(Text text, StringPreference preference) {
+  private BindingToTextValue(Text text, Preference<String> preference) {
     this.text = text;
     this.preference = preference;
   }
 
-  /** {@inheritDoc} */
   @Override public void applyPreferenceValueToTarget() {
-    apply(preference.getValue());
+    apply(preference.value());
   }
 
-  /** {@inheritDoc} */
   @Override public void applyDefaultPreferenceValueToTarget() {
-    apply(preference.getDefaultValue());
+    apply(preference.defaultValue());
   }
 
   private void apply(String value) {
     text.setText(value);
   }
 
-  /** {@inheritDoc} */
   @Override public void savePreferenceValue() {
-    preference.setValue(text.getText());
+    preference.updateValue(text.getText());
   }
 
   public static class BindingBuilder {
     private final Text text;
 
-    /**
-     * Creates a new </code>{@link BindingBuilder}</code>.
-     * @param text the text whose value will be bound to a preference value.
-     */
-    public BindingBuilder(Text text) {
+    BindingBuilder(Text text) {
       this.text = text;
     }
 
-    /**
-     * Creates a new <code>{@link BindingToTextValue}</code>.
-     * @param preference the preference to bind to the value of this builder's text.
-     * @return the created binding.
-     */
-    public BindingToTextValue to(StringPreference preference) {
+    public BindingToTextValue to(Preference<String> preference) {
       return new BindingToTextValue(text, preference);
     }
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BooleanPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BooleanPreference.java
new file mode 100644
index 0000000..7112f47
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/BooleanPreference.java
@@ -0,0 +1,35 @@
+/*
+ * 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.binding;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * A preference that stores a {@code boolean} value.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class BooleanPreference extends AbstractPreference<Boolean> {
+
+  BooleanPreference(String name, IPreferenceStore store) {
+    super(name, store);
+  }
+
+  @Override public Boolean value() {
+    return getPreferenceStore().getBoolean(name());
+  }
+
+  @Override public Boolean defaultValue() {
+    return getPreferenceStore().getDefaultBoolean(name());
+  }
+
+  @Override public void updateValue(Boolean value) {
+    getPreferenceStore().setValue(name(), value);
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/Preference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/Preference.java
new file mode 100644
index 0000000..f996ecc
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/Preference.java
@@ -0,0 +1,25 @@
+/*
+ * 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.binding;
+
+/**
+ * A single preference value.
+ * @param <T> the type of value this preference handles.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public interface Preference<T> {
+  String name();
+
+  T value();
+
+  T defaultValue();
+
+  void updateValue(T value);
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/PreferenceFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/PreferenceFactory.java
new file mode 100644
index 0000000..81bd736
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/PreferenceFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 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.binding;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import com.google.common.collect.ImmutableList;
+import com.google.eclipse.protobuf.ui.preferences.StringSplitter;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class PreferenceFactory {
+  private final IPreferenceStore store;
+
+  public PreferenceFactory(IPreferenceStore store) {
+    this.store = store;
+  }
+
+  public Preference<Boolean> newBooleanPreference(String name) {
+    return new BooleanPreference(name, store);
+  }
+
+  public Preference<String> newStringPreference(String name) {
+    return new StringPreference(name, store);
+  }
+
+   public Preference<ImmutableList<String>> newStringListPreference(String name, StringSplitter splitter) {
+    return new StringListPreference(name, splitter, store);
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/StringListPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/StringListPreference.java
new file mode 100644
index 0000000..dfe312a
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/StringListPreference.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.pages.binding;
+
+import static org.eclipse.xtext.util.Strings.concat;
+
+import java.util.List;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import com.google.common.collect.ImmutableList;
+import com.google.eclipse.protobuf.ui.preferences.StringSplitter;
+
+/**
+ * A preference that stores a list of {@code String} values.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class StringListPreference extends AbstractPreference<ImmutableList<String>> {
+  private final StringSplitter splitter;
+
+  StringListPreference(String name, StringSplitter splitter, IPreferenceStore store) {
+    super(name, store);
+    this.splitter = splitter;
+  }
+
+  @Override public ImmutableList<String> value() {
+    String value = getPreferenceStore().getString(name());
+    return splitter.splitIntoList(value);
+  }
+
+  @Override public ImmutableList<String> defaultValue() {
+    String defaultValue = getPreferenceStore().getDefaultString(name());
+    return splitter.splitIntoList(defaultValue);
+  }
+
+  @Override public void updateValue(ImmutableList<String> value) {
+    getPreferenceStore().setValue(name(), concatenate(value));
+  }
+
+  private String concatenate(List<String> value) {
+    return concat(splitter.delimiter(), value);
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/StringPreference.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/StringPreference.java
new file mode 100644
index 0000000..9398432
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/binding/StringPreference.java
@@ -0,0 +1,34 @@
+/*
+ * 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.binding;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * A preference that stores a {@code String} value.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class StringPreference extends AbstractPreference<String> {
+  StringPreference(String name, IPreferenceStore store) {
+    super(name, store);
+  }
+
+  @Override public String value() {
+    return getPreferenceStore().getString(name());
+  }
+
+  @Override public String defaultValue() {
+    return getPreferenceStore().getDefaultString(name());
+  }
+
+  @Override public void updateValue(String value) {
+    getPreferenceStore().setValue(name(), value);
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/AddDirectoryDialog.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/AddDirectoryDialog.java
similarity index 92%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/AddDirectoryDialog.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/AddDirectoryDialog.java
index c6d8845..8856738 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/AddDirectoryDialog.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/AddDirectoryDialog.java
@@ -6,11 +6,11 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.paths.page;
+package com.google.eclipse.protobuf.ui.preferences.paths;
 
 import static com.google.eclipse.protobuf.ui.preferences.pages.TextWidgets.setEditable;
-import static com.google.eclipse.protobuf.ui.preferences.paths.page.DirectorySelectionDialogs.*;
-import static com.google.eclipse.protobuf.ui.preferences.paths.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.paths.DirectorySelectionDialogs.*;
+import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.*;
 import static org.eclipse.jface.dialogs.IDialogConstants.OK_ID;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
@@ -22,7 +22,6 @@
 import org.eclipse.swt.widgets.*;
 
 import com.google.eclipse.protobuf.ui.preferences.pages.InputDialog;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.ProjectVariable;
 
 /**
  * Dialog where users can select a path (in the workspace or file system) to be included in resolution of imports.
@@ -51,7 +50,6 @@
     this.project = project;
   }
 
-  /** {@inheritDoc} */
   @Override protected Control createDialogArea(Composite parent) {
     Composite cmpDialogArea = (Composite) super.createDialogArea(parent);
 
@@ -124,14 +122,12 @@
     });
   }
 
-  /** {@inheritDoc} */
   @Override protected void createButtonsForButtonBar(Composite parent) {
     super.createButtonsForButtonBar(parent);
     getButton(OK_ID).setEnabled(false);
     txtPath.setFocus();
   }
 
-  /** {@inheritDoc} */
   @Override protected void okPressed() {
     selectedPath = enteredPathText();
     if (btnIsWorkspacePath.getSelection()) {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/DirectoryPath.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryPath.java
similarity index 93%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/DirectoryPath.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryPath.java
index d66cdf5..20eeb18 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/DirectoryPath.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryPath.java
@@ -6,9 +6,9 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.paths.core;
+package com.google.eclipse.protobuf.ui.preferences.paths;
 
-import static com.google.eclipse.protobuf.ui.preferences.paths.core.ProjectVariable.replaceProjectVariableWithProjectName;
+import static com.google.eclipse.protobuf.ui.preferences.paths.ProjectVariable.replaceProjectVariableWithProjectName;
 import static com.google.eclipse.protobuf.ui.util.IPaths.directoryLocationInWorkspace;
 
 import java.util.regex.*;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/DirectoryPathsEditor.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryPathsEditor.java
similarity index 96%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/DirectoryPathsEditor.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryPathsEditor.java
index b633509..7dd0139 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/DirectoryPathsEditor.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryPathsEditor.java
@@ -6,9 +6,9 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.paths.page;
+package com.google.eclipse.protobuf.ui.preferences.paths;
 
-import static com.google.eclipse.protobuf.ui.preferences.paths.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.*;
 import static java.util.Collections.unmodifiableList;
 import static org.eclipse.jface.window.Window.OK;
 
@@ -25,7 +25,6 @@
 import org.eclipse.xtext.ui.PluginImageHelper;
 
 import com.google.eclipse.protobuf.ui.preferences.pages.DataChangedListener;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.DirectoryPath;
 
 /**
  * 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/paths/page/DirectorySelectionDialogs.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectorySelectionDialogs.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/DirectorySelectionDialogs.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectorySelectionDialogs.java
index 662d065..8d993e0 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/DirectorySelectionDialogs.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectorySelectionDialogs.java
@@ -6,10 +6,10 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.paths.page;
+package com.google.eclipse.protobuf.ui.preferences.paths;
 
 import static com.google.eclipse.protobuf.ui.ProtobufUiModule.PLUGIN_ID;
-import static com.google.eclipse.protobuf.ui.preferences.paths.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.*;
 import static com.google.eclipse.protobuf.ui.util.Workspaces.workspaceRoot;
 import static org.eclipse.core.runtime.IStatus.ERROR;
 import static org.eclipse.core.runtime.Status.OK_STATUS;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/Messages.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.java
index beba9e5..d622c69 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.paths.page;
+package com.google.eclipse.protobuf.ui.preferences.paths;
 
 import org.eclipse.osgi.util.NLS;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.properties
similarity index 100%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/Messages.properties
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.properties
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/PathsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferencePage.java
similarity index 88%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/PathsPreferencePage.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferencePage.java
index f2c97cb..ea1c09d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/page/PathsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferencePage.java
@@ -6,13 +6,14 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.paths.page;
+package com.google.eclipse.protobuf.ui.preferences.paths;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.eclipse.protobuf.ui.ProtobufUiModule.PLUGIN_ID;
 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.paths.page.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.*;
+import static com.google.eclipse.protobuf.ui.preferences.paths.PreferenceNames.*;
 import static java.util.Collections.unmodifiableList;
 import static org.eclipse.core.resources.IncrementalProjectBuilder.FULL_BUILD;
 import static org.eclipse.core.runtime.Status.OK_STATUS;
@@ -32,7 +33,6 @@
 
 import com.google.eclipse.protobuf.ui.preferences.pages.*;
 import com.google.eclipse.protobuf.ui.preferences.pages.binding.*;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferences;
 import com.google.eclipse.protobuf.ui.validation.ValidationTrigger;
 import com.google.inject.Inject;
 
@@ -108,29 +108,27 @@
     pageIsNowValid();
   }
 
-
-
   @Override protected String enableProjectSettingsPreferenceName() {
     return null; // this page is always a "Project Properties" page
   }
 
-  @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
-    final PathsPreferences preferences = new PathsPreferences(getPreferenceStore());
-    preferenceBinder.addAll(
-        bindSelectionOf(btnOneDirectoryOnly).to(preferences.filesInOneDirectoryOnly()),
-        bindSelectionOf(btnMultipleDirectories).to(preferences.filesInMultipleDirectories())
+  @Override protected void setupBinding(PreferenceBinder binder, PreferenceFactory factory) {
+    binder.addAll(
+        bindSelectionOf(btnOneDirectoryOnly).to(factory.newBooleanPreference(FILES_IN_ONE_DIRECTORY_ONLY)),
+        bindSelectionOf(btnMultipleDirectories).to(factory.newBooleanPreference(FILES_IN_MULTIPLE_DIRECTORIES))
       );
-    preferenceBinder.add(new Binding() {
+    final Preference<String> directoryPaths = factory.newStringPreference(DIRECTORY_PATHS);
+    binder.add(new Binding() {
       @Override public void applyPreferenceValueToTarget() {
-        setDirectoryPaths(preferences.directoryPaths().getValue());
+        setDirectoryPaths(directoryPaths.value());
       }
 
       @Override public void applyDefaultPreferenceValueToTarget() {
-        setDirectoryPaths(preferences.directoryPaths().getDefaultValue());
+        setDirectoryPaths(directoryPaths.defaultValue());
       }
 
       @Override public void savePreferenceValue() {
-        preferences.directoryPaths().setValue(directoryNames());
+        directoryPaths.updateValue(directoryNames());
       }
     });
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferences.java
new file mode 100644
index 0000000..58c3fd7
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferences.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+import static com.google.eclipse.protobuf.ui.preferences.paths.DirectoryPath.parse;
+import static com.google.eclipse.protobuf.ui.preferences.paths.PreferenceNames.*;
+import static com.google.eclipse.protobuf.ui.util.CommaSeparatedValues.splitCsv;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+import com.google.common.base.Function;
+
+/**
+ * "Paths" preferences, retrieved from an <code>{@link IPreferenceStore}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class PathsPreferences {
+  private final IProject project;
+  private final IPreferenceStore store;
+
+  public PathsPreferences(IPreferenceStoreAccess storeAccess, IProject project) {
+    this.store = storeAccess.getWritablePreferenceStore(project);
+    this.project = project;
+  }
+
+  public boolean areFilesInMultipleDirectories() {
+    return store.getBoolean(FILES_IN_MULTIPLE_DIRECTORIES);
+  }
+
+  public <T> T applyToEachDirectoryPath(Function<DirectoryPath, T> function) {
+    String directoryPaths = store.getString(DIRECTORY_PATHS);
+    for (String s : splitCsv(directoryPaths)) {
+      DirectoryPath path = parse(s, project);
+      T value = function.apply(path);
+      if (value != null) {
+        return value;
+      }
+    }
+    return null;
+  }
+
+  public IProject project() {
+    return project;
+  }
+
+  public static class Initializer implements IPreferenceStoreInitializer {
+    @Override public void initialize(IPreferenceStoreAccess access) {
+      IPreferenceStore store = access.getWritablePreferenceStore();
+      store.setDefault(FILES_IN_ONE_DIRECTORY_ONLY, true);
+      store.setDefault(FILES_IN_MULTIPLE_DIRECTORIES, false);
+      store.setDefault(DIRECTORY_PATHS, "");
+    }
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PreferenceNames.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PreferenceNames.java
new file mode 100644
index 0000000..c56c0f3
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PreferenceNames.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 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;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+final class PreferenceNames {
+  static final String FILES_IN_ONE_DIRECTORY_ONLY= "paths.filesInOneDirectoryOnly";
+  static final String FILES_IN_MULTIPLE_DIRECTORIES = "paths.filesInMultipleDirectories";
+  static final String DIRECTORY_PATHS = "paths.directoryPaths";
+
+  private PreferenceNames() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/ProjectVariable.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/ProjectVariable.java
index d23de01..2b7b3d9 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/ProjectVariable.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/ProjectVariable.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.preferences.paths.core;
+package com.google.eclipse.protobuf.ui.preferences.paths;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.*;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferenceStoreInitializer.java
deleted file mode 100644
index bcfc596..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferenceStoreInitializer.java
+++ /dev/null
@@ -1,27 +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.paths.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 PathsPreferenceStoreInitializer implements IPreferenceStoreInitializer {
-  @Override public void initialize(IPreferenceStoreAccess access) {
-    IPreferenceStore store = access.getWritablePreferenceStore();
-    PathsPreferences preferences = new PathsPreferences(store);
-    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/paths/core/PathsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferences.java
deleted file mode 100644
index e197f18..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/core/PathsPreferences.java
+++ /dev/null
@@ -1,91 +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.paths.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.*;
-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;
-  private final IProject project;
-
-  /**
-   * Creates a new <code>{@link PathsPreferences}</code>.
-   * @param storeAccess simplified access to Eclipse's preferences.
-   * @param project the current project.
-   */
-  public PathsPreferences(IPreferenceStoreAccess storeAccess, IProject project) {
-    this(storeAccess.getWritablePreferenceStore(project), project);
-  }
-
-  /**
-   * Creates a new <code>{@link SaveActionsPreferences}</code>.
-   * @param store a table mapping named preferences to values.
-   */
-  public PathsPreferences(IPreferenceStore store) {
-    this(store, null);
-  }
-
-  /**
-   * Creates a new <code>{@link SaveActionsPreferences}</code>.
-   * @param store a table mapping named preferences to values.
-   * @param project the current project.
-   */
-  public PathsPreferences(IPreferenceStore store, IProject project) {
-    this.project = project;
-    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;
-  }
-
-  /**
-   * Returns the current project.
-   * @return the current project.
-   */
-  public IProject getProject() {
-    return project;
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/AbstractOutputDirectoryProtocOption.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/CodeGenerationProtocOption.java
similarity index 76%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/AbstractOutputDirectoryProtocOption.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/CodeGenerationProtocOption.java
index 7ff7447..575055c 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/AbstractOutputDirectoryProtocOption.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/CodeGenerationProtocOption.java
@@ -15,17 +15,16 @@
 import org.eclipse.core.runtime.*;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
+import com.google.eclipse.protobuf.ui.preferences.compiler.CodeGenerationPreference;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
-abstract class AbstractOutputDirectoryProtocOption implements ProtocOption {
+class CodeGenerationProtocOption implements ProtocOption {
   private static final NullProgressMonitor NO_MONITOR = new NullProgressMonitor();
 
   private final String optionName;
-  private final CompilerPreferences preferences;
+  private final CodeGenerationPreference preferences;
   private final IProject project;
 
   private boolean initialized;
@@ -33,7 +32,7 @@
   private IFolder outputDirectory;
   private String outputDirectoryLocation;
 
-  AbstractOutputDirectoryProtocOption(String optionName, CompilerPreferences preferences, IProject project) {
+  CodeGenerationProtocOption(String optionName, CodeGenerationPreference preferences, IProject project) {
     this.optionName = optionName;
     this.preferences = preferences;
     this.project = project;
@@ -59,10 +58,9 @@
 
   private void initialize() throws CoreException {
     initialized = true;
-    enabled = isEnabled(preferences).getValue();
+    enabled = preferences.isEnabled();
     if (enabled) {
-      String directoryName = outputDirectoryName(preferences).getValue();
-      outputDirectory = findOrCreateDirectory(directoryName);
+      outputDirectory = findOrCreateDirectory(preferences.outputDirectory());
       outputDirectoryLocation = outputDirectory.getLocation().toOSString();
     }
   }
@@ -87,7 +85,4 @@
     }
     return path.split("\\Q" + separator + "\\E");
   }
-
-  abstract BooleanPreference isEnabled(CompilerPreferences p);
-  abstract StringPreference outputDirectoryName(CompilerPreferences p);
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/CppProtocOption.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/CppProtocOption.java
deleted file mode 100644
index 2541c81..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/CppProtocOption.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012 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.protoc.command;
-
-import org.eclipse.core.resources.IProject;
-
-import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class CppProtocOption extends AbstractOutputDirectoryProtocOption {
-  CppProtocOption(CompilerPreferences preferences, IProject project) {
-    super("cpp_out", preferences, project);
-  }
-
-  @Override BooleanPreference isEnabled(CompilerPreferences preferences) {
-    return preferences.cppCodeGenerationEnabled();
-  }
-
-  @Override StringPreference outputDirectoryName(CompilerPreferences preferences) {
-    return preferences.cppOutputDirectory();
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption.java
index ccb48c2..7d9e9c0 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/DescriptorPathProtocOption.java
@@ -13,7 +13,7 @@
 import static org.eclipse.xtext.util.Strings.*;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
+import com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferences;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
@@ -45,7 +45,7 @@
 
   private void initialize() {
     initialized = true;
-    String fullPath = preferences.descriptorPath().getValue();
+    String fullPath = preferences.descriptorPath();
     if (!isEmpty(fullPath)) {
       int indexOfDescriptorFqn = fullPath.indexOf(descriptorFqn);
       if (indexOfDescriptorFqn == -1) {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ImportRootsProtocOption.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ImportRootsProtocOption.java
index ad00e08..6f72854 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ImportRootsProtocOption.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ImportRootsProtocOption.java
@@ -9,8 +9,6 @@
 package com.google.eclipse.protobuf.ui.protoc.command;
 
 import static com.google.common.collect.Lists.newArrayList;
-import static com.google.eclipse.protobuf.ui.preferences.paths.core.DirectoryPath.parse;
-import static com.google.eclipse.protobuf.ui.util.CommaSeparatedValues.splitCsv;
 import static java.util.Collections.emptyList;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
@@ -19,7 +17,8 @@
 
 import org.eclipse.core.resources.*;
 
-import com.google.eclipse.protobuf.ui.preferences.paths.core.*;
+import com.google.common.base.Function;
+import com.google.eclipse.protobuf.ui.preferences.paths.*;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
@@ -51,19 +50,20 @@
 
   private void initialize() {
     initialized = true;
-    if (!preferences.filesInMultipleDirectories().getValue()) {
+    if (!preferences.areFilesInMultipleDirectories()) {
       importRoots =  emptyList();
       return;
     }
     importRoots = newArrayList();
-    String directoryPaths = preferences.directoryPaths().getValue();
-    for (String importRoot : splitCsv(directoryPaths)) {
-      DirectoryPath path = parse(importRoot, project);
-      String location = path.absolutePathInFileSystem();
-      if (!isEmpty(location)) {
-        importRoots.add(location);
+    preferences.applyToEachDirectoryPath(new Function<DirectoryPath, Void>() {
+      @Override public Void apply(DirectoryPath path) {
+        String location = path.absolutePathInFileSystem();
+        if (!isEmpty(location)) {
+          importRoots.add(location);
+        }
+        return null;
       }
-    }
+    });
   }
 
   private String singleImportRoot(IFile protoFile) {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/JavaProtocOption.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/JavaProtocOption.java
deleted file mode 100644
index 498c1cd..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/JavaProtocOption.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012 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.protoc.command;
-
-import org.eclipse.core.resources.IProject;
-
-import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class JavaProtocOption extends AbstractOutputDirectoryProtocOption {
-  JavaProtocOption(CompilerPreferences preferences, IProject project) {
-    super("java_out", preferences, project);
-  }
-
-  @Override BooleanPreference isEnabled(CompilerPreferences preferences) {
-    return preferences.javaCodeGenerationEnabled();
-  }
-
-  @Override StringPreference outputDirectoryName(CompilerPreferences preferences) {
-    return preferences.javaOutputDirectory();
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ProtocCommandBuilder.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ProtocCommandBuilder.java
index 0509dca..8e40507 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ProtocCommandBuilder.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/ProtocCommandBuilder.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.resources.*;
 import org.eclipse.core.runtime.CoreException;
 
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferences;
+import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
 
 /**
  * Builds the command to call protoc to compile a single .proto file.
@@ -32,12 +32,11 @@
 
   public ProtocCommandBuilder(CompilerPreferences compilerPreferences, PathsPreferences pathsPreferences,
       IProject project) {
-    boolean useProtocInSystemPath = compilerPreferences.useProtocInSystemPath().getValue();
-    protocPath = useProtocInSystemPath ? "protoc" : compilerPreferences.protocPath().getValue();
+    protocPath = compilerPreferences.protocPath();
     options.add(new DescriptorPathProtocOption(compilerPreferences));
-    options.add(new JavaProtocOption(compilerPreferences, project));
-    options.add(new CppProtocOption(compilerPreferences, project));
-    options.add(new PythonProtocOption(compilerPreferences, project));
+    options.add(new CodeGenerationProtocOption("java_out", compilerPreferences.javaCodeGeneration(), project));
+    options.add(new CodeGenerationProtocOption("cpp_out", compilerPreferences.cppCodeGeneration(), project));
+    options.add(new CodeGenerationProtocOption("python_out", compilerPreferences.pythonCodeGeneration(), project));
     importRootsProtocOption = new ImportRootsProtocOption(pathsPreferences, project);
   }
 
@@ -65,8 +64,8 @@
   public List<IFolder> outputDirectories() throws CoreException {
     List<IFolder> outputDirectories = newArrayList();
     for (ProtocOption option : options) {
-      if (option instanceof AbstractOutputDirectoryProtocOption) {
-        AbstractOutputDirectoryProtocOption outputDirectoryProtocOption = (AbstractOutputDirectoryProtocOption) option;
+      if (option instanceof CodeGenerationProtocOption) {
+        CodeGenerationProtocOption outputDirectoryProtocOption = (CodeGenerationProtocOption) option;
         IFolder outputDirectory = outputDirectoryProtocOption.outputDirectory();
         if (outputDirectory != null) {
           outputDirectories.add(outputDirectory);
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/PythonProtocOption.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/PythonProtocOption.java
deleted file mode 100644
index 7da9c74..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/protoc/command/PythonProtocOption.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012 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.protoc.command;
-
-import org.eclipse.core.resources.IProject;
-
-import com.google.eclipse.protobuf.ui.preferences.*;
-import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class PythonProtocOption extends AbstractOutputDirectoryProtocOption {
-  PythonProtocOption(CompilerPreferences preferences, IProject project) {
-    super("python_out", preferences, project);
-  }
-
-  @Override BooleanPreference isEnabled(CompilerPreferences preferences) {
-    return preferences.pythonCodeGenerationEnabled();
-  }
-
-  @Override StringPreference outputDirectoryName(CompilerPreferences preferences) {
-    return preferences.pythonOutputDirectory();
-  }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategy.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategy.java
index 2c8f81e..44347bf 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategy.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategy.java
@@ -8,7 +8,7 @@
  */
 package com.google.eclipse.protobuf.ui.scoping;
 
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
 
 import org.eclipse.emf.common.util.URI;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
index 51f57fc..58f41e1 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
@@ -23,7 +23,7 @@
 import com.google.eclipse.protobuf.model.util.Imports;
 import com.google.eclipse.protobuf.protobuf.Import;
 import com.google.eclipse.protobuf.scoping.*;
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
 import com.google.eclipse.protobuf.ui.util.Uris;
 import com.google.inject.Inject;
 
@@ -77,7 +77,7 @@
       return resolver.resolveUri(importUri, resourceUri, preferencesFromAllProjects());
     }
     PathsPreferences preferences = new PathsPreferences(storeAccess, project);
-    if (preferences.filesInOneDirectoryOnly().getValue()) {
+    if (!preferences.areFilesInMultipleDirectories()) {
       resolver = singleDirectory;
     }
     return resolver.resolveUri(importUri, resourceUri, singletonList(preferences));
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy.java
index acd5160..381793a 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy.java
@@ -9,27 +9,21 @@
 package com.google.eclipse.protobuf.ui.scoping;
 
 import static com.google.common.collect.Lists.newArrayList;
-import static com.google.eclipse.protobuf.ui.util.CommaSeparatedValues.splitCsv;
-import static org.eclipse.core.runtime.IPath.SEPARATOR;
-import static org.eclipse.xtext.util.Strings.isEmpty;
 
 import java.util.List;
 
 import org.eclipse.emf.common.util.URI;
 
-import com.google.eclipse.protobuf.ui.preferences.paths.core.*;
-import com.google.eclipse.protobuf.ui.util.Uris;
+import com.google.common.base.Function;
+import com.google.eclipse.protobuf.ui.preferences.paths.*;
 import com.google.inject.Inject;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
 class MultipleDirectoriesFileResolverStrategy implements FileResolverStrategy {
-  private static final String PATH_SEPARATOR = new String(new char[] { SEPARATOR });
-  
-  @Inject private FileSystemPathResolver pathResolver;
+  @Inject private UriResolver uriResolver;
   @Inject private ResourceLocations locations;
-  @Inject private Uris uris;
 
   @Override
   public String resolveUri(String importUri, URI declaringResourceUri, Iterable<PathsPreferences> allPathPreferences) {
@@ -42,70 +36,27 @@
     return null;
   }
 
-  private String resolveUri(String importUri, URI declaringResourceUri, PathsPreferences preferences) {
-    String directoryPaths = preferences.directoryPaths().getValue();
-    List<String> unresolvedWorkspacePaths = newArrayList();
-    for (String importRoot : splitCsv(directoryPaths)) {
-      DirectoryPath path = DirectoryPath.parse(importRoot, preferences.getProject());
-      String resolved = resolveUri(importUri, path);
-      if (resolved != null) {
-        return resolved;
+  private String resolveUri(final String importUri, URI declaringResourceUri, PathsPreferences preferences) {
+    final List<String> unresolvedWorkspacePaths = newArrayList();
+    String resolved = preferences.applyToEachDirectoryPath(new Function<DirectoryPath, String>() {
+      @Override public String apply(DirectoryPath path) {
+        String uri = uriResolver.resolveUri(importUri, path);
+        if (uri == null && path.isWorkspacePath()) {
+          unresolvedWorkspacePaths.add(path.value());
+        }
+        return uri;
       }
-      if (path.isWorkspacePath()) {
-        unresolvedWorkspacePaths.add(path.value());
-      }
+    });
+    if (resolved != null) {
+      return resolved;
     }
     for (String root : unresolvedWorkspacePaths) {
       String directoryLocation = locations.directoryLocation(root);
-      String resolved = resolveUriInFileSystem(importUri, directoryLocation);
-      if (resolved != null) {
-        return resolved;
+      String uri = uriResolver.resolveUriInFileSystem(importUri, directoryLocation);
+      if (uri != null) {
+        return uri;
       }
     }
     return null;
   }
-
-  private String resolveUri(String importUri, DirectoryPath importRootPath) {
-    URI uri = uri(importUri, importRootPath.value(), importRootPath.isWorkspacePath());
-    return resolveUri(uri);
-  }
-
-  private String resolveUriInFileSystem(String importUri, String importRootPath) {
-    URI uri = fileUri(importUri, importRootPath);
-    return resolveUri(uri);
-  }
-
-  private URI uri(String importUri, String importRootPath, boolean isWorkspacePath) {
-    if (isWorkspacePath) {
-      return platformResourceUri(importUri, importRootPath);
-    }
-    return fileUri(importUri, importRootPath);
-  }
-  
-  private URI platformResourceUri(String importUri, String importRootPath) {
-    String path = buildUriPath(importUri, importRootPath);
-    return URI.createPlatformResourceURI(path, true);
-  }
-  
-  private URI fileUri(String importUri, String importRootPath) {
-    String resolvedImportRootPath = pathResolver.resolvePath(importRootPath);
-    if (isEmpty(resolvedImportRootPath)) {
-      return null;
-    }
-    String path = buildUriPath(importUri, resolvedImportRootPath);
-    return URI.createFileURI(path);
-  }
-  
-  private String buildUriPath(String importUri, String importRootPath) {
-    StringBuilder pathBuilder = new StringBuilder().append(importRootPath);
-    if (!importRootPath.endsWith(PATH_SEPARATOR)) {
-      pathBuilder.append(PATH_SEPARATOR);
-    }
-    pathBuilder.append(importUri);
-    return pathBuilder.toString();
-  }
-
-  private String resolveUri(URI uri) {
-    return (uris.referredResourceExists(uri)) ? uri.toString() : null;
-  }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolverStrategy.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolverStrategy.java
index 57de868..e152824 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolverStrategy.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolverStrategy.java
@@ -11,7 +11,7 @@
 import static org.eclipse.core.runtime.IPath.SEPARATOR;
 import static org.eclipse.emf.common.util.URI.createURI;
 
-import com.google.eclipse.protobuf.ui.preferences.paths.core.PathsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
 import com.google.eclipse.protobuf.ui.util.Uris;
 import com.google.inject.Inject;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/UriResolver.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/UriResolver.java
new file mode 100644
index 0000000..0cb9e78
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/UriResolver.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2012 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.scoping;
+
+import static org.eclipse.core.runtime.IPath.SEPARATOR;
+import static org.eclipse.xtext.util.Strings.isEmpty;
+
+import org.eclipse.emf.common.util.URI;
+
+import com.google.eclipse.protobuf.ui.preferences.paths.DirectoryPath;
+import com.google.eclipse.protobuf.ui.util.Uris;
+import com.google.inject.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton class UriResolver {
+  private static final String PATH_SEPARATOR = new String(new char[] { SEPARATOR });
+
+  @Inject private FileSystemPathResolver pathResolver;
+  @Inject private Uris uris;
+
+  String resolveUri(String importUri, DirectoryPath importRootPath) {
+    URI uri = resolveUri(importUri, importRootPath.value(), importRootPath.isWorkspacePath());
+    return resolveUri(uri);
+  }
+
+  String resolveUriInFileSystem(String importUri, String importRootPath) {
+    URI uri = resolveFileUri(importUri, importRootPath);
+    return resolveUri(uri);
+  }
+
+  private URI resolveUri(String importUri, String importRootPath, boolean isWorkspacePath) {
+    if (isWorkspacePath) {
+      return resolvePlatformResourceUri(importUri, importRootPath);
+    }
+    return resolveFileUri(importUri, importRootPath);
+  }
+
+  private URI resolvePlatformResourceUri(String importUri, String importRootPath) {
+    String path = buildUriPath(importUri, importRootPath);
+    return URI.createPlatformResourceURI(path, true);
+  }
+
+  private URI resolveFileUri(String importUri, String importRootPath) {
+    String resolvedImportRootPath = pathResolver.resolvePath(importRootPath);
+    if (isEmpty(resolvedImportRootPath)) {
+      return null;
+    }
+    String path = buildUriPath(importUri, resolvedImportRootPath);
+    return URI.createFileURI(path);
+  }
+
+  private String buildUriPath(String importUri, String importRootPath) {
+    StringBuilder pathBuilder = new StringBuilder().append(importRootPath);
+    if (!importRootPath.endsWith(PATH_SEPARATOR)) {
+      pathBuilder.append(PATH_SEPARATOR);
+    }
+    pathBuilder.append(importUri);
+    return pathBuilder.toString();
+  }
+
+  private String resolveUri(URI uri) {
+    return (uris.referredResourceExists(uri)) ? uri.toString() : null;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateFileOnActivation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateFileOnActivation.java
index 6762641..f13ede7 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateFileOnActivation.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateFileOnActivation.java
@@ -9,7 +9,7 @@
  */
 package com.google.eclipse.protobuf.ui.validation;
 
-import static com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferences.generalPreferences;
+import static com.google.eclipse.protobuf.ui.preferences.general.GeneralPreferences.generalPreferences;
 import static com.google.eclipse.protobuf.ui.validation.ProtobufValidation.validate;
 
 import org.eclipse.core.resources.IProject;
@@ -17,8 +17,8 @@
 import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
 
 import com.google.eclipse.protobuf.ui.plugin.ProtobufEditorPlugIn;
-import com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferences;
-import com.google.eclipse.protobuf.ui.util.*;
+import com.google.eclipse.protobuf.ui.preferences.general.GeneralPreferences;
+import com.google.eclipse.protobuf.ui.util.Editors;
 
 /**
  * Validates a .proto file when it is opened or activated.
@@ -52,6 +52,6 @@
   private boolean shouldValidateEditor(IProject project) {
     IPreferenceStoreAccess storeAccess = ProtobufEditorPlugIn.getInstanceOf(IPreferenceStoreAccess.class);
     GeneralPreferences preferences = generalPreferences(storeAccess, project);
-    return preferences.validateFilesOnActivation().getValue();
+    return preferences.shouldValidateFilesOnActivation();
   }
 }