Fixed: [Issue 89] Proto buffer editor needs to have options to remove
whitespace at end of lines

It works! Needs some cleanup.
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 738f811..84261ea 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java
@@ -10,11 +10,21 @@
 package com.google.eclipse.protobuf.ui.editor.model;
 
 import static com.google.eclipse.protobuf.ui.exception.CoreExceptions.error;
+import static com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferences.RemoveTrailingSpace.*;
 import static com.google.eclipse.protobuf.util.Encodings.UTF_8;
+import static org.eclipse.core.filebuffers.FileBuffers.getTextFileBufferManager;
+import static org.eclipse.core.filebuffers.LocationKind.*;
 import static org.eclipse.text.undo.DocumentUndoManagerRegistry.getDocumentUndoManager;
 
-import org.eclipse.core.runtime.*;
-import org.eclipse.jface.text.*;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.source.IAnnotationModel;
 import org.eclipse.text.edits.TextEdit;
 import org.eclipse.text.undo.IDocumentUndoManager;
@@ -23,6 +33,10 @@
 import org.eclipse.xtext.ui.editor.model.XtextDocument;
 import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider;
 
+import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferences.RemoveTrailingSpace;
+import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferencesFactory;
+import com.google.eclipse.protobuf.ui.util.editor.Editors;
 import com.google.inject.Inject;
 
 /**
@@ -30,7 +44,11 @@
  */
 public class ProtobufDocumentProvider extends XtextDocumentProvider {
 
+  private static final IRegion[] NO_CHANGE = new IRegion[0];
+  
+  @Inject private Editors editors;
   @Inject private DocumentContentsFactoryRegistry contentsFactories;
+  @Inject private SaveActionsPreferencesFactory preferencesFactory;  
   @Inject private SaveActions saveActions;
 
   @Override protected ElementInfo createElementInfo(Object element) throws CoreException {
@@ -71,12 +89,16 @@
 
   @Override protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document,
       boolean overwrite) throws CoreException {
-    if (element instanceof IFileEditorInput) performSaveActions(document);
+    if (element instanceof IFileEditorInput) {
+      performSaveActions(monitor, (IFileEditorInput) element, document);
+    }
     super.doSaveDocument(monitor, element, document, overwrite);
   }
 
-  private void performSaveActions(IDocument document) throws CoreException {
-    TextEdit edit = saveActions.createSaveAction(document, new IRegion[] { allOf(document) });
+  private void performSaveActions(IProgressMonitor monitor,
+      IFileEditorInput editorInput, IDocument document) throws CoreException {
+    IRegion[] changedRegions = changedRegions(monitor, editorInput, document);
+    TextEdit edit = saveActions.createSaveAction(document, changedRegions);
     if (edit == null) return;
     try {
       IDocumentUndoManager manager = getDocumentUndoManager(document);
@@ -87,8 +109,25 @@
       throw error(t);
     }
   }
-
-  private Region allOf(IDocument document) {
-    return new Region(0, document.getLength());
+  
+  private IRegion[] changedRegions(IProgressMonitor monitor, IFileEditorInput editorInput, IDocument document) throws CoreException {
+    SaveActionsPreferences preferences = preferencesFactory.preferences();
+    RemoveTrailingSpace removeTrailingSpace = preferences.removeTrailingSpace();
+    if (removeTrailingSpace.equals(NONE)) return NO_CHANGE;
+    if (removeTrailingSpace.equals(IN_EDITED_LINES)) {
+      return editors.calculateChangedLineRegions(textFileBuffer(monitor, editorInput), document, monitor);
+    }
+    return new IRegion[] { new Region(0, document.getLength()) };
+  }
+  
+  private ITextFileBuffer textFileBuffer(IProgressMonitor monitor, IFileEditorInput editorInput) throws CoreException {
+    IPath location = editorInput.getFile().getFullPath();
+    ITextFileBufferManager textFileBufferManager = getTextFileBufferManager();
+    textFileBufferManager.connect(location, NORMALIZE, monitor);
+    try {
+      return textFileBufferManager.getTextFileBuffer(location, IFILE);
+    } finally {
+      textFileBufferManager.disconnect(location, NORMALIZE, monitor);
+    }
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/SaveActions.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/SaveActions.java
index e72b868..8258517 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/SaveActions.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/SaveActions.java
@@ -13,12 +13,16 @@
 import static org.eclipse.jface.text.IDocumentExtension3.DEFAULT_PARTITIONING;
 import static org.eclipse.jface.text.TextUtilities.getPartition;
 
-import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.*;
-import com.google.inject.*;
-
 import org.apache.log4j.Logger;
-import org.eclipse.jface.text.*;
-import org.eclipse.text.edits.*;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+
+import com.google.inject.Singleton;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
@@ -26,13 +30,9 @@
 @Singleton
 class SaveActions {
 
-  @Inject private SaveActionsPreferencesFactory preferencesFactory;
-  
   private static Logger logger = Logger.getLogger(SaveActions.class);
   
   TextEdit createSaveAction(IDocument document, IRegion[] changedRegions) {
-    SaveActionsPreferences preferences = preferencesFactory.preferences();
-    if (!preferences.shouldRemoveTrailingSpace()) return null;
     TextEdit rootEdit = null;
     try {
       for (IRegion region : changedRegions) {
@@ -52,7 +52,7 @@
         }
       }
     } catch (BadLocationException e) {
-      logger.warn("Unable to create save actions", e);
+      logger.error("Unable to create save actions", e);
     }
     return rootEdit;
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/RawPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/RawPreferences.java
index 3436e56..0aad9be 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/RawPreferences.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/RawPreferences.java
@@ -19,12 +19,24 @@
 class RawPreferences {
 
   private final BooleanPreference removeTrailingWhitespace;
+  private final BooleanPreference inAllLines;
+  private final BooleanPreference inEditedLines;
 
   RawPreferences(IPreferenceStore store) {
     removeTrailingWhitespace = new BooleanPreference("saveActions.removeTrailingWhitespace", store);
+    inAllLines = new BooleanPreference("saveActions.inAllLines", store);
+    inEditedLines = new BooleanPreference("saveActions.inEditedLines", store);
   }
 
   BooleanPreference removeTrailingWhitespace() {
     return removeTrailingWhitespace;
   }
+  
+  BooleanPreference inAllLines() {
+    return inAllLines;
+  }
+
+  BooleanPreference inEditedLines() {
+    return inEditedLines;
+  }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
index 5e3f81e..ecbf94e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
@@ -35,6 +35,10 @@
 
   private Button btnRemoveTrailingwhitespace;
 
+  private Button btnInEditedLines;
+
+  private Button btnInAllLines;
+
   /** {@inheritDoc} */
   public void init(IWorkbench workbench) {}
 
@@ -44,7 +48,19 @@
     btnRemoveTrailingwhitespace = new Button(contents, SWT.CHECK);
     btnRemoveTrailingwhitespace.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1));
     btnRemoveTrailingwhitespace.setText(removeTrailingWhitespace);
+    
+    Composite composite = new Composite(contents, SWT.NONE);
+    composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+    composite.setLayout(new GridLayout(1, false));
+    
+    btnInEditedLines = new Button(composite, SWT.RADIO);
+    btnInEditedLines.setText("In edited lines");
+    
+    btnInAllLines = new Button(composite, SWT.RADIO);
+    btnInAllLines.setText("In all lines");
+    
     setUpBinding();
+    
     preferenceBinder.applyValues();
     return contents;
   }
@@ -52,7 +68,9 @@
   private void setUpBinding() {
     RawPreferences preferences = new RawPreferences(getPreferenceStore());
     preferenceBinder.addAll(
-        bindSelectionOf(btnRemoveTrailingwhitespace).to(preferences.removeTrailingWhitespace())
+        bindSelectionOf(btnRemoveTrailingwhitespace).to(preferences.removeTrailingWhitespace()),
+        bindSelectionOf(btnInAllLines).to(preferences.inAllLines()),
+        bindSelectionOf(btnInEditedLines).to(preferences.inEditedLines())
     );
   }
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferenceStoreInitializer.java
index a2f245b..4d3a0b8 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferenceStoreInitializer.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferenceStoreInitializer.java
@@ -22,6 +22,8 @@
   public void initialize(IPreferenceStoreAccess access) {
     IPreferenceStore store = access.getWritablePreferenceStore();
     RawPreferences preferences = new RawPreferences(store);
-    preferences.removeTrailingWhitespace().defaultValue(false);
+    preferences.removeTrailingWhitespace().defaultValue(true);
+    preferences.inAllLines().defaultValue(false);
+    preferences.inEditedLines().defaultValue(true);
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferences.java
index 0da70ef..4964ad9 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferences.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferences.java
@@ -17,13 +17,22 @@
  */
 public class SaveActionsPreferences {
 
-  private final boolean removeTrailingSpace;
+  private final RemoveTrailingSpace removeTrailingSpace;
   
   SaveActionsPreferences(RawPreferences preferences) {
-    removeTrailingSpace = preferences.removeTrailingWhitespace().value();
+    removeTrailingSpace = RemoveTrailingSpace.valueFrom(preferences);
   }
   
-  public boolean shouldRemoveTrailingSpace() {
+  public RemoveTrailingSpace removeTrailingSpace() {
     return removeTrailingSpace;
   }
+  
+  public static enum RemoveTrailingSpace {
+    NONE, IN_EDITED_LINES, IN_ALL_LINES;
+    
+    static RemoveTrailingSpace valueFrom(RawPreferences preferences) {
+      if (!preferences.removeTrailingWhitespace().value()) return NONE;
+      return preferences.inEditedLines().value() ? IN_EDITED_LINES : IN_ALL_LINES;
+    }
+  }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/editor/Editors.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/editor/Editors.java
index c26d91b..492cf12 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/editor/Editors.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/editor/Editors.java
@@ -38,7 +38,8 @@
 
   private static Logger logger = Logger.getLogger(Editors.class);
   
-  public static IRegion[] calculateChangedLineRegions(final ITextFileBuffer buffer, final IProgressMonitor monitor)
+  public IRegion[] calculateChangedLineRegions(final ITextFileBuffer buffer,
+      final IDocument current, final IProgressMonitor monitor)
       throws CoreException {
     final IRegion[][] result = new IRegion[1][];
     final IStatus[] errorStatus = new IStatus[] { OK_STATUS };
@@ -56,9 +57,8 @@
           ITextFileBufferManager fileBufferManager = createTextFileBufferManager();
           fileBufferManager.connectFileStore(fileStore, getSubProgressMonitor(monitor, 15));
           try {
-            IDocument current = buffer.getDocument();
             IDocument old = ((ITextFileBuffer) fileBufferManager.getFileStoreFileBuffer(fileStore)).getDocument();
-            result[0] = getChangedLineRegions(old, current);
+            result[0] = getChangedLineRegions(old);
           } finally {
             fileBufferManager.disconnectFileStore(fileStore, getSubProgressMonitor(monitor, 5));
             monitor.done();
@@ -69,8 +69,8 @@
          * Returns regions of all lines which differ comparing {@code old}s content with {@code current}s content. 
          * Successive lines are merged into one region.
          */
-        private IRegion[] getChangedLineRegions(IDocument old, IDocument current) {
-          RangeDifference[] differences = differencesBetween(old, current);
+        private IRegion[] getChangedLineRegions(IDocument old) {
+          RangeDifference[] differences = differencesWith(old);
           List<IRegion> regions = new ArrayList<IRegion>();
           int numberOfLines = current.getNumberOfLines();
           for (RangeDifference difference : differences) {
@@ -101,7 +101,7 @@
           return regions.toArray(new IRegion[regions.size()]);
         }
 
-        private RangeDifference[] differencesBetween(IDocument old, IDocument current) {
+        private RangeDifference[] differencesWith(IDocument old) {
           return findDifferences(new LineComparator(old), new LineComparator(current));
         }
       });