Fixed: [Issue 211] Multi-line imports are broken
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
index 88d2473..db92a2e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
@@ -8,22 +8,23 @@
  */
 package com.google.eclipse.protobuf.ui.editor.hyperlinking;
 
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
 import static org.eclipse.emf.common.util.URI.createURI;
 
-import com.google.eclipse.protobuf.model.util.Imports;
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.ui.editor.FileOpener;
-import com.google.inject.Inject;
-
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.text.*;
 import org.eclipse.jface.text.hyperlink.*;
 import org.eclipse.xtext.CrossReference;
+import org.eclipse.xtext.nodemodel.INode;
 import org.eclipse.xtext.resource.*;
 import org.eclipse.xtext.ui.editor.hyperlinking.DefaultHyperlinkDetector;
 import org.eclipse.xtext.ui.editor.model.IXtextDocument;
 import org.eclipse.xtext.util.concurrent.IUnitOfWork;
 
+import com.google.eclipse.protobuf.model.util.*;
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.ui.editor.FileOpener;
+import com.google.inject.Inject;
 
 /**
  * Represents an implementation of interface <code>{@link IHyperlinkDetector}</code> to find and convert
@@ -34,6 +35,7 @@
 public class ProtobufHyperlinkDetector extends DefaultHyperlinkDetector {
   private static final IHyperlink[] NO_HYPERLINKS = null;
 
+  @Inject private INodes nodes;
   @Inject private EObjectAtOffsetHelper eObjectAtOffsetHelper;
   @Inject private FileOpener fileOpener;
   @Inject private Imports imports;
@@ -63,31 +65,15 @@
         if (!imports.isResolved(anImport)) {
           return NO_HYPERLINKS;
         }
-        String importUri = imports.uriAsEnteredByUser(anImport);
-        if (importUri == null) {
+        INode importUriNode = nodes.firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
+        int importUriLength = importUriNode.getLength();
+        if (importUriLength == 0) {
           return NO_HYPERLINKS;
         }
-        IRegion importUriRegion;
-        try {
-          importUriRegion = importUriRegion(document, region.getOffset(), importUri);
-        } catch (BadLocationException e) {
-          return NO_HYPERLINKS;
-        }
-        if (importUriRegion == null) {
-          return NO_HYPERLINKS;
-        }
+        IRegion importUriRegion = new Region(importUriNode.getOffset(), importUriLength);
         IHyperlink hyperlink = new ImportHyperlink(createURI(anImport.getImportURI()), importUriRegion, fileOpener);
         return new IHyperlink[] { hyperlink };
       }
     });
   }
-
-  private IRegion importUriRegion(IXtextDocument document, int offset, String importUri) throws BadLocationException {
-    int lineNumber = document.getLineOfOffset(offset);
-    int lineLength = document.getLineLength(lineNumber);
-    int lineOffset = document.getLineOffset(lineNumber);
-    String line = document.get(lineOffset, lineLength);
-    int uriIndex = line.indexOf(importUri);
-    return new Region(lineOffset + uriIndex, importUri.length());
-  }
 }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java
index a1a64a2..8176a2d 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java
@@ -8,9 +8,11 @@
  */
 package com.google.eclipse.protobuf.conversion;
 
-import static com.google.eclipse.protobuf.util.Strings.*;
+import static com.google.eclipse.protobuf.util.Strings.unquote;
 import static org.eclipse.xtext.util.Strings.convertToJavaString;
 
+import java.util.Scanner;
+
 import org.eclipse.xtext.conversion.ValueConverterException;
 import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter;
 import org.eclipse.xtext.nodemodel.INode;
@@ -26,14 +28,14 @@
       return null;
     }
     // TODO check if we really need to quote
-    return '"' + convertToJavaString(removeLineBreaksFrom(value), false) + '"';
+    return '"' + toValue(value) + '"';
   }
 
   /**
    * Creates a {@code String} from the given input, if the given input represents a multiple-line string.
    * @param string the given input.
    * @param node the parsed node including hidden parts.
-   * @return the new integer.
+   * @return the new {@code String}.
    * @throws ValueConverterException if the given input has illegal characters.
    */
   @Override public String toValue(String string, INode node) throws ValueConverterException {
@@ -41,12 +43,22 @@
       return null;
     }
     try {
-      return convertToJavaString(unquote(removeLineBreaksFrom(string).trim()), true);
-    } catch (IllegalArgumentException e) {
+      return toValue(string);
+    } catch (RuntimeException e) {
       throw parsingError(string, node, e);
     }
   }
 
+  private String toValue(String string) {
+    StringBuilder valueBuilder = new StringBuilder();
+    Scanner scanner = new Scanner(string);
+    while (scanner.hasNextLine()) {
+      String line = scanner.nextLine();
+      valueBuilder.append(convertToJavaString(unquote(line.trim()), true));
+    }
+    return valueBuilder.toString();
+  }
+
   private ValueConverterException parsingError(String string, INode node, Exception cause) {
     return new ValueConverterException("Couldn't convert '" + string + "' to String.", node, cause);
   }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
index d308b3f..a2b4e79 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
@@ -9,19 +9,19 @@
 package com.google.eclipse.protobuf.model.util;
 
 import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
-import static com.google.eclipse.protobuf.util.Strings.*;
-import static org.eclipse.xtext.util.Strings.*;
-
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.resource.ResourceSets;
-import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
-import com.google.inject.Inject;
+import static org.eclipse.xtext.util.Strings.isEmpty;
 
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.resource.*;
 import org.eclipse.xtext.nodemodel.INode;
 import org.eclipse.xtext.scoping.impl.ImportUriResolver;
 
+import com.google.eclipse.protobuf.conversion.STRINGValueConverter;
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.resource.ResourceSets;
+import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
+import com.google.inject.Inject;
+
 /**
  * Utility methods related to imports.
  *
@@ -31,6 +31,7 @@
   @Inject private ProtoDescriptorProvider descriptorProvider;
   @Inject private INodes nodes;
   @Inject private ResourceSets resourceSets;
+  @Inject private STRINGValueConverter converter;
   @Inject private ImportUriResolver uriResolver;
 
   /**
@@ -81,7 +82,7 @@
     if (text == null) {
       return null;
     }
-    return convertToJavaString(unquote(removeLineBreaksFrom(text).trim()), true);
+    return converter.toValue(text, node);
   }
 
   /**
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
index ecc2601..6d736f4 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
@@ -8,6 +8,7 @@
  */
 package com.google.eclipse.protobuf.naming;
 
+import static com.google.eclipse.protobuf.util.Strings.removeLineBreaksFrom;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
 import java.util.regex.Pattern;
@@ -15,7 +16,6 @@
 import org.eclipse.xtext.naming.IQualifiedNameConverter.DefaultImpl;
 import org.eclipse.xtext.naming.*;
 
-import com.google.eclipse.protobuf.util.Strings;
 import com.google.inject.Singleton;
 
 /**
@@ -39,7 +39,7 @@
     if (isEmpty(s)) {
       throw new IllegalArgumentException("Qualified name cannot be null or empty");
     }
-    String withoutLineBreaks = Strings.removeLineBreaksFrom(s);
+    String withoutLineBreaks = removeLineBreaksFrom(s);
     String[] segments = delimiterPattern.split(withoutLineBreaks);
     return QualifiedName.create(segments);
   }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java
index bcaf5fa..e29605e 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java
@@ -8,10 +8,9 @@
  */
 package com.google.eclipse.protobuf.util;
 
-import static java.util.regex.Pattern.compile;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
-import java.util.regex.Pattern;
+import java.util.Scanner;
 
 /**
  * Utility methods related to {@code String}.s
@@ -19,8 +18,6 @@
  * @author alruiz@google.com (Alex Ruiz)
  */
 public final class Strings {
-  private static final Pattern LINE_BREAK = compile("\"[\t\r\n]+\"|'[\t\r\n]+'");
-
   /**
    * Returns a {@code String} containing the given one in double quotes.
    * @param s the given {@code String}, may be {@code null}.
@@ -64,7 +61,13 @@
     if (isEmpty(s)) {
       return s;
     }
-    return LINE_BREAK.matcher(s).replaceAll("");
+    StringBuilder valueBuilder = new StringBuilder();
+    Scanner scanner = new Scanner(s);
+    while (scanner.hasNextLine()) {
+      String line = scanner.nextLine();
+      valueBuilder.append(line.trim());
+    }
+    return valueBuilder.toString();
   }
   private Strings() {}
 }