Merge "Persist the annotated java file" into develop
diff --git a/org.eclipse.capra.core.feature/.project b/org.eclipse.capra.core.feature/.project
new file mode 100644
index 0000000..a798512
--- /dev/null
+++ b/org.eclipse.capra.core.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.capra.core.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.capra.core.feature/build.properties b/org.eclipse.capra.core.feature/build.properties
new file mode 100644
index 0000000..560c2d8
--- /dev/null
+++ b/org.eclipse.capra.core.feature/build.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+# 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
+#  
+#   Contributors:
+#      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+###############################################################################
+bin.includes = feature.xml
diff --git a/org.eclipse.capra.core.feature/feature.xml b/org.eclipse.capra.core.feature/feature.xml
new file mode 100644
index 0000000..a22cca9
--- /dev/null
+++ b/org.eclipse.capra.core.feature/feature.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.capra.core.feature"
+      label="Capra Core Functionality"
+      version="0.7.0.qualifier"
+      provider-name="Capra Development Team"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+
+   <copyright>
+      Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <plugin
+         id="org.eclipse.capra.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.handler.emf"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.handler.file"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.handler.gef"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.handler.hudson"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.handler.mylyn"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.capra.core.feature/pom.xml b/org.eclipse.capra.core.feature/pom.xml
new file mode 100644
index 0000000..da92ac8
--- /dev/null
+++ b/org.eclipse.capra.core.feature/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+        <modelVersion>4.0.0</modelVersion>
+
+        <parent>
+                <relativePath>../pom.xml</relativePath>
+                <groupId>org.eclipse.capra</groupId>
+                <artifactId>parent</artifactId>
+                <version>0.7.0-SNAPSHOT</version>
+        </parent>
+
+        <artifactId>org.eclipse.capra.core.feature</artifactId>
+        <packaging>eclipse-feature</packaging>
+
+</project>
diff --git a/org.eclipse.capra.feature/feature.xml b/org.eclipse.capra.feature/feature.xml
index 668e003..cb4ee2b 100644
--- a/org.eclipse.capra.feature/feature.xml
+++ b/org.eclipse.capra.feature/feature.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <feature
       id="org.eclipse.capra.feature"
-      label="Capra Core Functionality"
+      label="Capra Main Feature"
       version="0.7.0.qualifier"
       provider-name="Capra Development Team"
       license-feature="org.eclipse.license"
@@ -15,101 +15,16 @@
       %license
    </license>
 
-   <plugin
-         id="org.eclipse.capra.core"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.generic.persistence"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.generic.priority"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.generic.tracemodels"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.handler.emf"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.handler.file"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.handler.gef"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.handler.hudson"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.handler.mylyn"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.handler.papyrus"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.ui.notification"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.capra.documentation"
-         download-size="0"
-         install-size="0"
+   <includes
+         id="org.eclipse.capra.core.feature"
          version="0.0.0"/>
 
-   <plugin
-         id="org.eclipse.capra.ui"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
+   <includes
+         id="org.eclipse.capra.ui.feature"
+         version="0.0.0"/>
 
-   <plugin
-         id="org.eclipse.capra.handler.reqIf"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
+   <includes
+         id="org.eclipse.capra.generic.feature"
+         version="0.0.0"/>
 
 </feature>
diff --git a/org.eclipse.capra.generic.feature/.project b/org.eclipse.capra.generic.feature/.project
new file mode 100644
index 0000000..95efbb7
--- /dev/null
+++ b/org.eclipse.capra.generic.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.capra.generic.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.capra.generic.feature/build.properties b/org.eclipse.capra.generic.feature/build.properties
new file mode 100644
index 0000000..560c2d8
--- /dev/null
+++ b/org.eclipse.capra.generic.feature/build.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+# 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
+#  
+#   Contributors:
+#      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+###############################################################################
+bin.includes = feature.xml
diff --git a/org.eclipse.capra.generic.feature/feature.xml b/org.eclipse.capra.generic.feature/feature.xml
new file mode 100644
index 0000000..596eeb7
--- /dev/null
+++ b/org.eclipse.capra.generic.feature/feature.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.capra.generic.feature"
+      label="Capra Generic Models"
+      version="0.7.0.qualifier"
+      provider-name="Capra Development Team"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+
+   <copyright>
+      Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <plugin
+         id="org.eclipse.capra.generic.persistence"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.generic.priority"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.generic.tracemodels"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.capra.generic.feature/pom.xml b/org.eclipse.capra.generic.feature/pom.xml
new file mode 100644
index 0000000..0d2e304
--- /dev/null
+++ b/org.eclipse.capra.generic.feature/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+        <modelVersion>4.0.0</modelVersion>
+
+        <parent>
+                <relativePath>../pom.xml</relativePath>
+                <groupId>org.eclipse.capra</groupId>
+                <artifactId>parent</artifactId>
+                <version>0.7.0-SNAPSHOT</version>
+        </parent>
+
+        <artifactId>org.eclipse.capra.generic.feature</artifactId>
+        <packaging>eclipse-feature</packaging>
+
+</project>
diff --git a/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java b/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java
index 9eb58a0..b721304 100644
--- a/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java
+++ b/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java
@@ -14,7 +14,7 @@
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
 import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
-import org.eclipse.capra.ui.office.objects.CapraOfficeObject;
+import org.eclipse.capra.ui.office.model.CapraOfficeObject;
 import org.eclipse.emf.ecore.EObject;
 
 /**
@@ -33,7 +33,7 @@
 		// TODO here artifactName is the same as the row/paragraph
 		// description. Should it be different?
 		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), officeObject.getUri(),
-				officeObject.getName());
+				officeObject.getId());
 		return wrapper;
 	}
 
@@ -48,7 +48,7 @@
 
 	@Override
 	public String getDisplayName(CapraOfficeObject officeObject) {
-		return officeObject.getName();
+		return officeObject.getId();
 	}
 
 }
diff --git a/org.eclipse.capra.releng.p2/category.xml b/org.eclipse.capra.releng.p2/category.xml
index 4382d51..fcd3392 100644
--- a/org.eclipse.capra.releng.p2/category.xml
+++ b/org.eclipse.capra.releng.p2/category.xml
@@ -32,7 +32,7 @@
    </feature>
    <category-def name="org.eclipse.capra" label="Capra Traceability">
       <description>
-         Capra is an extensible traceability mangement tool.
+         Capra is an extensible traceability management tool.
       </description>
    </category-def>
    <category-def name="org.eclipse.capra.handler" label="Capra Traceability Handlers">
diff --git a/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target b/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target
index ce71547..76c6c2f 100644
--- a/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target
+++ b/org.eclipse.capra.releng.target/org.eclipse.capra.releng.target.target
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?pde version="3.8"?><target name="Neon" sequenceNumber="49">
+<?pde version="3.8"?><target name="Neon" sequenceNumber="52">
 <locations>
 <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
 <unit id="net.sourceforge.plantuml.feature.feature.group" version="0.0.0"/>
@@ -20,7 +20,9 @@
 <repository location="http://download.eclipse.org/tools/gef/gef4/updates/releases"/>
 </location>
 <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
-<repository location="http://download.eclipse.org/releases/neon"/>
+<unit id="org.mortbay.jetty.util" version="6.1.23.v201012071420"/>
+<unit id="org.mortbay.jetty.server" version="6.1.23.v201012071420"/>
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20160221192158/repository/"/>
 </location>
 <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
 <unit id="org.eclipse.rmf.reqif10.sdk.feature.feature.group" version="0.13.0.201509161042"/>
@@ -68,6 +70,7 @@
 <unit id="org.apache.commons.collections" version="3.2.2.v201511171945"/>
 <unit id="org.apache.poi.ooxml.schemas" version="3.9.0.v201405241750"/>
 <unit id="org.apache.poi" version="3.9.0.v201405241750"/>
+<unit id="com.fasterxml.jackson.core.jackson-core" version="2.5.0.v201504151636"/>
 <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20160520211859/repository"/>
 </location>
 </locations>
diff --git a/org.eclipse.capra.ui.drive/.classpath b/org.eclipse.capra.ui.drive/.classpath
new file mode 100644
index 0000000..0f05a44
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry exported="true" kind="lib" path="lib/google-oauth-client-jetty-1.22.0.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/google-api-services-drive-v3-rev61-1.22.0.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/google-api-client-1.22.0.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/google-http-client-1.22.0.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/google-http-client-jackson2-1.22.0.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/google-oauth-client-1.22.0.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/google-oauth-client-java6-1.22.0.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.capra.ui.drive/.project b/org.eclipse.capra.ui.drive/.project
new file mode 100644
index 0000000..64d5982
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.capra.ui.drive</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.capra.ui.drive/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.capra.ui.drive/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/org.eclipse.capra.ui.drive/META-INF/MANIFEST.MF b/org.eclipse.capra.ui.drive/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ac286fe
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Sheets
+Bundle-SymbolicName: org.eclipse.capra.ui.drive;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.equinox.registry,
+ org.eclipse.capra.ui.office,
+ org.eclipse.ui,
+ com.fasterxml.jackson.core.jackson-core,
+ org.mortbay.jetty.server,
+ org.mortbay.jetty.util,
+ javax.servlet
+Bundle-ClassPath: .,
+ lib/google-api-client-1.22.0.jar,
+ lib/google-http-client-1.22.0.jar,
+ lib/google-http-client-jackson2-1.22.0.jar,
+ lib/google-oauth-client-java6-1.22.0.jar,
+ lib/google-oauth-client-1.22.0.jar,
+ lib/google-api-services-drive-v3-rev61-1.22.0.jar,
+ lib/google-oauth-client-jetty-1.22.0.jar
diff --git a/org.eclipse.capra.ui.drive/build.properties b/org.eclipse.capra.ui.drive/build.properties
new file mode 100644
index 0000000..ec0018c
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/build.properties
@@ -0,0 +1,12 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               plugin.xml,\
+               lib/google-oauth-client-java6-1.22.0.jar,\
+               lib/google-oauth-client-1.22.0.jar,\
+               lib/google-http-client-jackson2-1.22.0.jar,\
+               lib/google-http-client-1.22.0.jar,\
+               lib/google-api-client-1.22.0.jar,\
+               lib/google-api-services-drive-v3-rev61-1.22.0.jar,\
+               lib/google-oauth-client-jetty-1.22.0.jar
+source.. = src/
diff --git a/org.eclipse.capra.ui.drive/client_secret.json b/org.eclipse.capra.ui.drive/client_secret.json
new file mode 100644
index 0000000..13c9b57
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/client_secret.json
@@ -0,0 +1 @@
+{"installed":{"client_id":"62584412035-1n3is8571r3u2rte2heui056pjcu5m2t.apps.googleusercontent.com","project_id":"spartan-context-162213","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"OoT7kHga7GGiOxYiNFhIBdO7","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
\ No newline at end of file
diff --git a/org.eclipse.capra.ui.drive/icons/excel.png b/org.eclipse.capra.ui.drive/icons/excel.png
new file mode 100644
index 0000000..850d131
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/icons/excel.png
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/icons/selectionView.png b/org.eclipse.capra.ui.drive/icons/selectionView.png
new file mode 100644
index 0000000..42fdc5a
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/icons/selectionView.png
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/lib/google-api-client-1.22.0.jar b/org.eclipse.capra.ui.drive/lib/google-api-client-1.22.0.jar
new file mode 100644
index 0000000..b9c2b2d
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/lib/google-api-client-1.22.0.jar
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/lib/google-api-services-drive-v3-rev61-1.22.0.jar b/org.eclipse.capra.ui.drive/lib/google-api-services-drive-v3-rev61-1.22.0.jar
new file mode 100644
index 0000000..2d285d8
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/lib/google-api-services-drive-v3-rev61-1.22.0.jar
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/lib/google-http-client-1.22.0.jar b/org.eclipse.capra.ui.drive/lib/google-http-client-1.22.0.jar
new file mode 100644
index 0000000..a31a9b1
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/lib/google-http-client-1.22.0.jar
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/lib/google-http-client-jackson2-1.22.0.jar b/org.eclipse.capra.ui.drive/lib/google-http-client-jackson2-1.22.0.jar
new file mode 100644
index 0000000..64f0c15
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/lib/google-http-client-jackson2-1.22.0.jar
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/lib/google-oauth-client-1.22.0.jar b/org.eclipse.capra.ui.drive/lib/google-oauth-client-1.22.0.jar
new file mode 100644
index 0000000..93d284d
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/lib/google-oauth-client-1.22.0.jar
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/lib/google-oauth-client-java6-1.22.0.jar b/org.eclipse.capra.ui.drive/lib/google-oauth-client-java6-1.22.0.jar
new file mode 100644
index 0000000..956f263
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/lib/google-oauth-client-java6-1.22.0.jar
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/lib/google-oauth-client-jetty-1.22.0.jar b/org.eclipse.capra.ui.drive/lib/google-oauth-client-jetty-1.22.0.jar
new file mode 100644
index 0000000..25b5ac5
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/lib/google-oauth-client-jetty-1.22.0.jar
Binary files differ
diff --git a/org.eclipse.capra.ui.drive/plugin.xml b/org.eclipse.capra.ui.drive/plugin.xml
new file mode 100644
index 0000000..d9768db
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/plugin.xml
@@ -0,0 +1,55 @@
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <category
+            id="org.eclipse.capra.ui.views"
+			name="Capra Views">
+      </category>
+	  <view
+			category="org.eclipse.capra.ui.views"
+			class="org.eclipse.capra.ui.drive.CapraGoogleDriveView"
+			icon="icons/selectionView.png"
+			id="org.eclipse.capra.ui.drive.CapraGoogleDriveView"
+			name="Drive Selection View">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+			id="org.eclipse.capra.ui.drive.openInBrowser"
+            name="Open in browser">
+      </command>
+      <command
+            id="org.eclipse.capra.ui.drive.openInOfficeView"
+            name="Open in Capra Office view">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.capra.ui.drive.CapraGoogleDriveView?after=additions">
+         <command
+               commandId="org.eclipse.capra.ui.drive.openInBrowser"
+               label="Open in browser"
+               style="push">
+         </command>
+         <command
+               commandId="org.eclipse.capra.ui.drive.openInOfficeView"
+               label="Open in Capra Office view"
+               style="push">
+         </command>
+      </menuContribution>
+   </extension>
+   <extension
+         point="org.eclipse.ui.handlers">
+      <handler
+            class="org.eclipse.capra.ui.drive.OpenInBrowserHandler"
+            commandId="org.eclipse.capra.ui.drive.openInBrowser">
+      </handler>
+      <handler
+            class="org.eclipse.capra.ui.drive.OpenInOfficeViewHandler"
+            commandId="org.eclipse.capra.ui.drive.openInOfficeView">
+      </handler>
+   </extension>
+</plugin>
diff --git a/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/CapraGoogleDriveView.java b/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/CapraGoogleDriveView.java
new file mode 100644
index 0000000..d50eea4
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/CapraGoogleDriveView.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * 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
+ *
+ * Contributors:
+ * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.drive;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.capra.ui.office.views.OfficeView;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
+import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
+import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
+import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
+import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.jackson2.JacksonFactory;
+import com.google.api.client.util.IOUtils;
+import com.google.api.client.util.store.FileDataStoreFactory;
+import com.google.api.services.drive.Drive;
+import com.google.api.services.drive.DriveScopes;
+import com.google.api.services.drive.model.File;
+
+/**
+ * Provides a Capra perspective view for displaying the contents of Google
+ * sheets from Google Drive.
+ * 
+ * @author Dusan Kalanj
+ *
+ */
+public class CapraGoogleDriveView extends ViewPart {
+
+	/**
+	 * The actual view that contains the contents of the documents.
+	 */
+	private TableViewer viewer;
+
+	/**
+	 * Contains the File objects that are listed in the view.
+	 */
+	private List<File> selection = new ArrayList<File>();
+
+	/**
+	 * Application name for authentication purposes.
+	 */
+	private static final String APPLICATION_NAME = "CapraDrive";
+
+	/**
+	 * Directory to store user credentials for this application.
+	 */
+	private static final java.io.File DATA_STORE_DIR_DRIVE = new java.io.File(System.getProperty("user.home"),
+			".capra-drive-credentials" + java.io.File.separator + "drive.googleapis.capra-drive");
+
+	private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
+	private static FileDataStoreFactory DATA_STORE_FACTORY_DRIVE;
+	private static HttpTransport HTTP_TRANSPORT;
+	private static Drive driveService;
+
+	static {
+		try {
+			HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
+			DATA_STORE_FACTORY_DRIVE = new FileDataStoreFactory(DATA_STORE_DIR_DRIVE);
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+	}
+
+	private GoogleClientSecrets getClientSecrets() {
+		GoogleClientSecrets googleClientSecrets = null;
+		InputStream in = CapraGoogleDriveView.class.getResourceAsStream("/client_secret.json");
+		try {
+			googleClientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return googleClientSecrets;
+	}
+
+	/**
+	 * Creates an authorized Credential object.
+	 * 
+	 * @return an authorized Credential object.
+	 * @throws IOException
+	 */
+	private Credential authorizeDrive() throws IOException {
+		// Load client secrets.
+		GoogleClientSecrets clientSecrets = getClientSecrets();
+
+		// Build flow and trigger user authorization request.
+		GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
+				clientSecrets, Arrays.asList(DriveScopes.DRIVE)).setDataStoreFactory(DATA_STORE_FACTORY_DRIVE)
+						.setAccessType("offline").build();
+		Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
+		// Credentials saved to " + DATA_STORE_DIR_DRIVE.getAbsolutePath()
+
+		return credential;
+	}
+
+	/**
+	 * Build and return an authorized Drive client service.
+	 * 
+	 * @return an authorized Drive client service
+	 * @throws IOException
+	 */
+	private Drive getAuthorizedDriveService() throws IOException {
+		Credential credential = authorizeDrive();
+		return new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
+	}
+
+	/**
+	 * Fills the Capra Drive view with Google sheet files from the Drive
+	 * 
+	 * @param driveService
+	 *            authorized Drive client service
+	 */
+	private void fillSelection() {
+		try {
+			driveService = getAuthorizedDriveService();
+			List<File> files = driveService.files().list().setFields("nextPageToken, files(id, name, mimeType)")
+					.execute().getFiles();
+			if (files != null && files.size() > 0)
+				for (File file : files)
+					if (file.getMimeType().equals("application/vnd.google-apps.spreadsheet"))
+						selection.add(file);
+			viewer.refresh();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * The content provider class used by the view.
+	 */
+	class ViewContentProvider implements IStructuredContentProvider {
+
+		@Override
+		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+		}
+
+		@Override
+		public void dispose() {
+		}
+
+		@Override
+		public Object[] getElements(Object parent) {
+			return selection.toArray();
+		}
+	}
+
+	/**
+	 * The label provider class used by the view.
+	 */
+	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+		ImageDescriptor imgDesc = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.capra.ui.drive",
+				"icons/excel.png");
+		Image image = imgDesc.createImage();
+
+		@Override
+		public String getText(Object obj) {
+			if (obj instanceof File)
+				return ((File) obj).getName();
+			else
+				return obj.toString();
+		};
+
+		@Override
+		public String getColumnText(Object obj, int index) {
+			return getText(obj);
+		}
+
+		@Override
+		public Image getColumnImage(Object obj, int index) {
+			return getImage(obj);
+		}
+
+		@Override
+		public Image getImage(Object obj) {
+			return image;
+		}
+	}
+
+	@Override
+	public void createPartControl(Composite parent) {
+
+		viewer = new TableViewer(parent);
+		viewer.setContentProvider(new ViewContentProvider());
+		viewer.setLabelProvider(new ViewLabelProvider());
+		viewer.setInput(getViewSite());
+
+		getSite().setSelectionProvider(viewer);
+
+		viewer.addDoubleClickListener(new IDoubleClickListener() {
+
+			@Override
+			public void doubleClick(DoubleClickEvent event) {
+				IStructuredSelection selection = (IStructuredSelection) ((DoubleClickEvent) event).getSelection();
+
+				if (selection.getFirstElement() instanceof String)
+					fillSelection();
+				else {
+					File file = (File) selection.getFirstElement();
+					String spreadSheetId = file.getId();
+					if (!spreadSheetId.isEmpty())
+						displaySheetInOfficeView(spreadSheetId);
+				}
+			}
+		});
+
+		viewer.add("Double click to fetch sheets from Drive.");
+		hookContextMenu();
+	}
+
+	/**
+	 * Getter for the authorized drive service object.
+	 * 
+	 * @return authorized drive service
+	 */
+	public static Drive getDriveService() {
+		return driveService;
+	}
+
+	/**
+	 * Displays the sheet with the provided ID in the Capra Office view.
+	 * 
+	 * @param spreadSheetId
+	 *            the ID of the sheet
+	 */
+	public static void displaySheetInOfficeView(String spreadSheetId) {
+		try {
+			java.io.File tempFile = java.io.File.createTempFile("tmpFile", ".xlsx");
+			InputStream in = driveService.files()
+					.export(spreadSheetId, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+					.executeAsInputStream();
+			IOUtils.copy(in, new FileOutputStream(tempFile));
+			OfficeView.getOpenedView().parseExcelDocument(tempFile, spreadSheetId, null);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void hookContextMenu() {
+		MenuManager menuMgr = new MenuManager("#PopupMenu");
+		menuMgr.setRemoveAllWhenShown(true);
+		menuMgr.addMenuListener(new IMenuListener() {
+			public void menuAboutToShow(IMenuManager manager) {
+			}
+		});
+		Menu menu = menuMgr.createContextMenu(viewer.getControl());
+		viewer.getControl().setMenu(menu);
+		getSite().registerContextMenu(menuMgr, viewer);
+	}
+
+	@Override
+	public void setFocus() {
+		viewer.getControl().setFocus();
+	}
+}
diff --git a/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/OpenInBrowserHandler.java b/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/OpenInBrowserHandler.java
new file mode 100644
index 0000000..f618d2c
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/OpenInBrowserHandler.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * 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
+ *
+ * Contributors:
+ * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.drive;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+import com.google.api.services.drive.model.File;
+
+/**
+ * A handler for displaying the selected Google sheet in the default browser.
+ *
+ * @author Dusan Kalanj
+ *
+ */
+public class OpenInBrowserHandler extends AbstractHandler {
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+		IWorkbenchPage activePage = window.getActivePage();
+		ISelection selection = activePage.getSelection();
+		if (selection instanceof IStructuredSelection) {
+			File driveFile = (File) ((IStructuredSelection) selection).getFirstElement();
+			try {
+				Desktop.getDesktop().browse(new URI("https://docs.google.com/spreadsheets/d/" + driveFile.getId()));
+			} catch (IOException | URISyntaxException e) {
+				e.printStackTrace();
+			}
+		}
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/OpenInOfficeViewHandler.java b/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/OpenInOfficeViewHandler.java
new file mode 100644
index 0000000..a457376
--- /dev/null
+++ b/org.eclipse.capra.ui.drive/src/org/eclipse/capra/ui/drive/OpenInOfficeViewHandler.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * 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
+ *
+ * Contributors:
+ * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.drive;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+import com.google.api.services.drive.model.File;
+
+/**
+ * A handler for displaying the selected Google sheet in the Capra Office view.
+ *
+ * @author Dusan Kalanj
+ *
+ */
+public class OpenInOfficeViewHandler extends AbstractHandler {
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+		IWorkbenchPage activePage = window.getActivePage();
+		ISelection selection = activePage.getSelection();
+		if (selection instanceof IStructuredSelection) {
+			File driveFile = (File) ((IStructuredSelection) selection).getFirstElement();
+			CapraGoogleDriveView.displaySheetInOfficeView(driveFile.getId());
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.capra.ui.feature/.project b/org.eclipse.capra.ui.feature/.project
new file mode 100644
index 0000000..a5ea5d0
--- /dev/null
+++ b/org.eclipse.capra.ui.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.capra.ui.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.capra.ui.feature/build.properties b/org.eclipse.capra.ui.feature/build.properties
new file mode 100644
index 0000000..560c2d8
--- /dev/null
+++ b/org.eclipse.capra.ui.feature/build.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+# 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
+#  
+#   Contributors:
+#      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+###############################################################################
+bin.includes = feature.xml
diff --git a/org.eclipse.capra.ui.feature/feature.xml b/org.eclipse.capra.ui.feature/feature.xml
new file mode 100644
index 0000000..9c5bb3b
--- /dev/null
+++ b/org.eclipse.capra.ui.feature/feature.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.capra.ui.feature"
+      label="Capra UI Functionality"
+      version="0.7.0.qualifier"
+      provider-name="Capra Development Team"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+
+   <copyright>
+      Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <plugin
+         id="org.eclipse.capra.ui.notification"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.capra.documentation"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.capra.ui"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.capra.ui.feature/pom.xml b/org.eclipse.capra.ui.feature/pom.xml
new file mode 100644
index 0000000..3bdf010
--- /dev/null
+++ b/org.eclipse.capra.ui.feature/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+        <modelVersion>4.0.0</modelVersion>
+
+        <parent>
+                <relativePath>../pom.xml</relativePath>
+                <groupId>org.eclipse.capra</groupId>
+                <artifactId>parent</artifactId>
+                <version>0.7.0-SNAPSHOT</version>
+        </parent>
+
+        <artifactId>org.eclipse.capra.ui.feature</artifactId>
+        <packaging>eclipse-feature</packaging>
+
+</project>
diff --git a/org.eclipse.capra.ui.office/META-INF/MANIFEST.MF b/org.eclipse.capra.ui.office/META-INF/MANIFEST.MF
index fe5ef5d..890041e 100644
--- a/org.eclipse.capra.ui.office/META-INF/MANIFEST.MF
+++ b/org.eclipse.capra.ui.office/META-INF/MANIFEST.MF
@@ -20,7 +20,8 @@
  org.eclipse.core.runtime,
  org.eclipse.core.expressions
 Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.capra.ui.office.objects,
- org.eclipse.capra.ui.office.utils
+Export-Package: org.eclipse.capra.ui.office.model,
+ org.eclipse.capra.ui.office.utils,
+ org.eclipse.capra.ui.office.views
 Bundle-Activator: org.eclipse.capra.ui.office.Activator
 
diff --git a/org.eclipse.capra.ui.office/plugin.xml b/org.eclipse.capra.ui.office/plugin.xml
index a519c22..16e4f32 100644
--- a/org.eclipse.capra.ui.office/plugin.xml
+++ b/org.eclipse.capra.ui.office/plugin.xml
@@ -102,7 +102,7 @@
                   tooltip="Shows the details of the selected row">
                <visibleWhen>
      	          <iterate ifEmpty="false">
-                     <instanceof value="org.eclipse.capra.ui.office.objects.CapraOfficeObject"/>
+                     <instanceof value="org.eclipse.capra.ui.office.model.CapraOfficeObject"/>
                   </iterate>
                </visibleWhen>
             </command>
@@ -137,7 +137,7 @@
             id="org.eclipse.capra.ui.office.utils.OfficePropertyTester"
             namespace="org.eclipse.capra.ui.office.utils"
             properties="isViewPopulated, isExcelObject"
-            type="org.eclipse.capra.ui.office.objects.CapraOfficeObject">
+            type="org.eclipse.capra.ui.office.model.CapraOfficeObject">
       </propertyTester>
    </extension>
    <extension
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraExcelRow.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraExcelRow.java
similarity index 66%
rename from org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraExcelRow.java
rename to org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraExcelRow.java
index 6891c1f..2b64724 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraExcelRow.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraExcelRow.java
@@ -8,31 +8,31 @@
  * Contributors:
  * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
  *******************************************************************************/
-
-package org.eclipse.capra.ui.office.objects;
+package org.eclipse.capra.ui.office.model;
 
 import java.awt.Desktop;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.nio.file.NoSuchFileException;
 import java.util.Arrays;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.poi.hssf.OldExcelFormatException;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.util.CellReference;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.DataFormatter;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.eclipse.capra.ui.office.exceptions.CapraOfficeObjectNotFound;
 import org.eclipse.capra.ui.office.preferences.OfficePreferences;
+import org.eclipse.capra.ui.office.utils.CapraOfficeUtils;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
@@ -74,7 +74,9 @@
 
 	/**
 	 * The ID of the column that is used to extract the identifier of the row
-	 * (if value is "0", then line numbers are used as identifiers).
+	 * (if value is OfficePreferences.EXCEL_COLUMN_VALUE_DEFAULT, line numbers
+	 * are used as identifiers). The property is set according to the value in
+	 * the Capra preference page in Eclipse preferences.
 	 */
 	private String idColumn;
 
@@ -84,10 +86,11 @@
 	 * object that contains the row.
 	 * 
 	 * @param officeFile
-	 *            a File object representing the Office document
+	 *            a File object representing an Excel file.
 	 * @param row
-	 *            an Excel row, extracted from an Excel document
-	 * 
+	 *            an Excel row, extracted from the provided Excel file.
+	 * @param idColumn
+	 *            the excel column that is used to extract the ID of the row
 	 */
 	public CapraExcelRow(File officeFile, Row row, String idColumn) {
 		super();
@@ -97,8 +100,8 @@
 		StringBuilder rowBuilder = new StringBuilder();
 		rowBuilder.append("ID " + rowId + ": ");
 
+		// Gather the text from the whole Excel row into one StringBuilder
 		boolean firstCellSet = false;
-
 		for (int j = 1; j < row.getLastCellNum(); j++) {
 			Cell cell = row.getCell(j);
 			String cellValue = FORMATTER.formatCellValue(cell);
@@ -112,15 +115,18 @@
 			}
 		}
 
+		// Set data and uri fields if any data was extracted from the row. If no
+		// data was found, data and uri will be empty strings (as defined in the
+		// CapraOfficeObject - parent object).
 		if (firstCellSet) {
 			Pattern p = Pattern.compile(LINE_BREAKS_AND_CONTROL_REQ);
 			Matcher m = p.matcher(rowBuilder);
+			String rowData = (m.replaceAll(" ")).trim();
 
-			String rowContent = (m.replaceAll(" ")).trim();
 			String rowUriEnd = row.getSheet().getSheetName() + CapraOfficeObject.URI_DELIMITER + rowId;
-			String rowUri = CapraOfficeObject.createUri(officeFile, rowUriEnd);
+			String rowUri = createUri(officeFile.getAbsolutePath(), rowUriEnd);
 
-			this.setData(rowContent);
+			this.setData(rowData);
 			this.setUri(rowUri);
 		}
 	}
@@ -128,25 +134,35 @@
 	@Override
 	public void showOfficeObjectInNativeEnvironment() throws CapraOfficeObjectNotFound {
 
-		String fileType = Files.getFileExtension(getFile().getAbsolutePath());
-		String rowId = getRowIdFromObjectUri();
-		String sheetName = getSheetName();
-
-		Sheet sheet;
-
-		try (FileInputStream in = new FileInputStream(getFile())) {
-			if (fileType.equals(CapraOfficeObject.XLSX)) {
-				sheet = new XSSFWorkbook(in).getSheet(sheetName);
-			} else {
-				sheet = new HSSFWorkbook(in).getSheet(sheetName);
-			}
-		} catch (IOException e) {
+		// Get Excel file from the CapraExcelRow object.
+		File officeFile;
+		try {
+			officeFile = getFile();
+		} catch (NoSuchFileException e) {
 			e.printStackTrace();
 			return;
 		}
 
-		int rowIndex = NO_ROW_INDEX;
+		// Extract relevant info from the object.
+		String fileType = Files.getFileExtension(officeFile.getAbsolutePath());
+		String rowId = getRowIdFromObjectUri();
+		String sheetName = getSheetName();
+
+		// Get the object's sheet
+		Sheet sheet = null;
+		try {
+			Workbook workBook = CapraOfficeUtils.getExcelWorkbook(officeFile);
+			sheet = CapraOfficeUtils.getSheet(workBook, sheetName);
+		} catch (OldExcelFormatException | IOException e) {
+			e.printStackTrace();
+			return;
+		}
+
+		// Find the Excel row that the CapraExcelRow object points to.
+		// lastCellReference is used to store the column ID (such as B or C2) of
+		// the last cell that contains any data in the row.
 		String lastCellReference = NO_LAST_CELL_REFERENCE;
+		int rowIndex = NO_ROW_INDEX;
 		for (int i = 0; i <= sheet.getLastRowNum(); i++) {
 			Row row = sheet.getRow(i);
 			if (row != null) {
@@ -162,7 +178,13 @@
 		if (rowIndex == NO_ROW_INDEX || lastCellReference == NO_LAST_CELL_REFERENCE)
 			throw new CapraOfficeObjectNotFound(getRowIdFromObjectUri());
 
+		// firstDisplayedRowIndex is used to set the first visible row in the
+		// view that opens to the user - for example if the row in question is
+		// at index 50, the solution will open the Excel file at row 48.
 		int firstDisplayedRowIndex = (rowIndex - 2 > 0) ? rowIndex - 2 : 1;
+
+		// The next block of code highlights the selected row in the file by
+		// setting some XML values in the excel file.
 		if (fileType.equals(CapraOfficeObject.XLSX)) {
 			XSSFSheet xssfSheet = XSSFSheet.class.cast(sheet);
 			int sheetIndex = xssfSheet.getWorkbook().getSheetIndex(xssfSheet);
@@ -183,18 +205,19 @@
 
 			HSSFRow row = hssfSheet.getRow(rowIndex);
 			HSSFCell cell = row.getCell(0);
-			cell.setAsActiveCell(); // TODO doesn't work - bug (but xls doesn't
-									// necessarily even have to be supported)
+			cell.setAsActiveCell(); // TODO doesn't work - bug in library?
 		}
 
+		// Overwrites the existing Excel file with the new XML values.
 		try (FileOutputStream out = new FileOutputStream(getFile())) {
 			sheet.getWorkbook().write(out);
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 
-		// TODO If Excel is already open, then this doesn't trigger. Is there a
-		// way to refresh the application?
+		// Opens the Excel file with the Excel application.
+		// TODO If Excel is already open, this doesn't trigger. Is there a way
+		// to refresh the (Excel) application?
 		try {
 			Desktop.getDesktop().open(getFile());
 		} catch (IOException e) {
@@ -204,7 +227,9 @@
 	}
 
 	/**
-	 * Extracts the name of the sheet which the object is associated with.
+	 * Extracts the name of the sheet (from the URI of the object) which the
+	 * object is associated with. The URI of the object should always be in the
+	 * format fileId + DELIMITER + sheetName + DELIMITER + rowId.
 	 * 
 	 * @return name of the sheet
 	 */
@@ -214,13 +239,31 @@
 		return itemId.substring(0, lastIndexOfDelimiter);
 	}
 
+	/**
+	 * Extracts the ID of the row from the URI of the object. The URI of the
+	 * object should always be in the format fileId + DELIMITER + sheetName +
+	 * DELIMITER + rowId.
+	 * 
+	 * @return ID of the row
+	 */
 	private String getRowIdFromObjectUri() {
 		String itemId = getId();
 		int lastIndexOfDelimiter = itemId.indexOf(CapraOfficeObject.URI_DELIMITER);
 		return itemId.substring(lastIndexOfDelimiter + CapraOfficeObject.URI_DELIMITER.length());
 	}
 
-	private String getRowIdFromExcelRow(Row row) {
+	/**
+	 * Extracts the ID of the Excel row (not CapraExcelRow!) based on the
+	 * idColumn value. If the value of idColumn is EXCEL_COLUMN_VALUE_DEFAULT,
+	 * then rowID is the same as row number, otherwise a specific column
+	 * (defined by idColumn property - such as A1) is used to extract the data
+	 * that will serve as the ID of the row.
+	 * 
+	 * @param row
+	 *            the row to identify
+	 * @return the ID of the row
+	 */
+	protected String getRowIdFromExcelRow(Row row) {
 		String rowId = "";
 		if (idColumn.equals(OfficePreferences.EXCEL_COLUMN_VALUE_DEFAULT))
 			rowId = Integer.toString(row.getRowNum() + 1);
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraGoogleSheetsRow.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraGoogleSheetsRow.java
new file mode 100644
index 0000000..7d19c28
--- /dev/null
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraGoogleSheetsRow.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * 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
+ *
+ * Contributors:
+ * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.ui.office.model;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.poi.ss.usermodel.Row;
+import org.eclipse.capra.ui.office.exceptions.CapraOfficeObjectNotFound;
+
+/**
+ * This class extends the CapraExcelRow and provides an object to describe a
+ * single MS Excel row, the file of which is only stored temporarily as it was
+ * obtained directly from Google drive.
+ * 
+ * @author Dusan Kalanj
+ *
+ */
+public class CapraGoogleSheetsRow extends CapraExcelRow {
+
+	/**
+	 * Extracts the data from the Excel row the same way as its parent
+	 * (CapraExcelRow), but sets a different URI. Because the excel file is only
+	 * stored temporarily, it uses a Google drive fileId instead of a file path
+	 * in the first part of the uri (the format of the uri is fileId + DELIMITER
+	 * + sheetId + DELIMITER + rowId).
+	 * 
+	 * @param officeFile
+	 *            the (temporarily stored) excel file that holds the row
+	 * @param row
+	 *            the row from which to extract the data
+	 * @param idColumn
+	 *            the column to be used to extract the ID of the row
+	 * @param googleDriveFileId
+	 *            the Google drive file ID of the file (found in the URL when
+	 *            opening the file in Google Drive)
+	 */
+	public CapraGoogleSheetsRow(File officeFile, Row row, String idColumn, String googleDriveFileId) {
+		super(officeFile, row, idColumn);
+		String rowId = getRowIdFromExcelRow(row);
+		String objectId = row.getSheet().getSheetName() + CapraOfficeObject.URI_DELIMITER + rowId;
+		String uri = createUri(googleDriveFileId, objectId);
+		this.setUri(uri);
+	}
+
+	@Override
+	public void showOfficeObjectInNativeEnvironment() throws CapraOfficeObjectNotFound {
+		try {
+			Desktop.getDesktop().browse(new URI("https://docs.google.com/spreadsheets/d/" + this.getFileId()));
+		} catch (IOException | URISyntaxException e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraOfficeObject.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraOfficeObject.java
similarity index 73%
rename from org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraOfficeObject.java
rename to org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraOfficeObject.java
index bf16450..ebe921b 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraOfficeObject.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraOfficeObject.java
@@ -9,11 +9,12 @@
  * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
  *******************************************************************************/
 
-package org.eclipse.capra.ui.office.objects;
+package org.eclipse.capra.ui.office.model;
 
 import java.awt.Desktop;
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.NoSuchFileException;
 
 import org.eclipse.capra.ui.office.exceptions.CapraOfficeObjectNotFound;
 
@@ -93,7 +94,8 @@
 	}
 
 	/**
-	 * Returns the ID of the OfficeObject.
+	 * Returns the ID of the OfficeObject from its URI. The format of the URI
+	 * should always be fileId + DELIMITER + objectId.
 	 */
 	public String getId() {
 		int firstDelimiterIndex = uri.indexOf(URI_DELIMITER);
@@ -101,51 +103,55 @@
 	}
 
 	/**
-	 * Returns the File reference of the file that contains the OfficeObject
+	 * Returns the File reference of the file that contains the OfficeObject.
+	 * The format of the URI should always be fileId + DELIMITER + objectId.
 	 */
-	public File getFile() {
+	public File getFile() throws NoSuchFileException {
+		String fileId = getFileId();
+		File officeFile = new File(fileId);
+		if (officeFile.exists())
+			return officeFile;
+		else
+			throw new NoSuchFileException(fileId);
+	}
+
+	/**
+	 * Returns the ID of the file - the first part of the URI. The format of the
+	 * URI should always be fileId + DELIMITER + objectId.
+	 */
+	public String getFileId() {
 		int firstDelimiterIndex = uri.indexOf(URI_DELIMITER);
-		return new File(uri.substring(0, firstDelimiterIndex));
+		return uri.substring(0, firstDelimiterIndex);
 	}
 
 	/**
-	 * Generates a readable name for the purpose of supplying it to
-	 * createArtifact method in the OfficeHandler.
-	 * 
-	 * @return a readable name of the OfficeObject
-	 */
-	public String getName() {
-		return getFile().getName() + URI_DELIMITER + getId();
-	}
-
-	/**
-	 * Extracts the ID of the object from uri of the OfficeObject.
+	 * Extracts the objectId from the provided CapraOfficeObject uri. The format
+	 * of the URI should always be fileId + DELIMITER + objectId.
 	 * 
 	 * @param uri
 	 *            uri of the object
 	 * @return ID of the object
 	 */
-	public static String getIdFromUri(String uri) {
+	public static String getObjectIdFromUri(String uri) {
 		int firstDelimiterIndex = uri.indexOf(URI_DELIMITER);
 		return uri.substring(firstDelimiterIndex + URI_DELIMITER.length());
 	}
 
 	/**
-	 * Extracts the file-path from uri of the OfficeObject.
+	 * Extracts the fileId from the provided CapraOfficeObject uri. The format
+	 * of the URI should always be fileId + DELIMITER + objectId.
 	 * 
 	 * @param uri
 	 *            uri of the object
 	 * @return file-path of the file that contains the object
 	 */
-	public static String getFilePathFromUri(String uri) {
+	public static String getFileIdFromUri(String uri) {
 		int delimiterIndex = uri.indexOf(URI_DELIMITER);
 		return uri.substring(0, delimiterIndex);
 	}
 
 	/**
-	 * Opens the OfficeObject in its native environment. If object is of class
-	 * OfficeObject (parent object), then the method does nothing but return an
-	 * error string
+	 * Opens the OfficeObject in its native environment.
 	 * 
 	 * @return an OK or ERROR message
 	 * @throws CapraOfficeObjectNotFound
@@ -160,24 +166,21 @@
 	}
 
 	/**
-	 * Generates a uri given the file-path of the file that contains the object
-	 * and an objectID
+	 * Generates a uri given the fileId of the file that contains the object and
+	 * an objectId.
 	 * 
-	 * @param officeFile
-	 *            File object containing the absolute file-path of the file that
-	 *            contains the object
+	 * @param fileId
+	 *            ID of the file that contains the object with objectId
 	 * @param objectID
-	 *            ID of the object - usually its index in the file
-	 *
+	 *            ID of the object
 	 * @return a uri of the object in the form of filePath/objectID
 	 */
-	public static String createUri(File officeFile, Object objectId) {
-		return officeFile.getAbsolutePath() + URI_DELIMITER + objectId;
+	public static String createUri(String fileId, String objectId) {
+		return fileId + URI_DELIMITER + objectId;
 	}
 
 	/**
-	 * Returns the description of the OfficeObject. If the description is too
-	 * long, it limits the return value.
+	 * Returns the data of the OfficeObject.
 	 */
 	@Override
 	public String toString() {
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraWordRequirement.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraWordRequirement.java
similarity index 84%
rename from org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraWordRequirement.java
rename to org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraWordRequirement.java
index 0c46b6f..51cf6ee 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraWordRequirement.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/model/CapraWordRequirement.java
@@ -9,20 +9,16 @@
  * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
  *******************************************************************************/
 
-package org.eclipse.capra.ui.office.objects;
+package org.eclipse.capra.ui.office.model;
 
 import java.io.File;
-import java.io.StringReader;
 import java.util.Arrays;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.eclipse.capra.ui.office.utils.CapraOfficeUtils;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
 
 /**
  * This class extends the CapraOfficeObject and provides an object to describe a
@@ -75,12 +71,14 @@
 		CTP pCtp = paragraph.getCTP();
 		Document doc;
 		try {
-			doc = loadXMLFromString(pCtp.toString());
+			doc = CapraOfficeUtils.createDOMDocument(pCtp.toString());
 		} catch (Exception e) {
 			e.printStackTrace();
 			return;
 		}
 
+		// Get all nodes from the paragraph (there should be just one node if
+		// the TODO bellow isn't implemented)
 		NodeList nodeList = doc.getElementsByTagName(FIELD_TAG);
 		if (nodeList.getLength() > 0) {
 			// TODO Use a for loop if the solution needs to parse multiple
@@ -88,6 +86,7 @@
 			// paragraph.getText() should be replaced with something from the
 			// org.w3c.dom.Document class.
 			String[] parts = nodeList.item(0).getTextContent().split(WORD_FIELD_SPLIT_DELIMITERS);
+			// Extract text from the paragraph and the ID of the requirement.
 			if (Arrays.asList(parts).contains(fieldName) && parts.length > 2) {
 				rText = paragraph.getText();
 				rId = parts[2].trim();
@@ -95,19 +94,13 @@
 		}
 
 		rText = rText.replaceAll(LINE_BREAKS_AND_CONTROL_REGEX, " ").trim();
+		// Set the data and uri properties of the CapraOfficeObject
 		if (!rText.isEmpty()) {
 			rText = "ID " + rId + ": " + rText;
-			String pUri = CapraOfficeObject.createUri(officeFile, rId);
+			String pUri = createUri(officeFile.getAbsolutePath(), rId);
 
 			this.setData(rText);
 			this.setUri(pUri);
 		}
 	}
-
-	private Document loadXMLFromString(String xml) throws Exception {
-		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-		DocumentBuilder builder = factory.newDocumentBuilder();
-		InputSource is = new InputSource(new StringReader(xml));
-		return builder.parse(is);
-	}
 }
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/preferences/OfficePreferences.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/preferences/OfficePreferences.java
index 76df8bd..bdf964e 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/preferences/OfficePreferences.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/preferences/OfficePreferences.java
@@ -79,6 +79,17 @@
 	private Text excel_customIdColumnName;
 	private Text word_fieldName;
 
+	/**
+	 * Creates a swt widget that takes the numColumns of grid space inside the
+	 * parent.
+	 * 
+	 * @param parent
+	 *            the element that will hold the widget
+	 * @param numColumns
+	 *            the number of columns that the widget will take inside the
+	 *            grid of the parent.
+	 * @return the created widget
+	 */
 	private Composite createComposite(Composite parent, int numColumns) {
 		Composite composite = new Composite(parent, SWT.NULL);
 
@@ -99,6 +110,9 @@
 		setPreferenceStore(Activator.getDefault().getPreferenceStore());
 	}
 
+	/**
+	 * Saves the input values on click-apply or click-ok
+	 */
 	private void storeValues() {
 		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
 
@@ -122,6 +136,10 @@
 		store.setValue(WORD_FIELD_NAME, word_fieldName.getText());
 	}
 
+	/**
+	 * Fills the text fields and radio buttons with stored values when the
+	 * preference page is opened.
+	 */
 	private void initializeValues() {
 		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
 
@@ -139,6 +157,9 @@
 		word_fieldName.setText(store.getString(WORD_FIELD_NAME));
 	}
 
+	/**
+	 * Sets the default values if the user clicks on restore defaults option.
+	 */
 	private void initializeDefaults() {
 		excel_rowIdIsRowNumber.setSelection(EXCEL_COLUMN_RADIO_ID_IS_LINE_NUMBER);
 		excel_rowIdIsCustomColumn.setSelection(!EXCEL_COLUMN_RADIO_ID_IS_LINE_NUMBER);
@@ -203,6 +224,18 @@
 		return new Composite(parent, SWT.NULL);
 	}
 
+	/**
+	 * Creates a label widget that takes the width of numOfColumns grid cells
+	 * inside a parent.
+	 * 
+	 * @param parent
+	 *            the element that will hold the label.
+	 * @param text
+	 *            the text of the label.
+	 * @param numOfColumns
+	 *            the width (in grid cells) of the label.
+	 * @return newly created Label object
+	 */
 	private Label createLabel(Composite parent, String text, int numOfColumns) {
 		Label label = new Label(parent, SWT.LEFT);
 		label.setText(text);
@@ -213,6 +246,18 @@
 		return label;
 	}
 
+	/**
+	 * Creates a Text widget that takes the width of numOfColumns grid cells
+	 * inside a parent.
+	 * 
+	 * @param parent
+	 *            the element that will hold the label.
+	 * @param numOfColumns
+	 *            the width (in grid cells) of the widget.
+	 * @param minimumWidth
+	 *            the minimum width of the Text widget.
+	 * @return the newly created Text widget.
+	 */
 	private Text createTextField(Composite parent, int numOfColumns, int minimumWidth) {
 		Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
 		GridData data = new GridData();
@@ -226,6 +271,18 @@
 		return text;
 	}
 
+	/**
+	 * Creates a Button widget that takes the width of numOfColumns grid cells
+	 * inside a parent.
+	 * 
+	 * @param parent
+	 *            the element that will hold the label.
+	 * @param label
+	 *            the text of the widget.
+	 * @param numOfColumns
+	 *            the width (in grid cells) of the widget.
+	 * @return the newly created Button widget.
+	 */
 	private Button createRadioButton(Composite parent, String label, int numOfColumns) {
 		Button button = new Button(parent, SWT.RADIO | SWT.LEFT);
 		button.setText(label);
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/CapraOfficeUtils.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/CapraOfficeUtils.java
new file mode 100644
index 0000000..a74dfbc
--- /dev/null
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/CapraOfficeUtils.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * 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
+ *
+ * Contributors:
+ * 	   Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+package org.eclipse.capra.ui.office.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.poi.hssf.OldExcelFormatException;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.xmlbeans.SchemaTypeLoaderException;
+import org.eclipse.capra.ui.office.model.CapraOfficeObject;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+import com.google.common.base.Strings;
+import com.google.common.io.Files;
+
+/**
+ * This class contains convenient static methods that support the Capra Office
+ * plugin.
+ * 
+ * @author Dusan Kalanj
+ *
+ */
+public class CapraOfficeUtils {
+
+	/**
+	 * generates a HashMap that contains sheet names and info about their
+	 * emptiness:
+	 * <ul>
+	 * <li>keySet (String) - names of all the sheets, contained in the selected
+	 * workbook</li>
+	 * <li>valueSet (Boolean) - information about whether sheets are empty or
+	 * not</li>
+	 * </ul>
+	 * 
+	 * @param workBook
+	 *            an Excel Workbook object
+	 * @return a HashMap that contains the names (String) of all the sheets,
+	 *         contained in the selected workbook and information about whether
+	 *         they are empty or not (Boolean).
+	 */
+	public static HashMap<String, Boolean> getSheetsEmptinessInfo(Workbook workBook) {
+		HashMap<String, Boolean> isSheetEmptyMap = new HashMap<String, Boolean>();
+		for (int i = 0; i < workBook.getNumberOfSheets(); i++) {
+			Sheet s = workBook.getSheetAt(i);
+			isSheetEmptyMap.put(s.getSheetName(), s.getLastRowNum() < 1);
+		}
+		return isSheetEmptyMap;
+	}
+
+	/**
+	 * Gets the sheet with the provided sheetName from inside the provided Excel
+	 * Workbook.
+	 * 
+	 * @param workBook
+	 *            an Excel Workbook object
+	 * @param sheetName
+	 *            the name of the sheet
+	 * @return the sheet with the provided sheetName from the provided workBook
+	 * @throws NullPointerException
+	 */
+	public static Sheet getSheet(Workbook workBook, String sheetName) throws NullPointerException {
+		if (Strings.isNullOrEmpty(sheetName)) {
+			// This try block is necessary as there is a bug in the
+			// Workbook.getActiveSheetIndex() and Workbook.getFirstVisibleTab()
+			// methods; they throw a NullPointerException whenever the
+			// woorkbook doesn't hold information about which sheet is active
+			// and/or visible (maybe it occurs when the file is auto-generated).
+			int activeSheetIndex;
+			try {
+				activeSheetIndex = workBook.getActiveSheetIndex();
+			} catch (NullPointerException e1) {
+				try {
+					activeSheetIndex = workBook.getFirstVisibleTab();
+				} catch (NullPointerException e2) {
+					activeSheetIndex = 0;
+				}
+			}
+
+			// Should be without the try block, but the library contains a bug.
+			try {
+				sheetName = workBook.getSheetName(activeSheetIndex);
+			} catch (NullPointerException e) {
+				throw new NullPointerException();
+			}
+		}
+
+		return workBook.getSheet(sheetName);
+	}
+
+	/**
+	 * Gets the Excel Workbook from the provided Excel file.
+	 * 
+	 * @param excelFile
+	 *            a MS Excel file.
+	 * @return an Excel Workbook object
+	 * @throws OldExcelFormatException
+	 * @throws IOException
+	 */
+	public static Workbook getExcelWorkbook(File excelFile) throws OldExcelFormatException, IOException {
+		String fileType = Files.getFileExtension(excelFile.getAbsolutePath());
+		Workbook workBook;
+
+		if (fileType.equals(CapraOfficeObject.XLSX))
+			workBook = new XSSFWorkbook(new FileInputStream(excelFile));
+		else
+			workBook = new HSSFWorkbook(new FileInputStream(excelFile));
+
+		return workBook;
+	}
+
+	/**
+	 * Gets a list of paragraph objects that are contained in the provided MS
+	 * Word file.
+	 * 
+	 * @param wordFile
+	 *            a MS Word file
+	 * @return a list of XWPFParagraph objects that describe the paragraphs
+	 *         contained by the provided MS Word file.
+	 * @throws SchemaTypeLoaderException
+	 * @throws IOException
+	 */
+	public static List<XWPFParagraph> getWordParagraphs(File wordFile) throws SchemaTypeLoaderException, IOException {
+		FileInputStream fs = new FileInputStream(wordFile);
+		XWPFDocument xwpfDoc = new XWPFDocument(fs);
+		return xwpfDoc.getParagraphs();
+	}
+
+	/**
+	 * Creates a DOM document from the provided xml String.
+	 * 
+	 * @param xml
+	 *            a valid XML String
+	 * @return DOM document that describes the XML String
+	 * @throws Exception
+	 */
+	public static Document createDOMDocument(String xml) throws Exception {
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		DocumentBuilder builder = factory.newDocumentBuilder();
+		InputSource is = new InputSource(new StringReader(xml));
+		return builder.parse(is);
+	}
+
+}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficePropertyTester.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficePropertyTester.java
index 9b471fc..cf93e7b 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficePropertyTester.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficePropertyTester.java
@@ -11,7 +11,7 @@
 
 package org.eclipse.capra.ui.office.utils;
 
-import org.eclipse.capra.ui.office.objects.CapraExcelRow;
+import org.eclipse.capra.ui.office.model.CapraExcelRow;
 import org.eclipse.core.expressions.PropertyTester;
 
 /**
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeSourceProvider.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeSourceProvider.java
index 05911dc..a30a702 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeSourceProvider.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeSourceProvider.java
@@ -14,7 +14,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.eclipse.capra.ui.office.objects.CapraOfficeObject;
+import org.eclipse.capra.ui.office.model.CapraOfficeObject;
 import org.eclipse.ui.AbstractSourceProvider;
 import org.eclipse.ui.ISources;
 
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java
index e87911c..72b97eb 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java
@@ -18,7 +18,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 
-import org.eclipse.capra.ui.office.objects.CapraOfficeObject;
+import org.eclipse.capra.ui.office.model.CapraOfficeObject;
 import org.eclipse.swt.dnd.ByteArrayTransfer;
 import org.eclipse.swt.dnd.DND;
 import org.eclipse.swt.dnd.TransferData;
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java
index ded9e9b..95a6567 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java
@@ -13,7 +13,6 @@
 
 import java.awt.Desktop;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -22,21 +21,20 @@
 import java.util.List;
 
 import org.apache.poi.hssf.OldExcelFormatException;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
 import org.apache.xmlbeans.SchemaTypeLoaderException;
 import org.eclipse.capra.ui.office.Activator;
 import org.eclipse.capra.ui.office.exceptions.CapraOfficeFileNotSupportedException;
 import org.eclipse.capra.ui.office.exceptions.CapraOfficeObjectNotFound;
-import org.eclipse.capra.ui.office.objects.CapraExcelRow;
-import org.eclipse.capra.ui.office.objects.CapraOfficeObject;
-import org.eclipse.capra.ui.office.objects.CapraWordRequirement;
+import org.eclipse.capra.ui.office.model.CapraExcelRow;
+import org.eclipse.capra.ui.office.model.CapraGoogleSheetsRow;
+import org.eclipse.capra.ui.office.model.CapraOfficeObject;
+import org.eclipse.capra.ui.office.model.CapraWordRequirement;
 import org.eclipse.capra.ui.office.preferences.OfficePreferences;
+import org.eclipse.capra.ui.office.utils.CapraOfficeUtils;
 import org.eclipse.capra.ui.office.utils.OfficeSourceProvider;
 import org.eclipse.capra.ui.office.utils.OfficeTransferType;
 import org.eclipse.core.commands.ExecutionEvent;
@@ -78,7 +76,6 @@
 import org.eclipse.ui.part.ViewPart;
 import org.eclipse.ui.services.ISourceProviderService;
 
-import com.google.common.base.Strings;
 import com.google.common.io.Files;
 
 /**
@@ -118,8 +115,8 @@
 	private List<CapraOfficeObject> selection = new ArrayList<CapraOfficeObject>();
 
 	/**
-	 * The names (<String>) of all the sheets, contained in the selected
-	 * workbook and information about whether they are empty or not (<Boolean>).
+	 * The names (String) of all the sheets, contained in the selected workbook
+	 * and information about whether they are empty or not (Boolean).
 	 */
 	private HashMap<String, Boolean> isSheetEmptyMap;
 
@@ -129,6 +126,17 @@
 	private String selectedSheetName;
 
 	/**
+	 * The file that is currently displayed in the view.
+	 */
+	private File selectedFile;
+
+	/**
+	 * The ID of the file that is currently displayed in the view (non-null only
+	 * if acquired from Google Drive).
+	 */
+	private String selectedFileId;
+
+	/**
 	 * Instance of OfficeSourceProvider (used for hiding context menu options)
 	 */
 	private OfficeSourceProvider provider = (OfficeSourceProvider) ((ISourceProviderService) PlatformUI.getWorkbench()
@@ -195,7 +203,11 @@
 		@Override
 		public boolean performDrop(Object data) {
 			try {
-				dropToSelection(data);
+				if (data instanceof String[]) {
+					File file = new File(((String[]) data)[0]);
+					if (file != null && file.exists())
+						parseGenericFile(file);
+				}
 			} catch (CapraOfficeFileNotSupportedException e) {
 				e.printStackTrace();
 				showErrorMessage(ERROR_TITLE, e.getMessage(), null);
@@ -229,9 +241,8 @@
 				TableItem[] items = viewer.getTable().getSelection();
 				ArrayList<CapraOfficeObject> officeObjects = new ArrayList<CapraOfficeObject>();
 
-				for (int i = 0; i < items.length; i++) {
+				for (int i = 0; i < items.length; i++)
 					officeObjects.add((CapraOfficeObject) items[i].getData());
-				}
 
 				event.data = officeObjects;
 			}
@@ -270,29 +281,20 @@
 	}
 
 	/**
-	 * A method that is called when the user drags a file into the OfficeView.
-	 * Its main task is to parse the dragged file and display its contents in
-	 * the OfficeView. It only parses the file if it is of type xlsx, xls, or
-	 * docx.
+	 * A method that is called when the user drags file (word or excel) into the
+	 * OfficeView. Its main task is to parse the dragged file and display its
+	 * contents in the OfficeView. It only parses the file if it is of type
+	 * xlsx, xls, or docx.
 	 *
 	 * @param data
 	 *            the object that was dragged into the view
 	 * @throws CapraOfficeFileNotSupportedException
 	 */
-	private void dropToSelection(Object data) throws CapraOfficeFileNotSupportedException {
-
-		File file = null;
-
-		if (data instanceof String[])
-			file = new File(((String[]) data)[0]);
-
-		if (file == null)
-			return;
-
+	private void parseGenericFile(File file) throws CapraOfficeFileNotSupportedException {
 		String fileExtension = Files.getFileExtension(file.getName());
 
 		if (fileExtension.equals(CapraOfficeObject.XLSX) || fileExtension.equals(CapraOfficeObject.XLS))
-			parseExcelDocument(file, null);
+			parseExcelDocument(file, null, null);
 		else if (fileExtension.equals(CapraOfficeObject.DOCX))
 			parseWordDocument(file);
 		else
@@ -305,20 +307,24 @@
 	 * @param officeFile
 	 *            the File object pointing to the Excel document that was
 	 *            dragged into the view
+	 * @param googleDriveFileId
+	 *            the id of the file from Google drive (shown in the URL when a
+	 *            user opens a file inside Google Drive). If provided it will be
+	 *            used when creating the URI of the objects, otherwise (if null)
+	 *            the path of the containing file will be used instead. That
+	 *            also means that, if googleDriveFileId is provided, the Objects
+	 *            in the OfficeView will be of type CapraGoogleSheetsRow,
+	 *            otherwise of type CapraExcelRow.
 	 * @param sheetName
 	 *            the name of the sheet that should be displayed in the Office
 	 *            view. If null, the currently active sheet will be displayed.
 	 */
-	private void parseExcelDocument(File officeFile, String sheetName) {
+	public void parseExcelDocument(File officeFile, String googleDriveFileId, String sheetName) {
 
-		String fileType = Files.getFileExtension(officeFile.getAbsolutePath());
+		// Get Excel Workbook
 		Workbook workBook;
-
 		try {
-			if (fileType.equals(CapraOfficeObject.XLSX))
-				workBook = new XSSFWorkbook(new FileInputStream(officeFile));
-			else
-				workBook = new HSSFWorkbook(new FileInputStream(officeFile));
+			workBook = CapraOfficeUtils.getExcelWorkbook(officeFile);
 		} catch (OldExcelFormatException e) {
 			showErrorMessage(ERROR_TITLE, e.getMessage(), null);
 			return;
@@ -327,85 +333,55 @@
 			return;
 		}
 
-		if (Strings.isNullOrEmpty(sheetName)) {
-			// This try block is necessary as there is a bug in the
-			// Workbook.getActiveSheetIndex() and Workbook.getFirstVisibleTab()
-			// methods; they throw a NullPointerException whenever the
-			// woorkbook doesn't hold information about which sheet is active
-			// and/or visible (maybe it occurs when the file is auto-generated).
-			int activeSheetIndex;
-			try {
-				activeSheetIndex = workBook.getActiveSheetIndex();
-			} catch (NullPointerException e1) {
-				e1.printStackTrace();
-				try {
-					activeSheetIndex = workBook.getFirstVisibleTab();
-				} catch (NullPointerException e2) {
-					e2.printStackTrace();
-					activeSheetIndex = 0;
-				}
-			}
-
-			try {
-				sheetName = workBook.getSheetName(activeSheetIndex);
-			} catch (NullPointerException e) {
-				e.printStackTrace();
-				String hyperlinkMessage = "It looks like the file doesn't contain any sheets. Please report the issue to our <a href=\""
-						+ BUGZILLA_OFFICE_URL + "\"> Bugzilla project page </a> and we will do our best to resolve it.";
-				showErrorMessage(ERROR_TITLE, hyperlinkMessage, BUGZILLA_OFFICE_URL);
-				return;
-			}
-		}
-
-		Sheet sheetToDisplay = workBook.getSheet(sheetName);
-		// In theory, this could only happen if someone uses the selectSheet
-		// (public) method and provides a non-valid sheetName. The method is
-		// currently only used for changing the displayed sheet through the
-		// tool-bar menu, where all the names are valid.
-		// TODO The best way to tackle this would probably be to introduce a new
-		// exception (CapraOfficeSheetNotFoundException?), but to do that, a bit
-		// of reordering and partitioning of the methods would be required -
-		// ideally, the selectSheet (public) method would throw the exception,
-		// not this one.
-		if (sheetToDisplay == null) {
-			String hyperlinkMessage = "It appears that there is something wrong with the file. Please report the issue to our <a href=\""
+		// Get Excel sheet with provided sheetName from provided workBook
+		Sheet sheet = CapraOfficeUtils.getSheet(workBook, sheetName);
+		if (sheet == null) {
+			// In theory, this could only happen if someone uses the selectSheet
+			// (public) method and provides a non-valid sheetName. The method is
+			// currently only used for changing the displayed sheet through the
+			// tool-bar menu, where all the names are valid. TODO The best way
+			// to tackle this would probably be to introduce a new exception
+			// (CapraOfficeSheetNotFoundException?), but to do that, a bit of
+			// reordering and partitioning of the methods would be required -
+			// ideally, the selectSheet (public) method would throw the
+			// exception, not this one.
+			String hyperlinkMessage = "It appears that the file doesn't contain any sheets. If that is not true, please report the issue to our <a href=\""
 					+ BUGZILLA_OFFICE_URL + "\"> Bugzilla project page </a> and we will do our best to resolve it.";
 			showErrorMessage(ERROR_TITLE, hyperlinkMessage, BUGZILLA_OFFICE_URL);
 			return;
 		}
 
+		// Check if the whole workbook (all of the sheets) is empty.
+		HashMap<String, Boolean> isSheetEmptyMap = CapraOfficeUtils.getSheetsEmptinessInfo(workBook);
+		if (!isSheetEmptyMap.values().contains(false)) {
+			showErrorMessage(ERROR_TITLE, "There are no rows to display in any of the sheets.", null);
+			clearSelection();
+			return;
+		}
+
 		// Clear the Office view and all static variables
 		clearSelection();
 
-		// Check if the sheet-to-display isn't empty and find a first non-empty
-		// sheet if that is the case, and fill isSheetEmpty HashMap with sheet
-		// names for keys and info about whether they are not empty for values
-		boolean nonEmptySheetFound = sheetToDisplay.getLastRowNum() > 0;
-		isSheetEmptyMap = new HashMap<String, Boolean>();
-		for (int i = 0; i < workBook.getNumberOfSheets(); i++) {
-			Sheet s = workBook.getSheetAt(i);
-			isSheetEmptyMap.put(s.getSheetName(), s.getLastRowNum() > 0);
-
-			if (!nonEmptySheetFound && s.getLastRowNum() > 0) {
-				nonEmptySheetFound = true;
-				sheetToDisplay = s;
-			}
-		}
-
-		if (!nonEmptySheetFound) {
-			showErrorMessage(ERROR_TITLE, "There are no rows to display in any of the sheets.", null);
-			clearSelection();
-			return;
-		}
-
-		selectedSheetName = sheetToDisplay.getSheetName();
+		// Save new values to properties
+		this.selectedSheetName = sheet.getSheetName();
+		this.selectedFile = officeFile;
+		this.selectedFileId = googleDriveFileId;
+		this.isSheetEmptyMap = isSheetEmptyMap;
 
 		// Populate the view with Excel rows
 		String idColumn = Activator.getDefault().getPreferenceStore().getString(OfficePreferences.EXCEL_COLUMN_VALUE);
-		for (int i = 0; i <= sheetToDisplay.getLastRowNum(); i++) {
-			Row row = sheetToDisplay.getRow(i);
+		boolean isGoogleSheet = googleDriveFileId != null;
+		for (int i = 0; i <= sheet.getLastRowNum(); i++) {
+			Row row = sheet.getRow(i);
 			if (row != null) {
-				CapraExcelRow cRow = new CapraExcelRow(officeFile, row, idColumn);
+				CapraOfficeObject cRow;
+				// If the file is in the java's "temporary-file" folder, it was
+				// obtained from Google drive
+				if (isGoogleSheet)
+					cRow = new CapraGoogleSheetsRow(officeFile, row, idColumn, googleDriveFileId);
+				else
+					cRow = new CapraExcelRow(officeFile, row, idColumn);
+
 				if (!cRow.getData().isEmpty())
 					selection.add(cRow);
 			}
@@ -428,9 +404,8 @@
 	private void parseWordDocument(File officeFile) {
 
 		List<XWPFParagraph> paragraphs;
-		try (FileInputStream fs = new FileInputStream(officeFile)) {
-			XWPFDocument xwpfDoc = new XWPFDocument(fs);
-			paragraphs = (xwpfDoc).getParagraphs();
+		try {
+			paragraphs = CapraOfficeUtils.getWordParagraphs(officeFile);
 		} catch (IOException e) {
 			e.printStackTrace();
 			showErrorMessage(ERROR_TITLE, e.getMessage(), null);
@@ -441,8 +416,15 @@
 			return;
 		}
 
+		if (paragraphs.isEmpty())
+			return;
+
+		// Clear the Office view and all static variables
 		clearSelection();
 
+		// Save new values to properties
+		this.selectedFile = officeFile;
+
 		// Populate the view with Word requirements
 		String fieldName = Activator.getDefault().getPreferenceStore().getString(OfficePreferences.WORD_FIELD_NAME);
 		for (int i = 0; i < paragraphs.size(); i++) {
@@ -458,6 +440,7 @@
 			provider.setResource(selection.get(0));
 		else {
 			showErrorMessage(ERROR_TITLE, "There are no fields with the specified field name in this document.", null);
+			clearSelection();
 			return;
 		}
 
@@ -465,8 +448,8 @@
 	}
 
 	/**
-	 * Shows the details of the object in its native environment (MS Word or MS
-	 * Excel).
+	 * Shows the details of the object in its native environment (MS Word, MS
+	 * Excel or Google Drive (sheets)).
 	 * 
 	 * @param event
 	 *            Should be of type DoubleClickEvent or ExecutionEvent, hold the
@@ -512,6 +495,8 @@
 		viewer.refresh();
 		provider.setResource(null);
 		selectedSheetName = null;
+		selectedFile = null;
+		selectedFileId = null;
 		isSheetEmptyMap = null;
 	}
 
@@ -527,9 +512,9 @@
 
 		if (filePath != null && !filePath.isEmpty()) {
 			File file = new File(filePath);
-			if (file != null) {
+			if (file != null && file.exists()) {
 				try {
-					dropToSelection(new String[] { file.getAbsolutePath() });
+					parseGenericFile(file);
 				} catch (CapraOfficeFileNotSupportedException e) {
 					e.printStackTrace();
 					showErrorMessage(ERROR_TITLE, e.getMessage(), null);
@@ -544,12 +529,11 @@
 	 * @param sheetName
 	 *            the name of the sheet to be displayed in the Office view.
 	 */
-	public void selectSheet(String sheetName) {
-
+	public void displaySheet(String sheetName) {
 		if (selection.isEmpty())
 			return;
 		else if (selection.get(0) instanceof CapraExcelRow)
-			parseExcelDocument(selection.get(0).getFile(), sheetName);
+			parseExcelDocument(selectedFile, selectedFileId, sheetName);
 	}
 
 	/**
@@ -561,6 +545,17 @@
 	 *         opened.
 	 */
 	public HashMap<String, Boolean> getIsSheetEmptyMap() {
+
+		// isSheetEmptyMap is used by the SelectSheetDynamicMenu class.
+		if (isSheetEmptyMap == null) {
+			try {
+				isSheetEmptyMap = CapraOfficeUtils.getSheetsEmptinessInfo(
+						CapraOfficeUtils.getExcelWorkbook(((CapraExcelRow) (selection.get(0))).getFile()));
+			} catch (OldExcelFormatException | IOException e) {
+				e.printStackTrace();
+			}
+		}
+
 		return isSheetEmptyMap;
 	}
 
@@ -597,11 +592,14 @@
 			return;
 
 		if (selection.get(0) instanceof CapraExcelRow)
-			parseExcelDocument(selection.get(0).getFile(), selectedSheetName);
+			parseExcelDocument(selectedFile, selectedFileId, selectedSheetName);
 		else if (selection.get(0) instanceof CapraWordRequirement)
-			parseWordDocument(selection.get(0).getFile());
+			parseWordDocument(selectedFile);
 	}
 
+	/**
+	 * Enable context menu for this view.
+	 */
 	private void hookContextMenu() {
 		MenuManager menuMgr = new MenuManager("#PopupMenu");
 		menuMgr.setRemoveAllWhenShown(true);
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/SelectSheetDynamicMenu.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/SelectSheetDynamicMenu.java
index 548be79..a56b4d3 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/SelectSheetDynamicMenu.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/SelectSheetDynamicMenu.java
@@ -32,11 +32,15 @@
 	@Override
 	public void fill(Menu menu, int index) {
 
+		// A HashMap that holds information about the emptiness of sheets. Key -
+		// sheetName, value - true if map is empty, false otherwise
 		HashMap<String, Boolean> isSheetEmptyMap = OfficeView.getOpenedView().getIsSheetEmptyMap();
-		
+
 		if (isSheetEmptyMap == null)
 			return;
 
+		// Add sheetNames to the dynamic context menu and make them
+		// un-selectable if they are empty
 		for (String sheetName : isSheetEmptyMap.keySet()) {
 			MenuItem menuItem = new MenuItem(menu, SWT.CHECK, index);
 
@@ -44,19 +48,19 @@
 
 				@Override
 				public void widgetSelected(SelectionEvent e) {
-					OfficeView.getOpenedView().selectSheet(menuItem.getText());
+					OfficeView.getOpenedView().displaySheet(menuItem.getText());
 				}
 
 				@Override
 				public void widgetDefaultSelected(SelectionEvent e) {
-					OfficeView.getOpenedView().selectSheet(menuItem.getText());
+					OfficeView.getOpenedView().displaySheet(menuItem.getText());
 				}
 			});
 
 			if (OfficeView.getOpenedView().getSelectedSheetName().contentEquals(sheetName))
 				menuItem.setSelection(true);
 
-			if (isSheetEmptyMap.get(sheetName))
+			if (!isSheetEmptyMap.get(sheetName))
 				menuItem.setText(sheetName);
 			else {
 				menuItem.setText(sheetName + " (Empty)");
diff --git a/pom.xml b/pom.xml
index 7741e0e..1b7b9b9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,10 +23,12 @@
 
 	<modules>
 		<module>org.eclipse.capra.core</module>
+		<module>org.eclipse.capra.core.feature</module>
 		<module>org.eclipse.capra.documentation</module>
 		<module>org.eclipse.capra.generic.persistence</module>
 		<module>org.eclipse.capra.generic.priority</module>
 		<module>org.eclipse.capra.generic.tracemodels</module>
+		<module>org.eclipse.capra.generic.feature</module>
 		<module>org.eclipse.capra.handler.cdt</module>
 		<module>org.eclipse.capra.handler.cdt.tests</module>
 		<module>org.eclipse.capra.handler.cdt.feature</module>
@@ -48,6 +50,7 @@
 		<module>org.eclipse.capra.handler.php</module>
 		<module>org.eclipse.capra.handler.php.feature</module>
 		<module>org.eclipse.capra.ui</module>
+		<module>org.eclipse.capra.ui.feature</module>
 		<module>org.eclipse.capra.ui.notification</module>
 		<module>org.eclipse.capra.ui.plantuml</module>
 		<module>org.eclipse.capra.ui.plantuml.feature</module>