diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/FeatureId.java b/src/main/java/org/eclipsefoundation/marketplace/dto/FeatureId.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c749b6b4855b8468fac14c2a7df076662d1142c
--- /dev/null
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/FeatureId.java
@@ -0,0 +1,46 @@
+/* Copyright (c) 2019 Eclipse Foundation and others.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License 2.0
+ * which is available at http://www.eclipse.org/legal/epl-v20.html,
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipsefoundation.marketplace.dto;
+
+import javax.json.bind.annotation.JsonbProperty;
+
+/**
+ * Represents a feature in a listing solution version.
+ * 
+ * @author Martin Lowe
+ */
+public class FeatureId {
+	@JsonbProperty("feature_id")
+	private String name;
+	private String installState;
+	
+	/**
+	 * @return the featureId
+	 */
+	public String getName() {
+		return name;
+	}
+	/**
+	 * @param name the featureId to set
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+	/**
+	 * @return the installState
+	 */
+	public String getInstallState() {
+		return installState;
+	}
+	/**
+	 * @param installState the installState to set
+	 */
+	public void setInstallState(String installState) {
+		this.installState = installState;
+	}
+	
+}
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/SolutionVersion.java b/src/main/java/org/eclipsefoundation/marketplace/dto/SolutionVersion.java
index f4caf4bed269354b77d721705525cc92935ea53e..1968ffbd451d21b5d21b284df9ec7a73a57d7a9c 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/SolutionVersion.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/SolutionVersion.java
@@ -22,6 +22,13 @@ public class SolutionVersion {
 	private List<String> platforms;
 	private String minJavaVersion;
 	private String updateSiteUrl;
+	private List<FeatureId> featureIds;
+	
+	public SolutionVersion() {
+		this.eclipseVersions = new ArrayList<>();
+		this.platforms = new ArrayList<>();
+		this.featureIds = new ArrayList<>();
+	}
 
 	/**
 	 * @return the versionString
@@ -95,4 +102,18 @@ public class SolutionVersion {
 		this.updateSiteUrl = updateSiteUrl;
 	}
 
+	/**
+	 * @return the featureIds
+	 */
+	public List<FeatureId> getFeatureIds() {
+		return featureIds;
+	}
+
+	/**
+	 * @param featureIds the featureIds to set
+	 */
+	public void setFeatureIds(List<FeatureId> featureIds) {
+		this.featureIds = featureIds;
+	}
+
 }
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/converters/FeatureIdConverter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/converters/FeatureIdConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..29b3fad142491094fd977aecec81d8282648cbfa
--- /dev/null
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/converters/FeatureIdConverter.java
@@ -0,0 +1,38 @@
+/* Copyright (c) 2019 Eclipse Foundation and others.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License 2.0
+ * which is available at http://www.eclipse.org/legal/epl-v20.html,
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipsefoundation.marketplace.dto.converters;
+
+import org.bson.Document;
+import org.eclipsefoundation.marketplace.dto.FeatureId;
+import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames;
+
+/**
+ * Converter implementation for the {@link FeatureId} object.
+ * 
+ * @author Martin Lowe
+ */
+public class FeatureIdConverter implements Converter<FeatureId> {
+
+	@Override
+	public FeatureId convert(Document src) {
+		FeatureId featureId = new FeatureId();
+
+		featureId.setName(src.getString(DatabaseFieldNames.FEATURE_ID));
+		featureId.setInstallState(src.getString(DatabaseFieldNames.INSTALL_STATE));
+
+		return featureId;
+	}
+
+	@Override
+	public Document convert(FeatureId src) {
+		Document doc = new Document();
+		doc.put(DatabaseFieldNames.FEATURE_ID, src.getName());
+		doc.put(DatabaseFieldNames.INSTALL_STATE, src.getInstallState());
+		return doc;
+	}
+
+}
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/converters/SolutionVersionConverter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/converters/SolutionVersionConverter.java
index d75e8ae846feb360479ea49344c4fb1742201410..880f31717d1abfd2fa89374f7b4c5e8472402001 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/converters/SolutionVersionConverter.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/converters/SolutionVersionConverter.java
@@ -6,8 +6,11 @@
  */
 package org.eclipsefoundation.marketplace.dto.converters;
 
+import java.util.stream.Collectors;
+
 import org.bson.Document;
 import org.eclipsefoundation.marketplace.dto.SolutionVersion;
+import org.eclipsefoundation.marketplace.namespace.DatabaseFieldNames;
 
 /**
  * Converter implementation for the {@link SolutionVersion} object.
@@ -16,6 +19,8 @@ import org.eclipsefoundation.marketplace.dto.SolutionVersion;
  */
 public class SolutionVersionConverter implements Converter<SolutionVersion> {
 
+	private final FeatureIdConverter featureIdConverter = new FeatureIdConverter();
+
 	@Override
 	public SolutionVersion convert(Document src) {
 		SolutionVersion version = new SolutionVersion();
@@ -24,7 +29,8 @@ public class SolutionVersionConverter implements Converter<SolutionVersion> {
 		version.setMinJavaVersion(src.getString("min_java_version"));
 		version.setUpdateSiteUrl(src.getString("update_site_url"));
 		version.setVersion(src.getString("version"));
-
+		version.setFeatureIds(src.getList(DatabaseFieldNames.FEATURE_IDS, Document.class).stream()
+				.map(featureIdConverter::convert).collect(Collectors.toList()));
 		return version;
 	}
 
@@ -36,7 +42,8 @@ public class SolutionVersionConverter implements Converter<SolutionVersion> {
 		doc.put("min_java_version", src.getMinJavaVersion());
 		doc.put("update_site_url", src.getUpdateSiteUrl());
 		doc.put("version", src.getVersion());
-
+		doc.put(DatabaseFieldNames.FEATURE_IDS,
+				src.getFeatureIds().stream().map(featureIdConverter::convert).collect(Collectors.toList()));
 		return doc;
 	}
 }
diff --git a/src/main/java/org/eclipsefoundation/marketplace/model/UserAgent.java b/src/main/java/org/eclipsefoundation/marketplace/model/UserAgent.java
index bc1782286d750660ab91565281a6927811796e09..c5221f559ad3c70ea1fcaba8c04658791bfc6238 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/model/UserAgent.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/model/UserAgent.java
@@ -49,6 +49,8 @@ public class UserAgent {
 	private String osVersion;
 	private String locale;
 
+	private String eclipseVersion;
+
 	public UserAgent(String userAgent) {
 		Objects.requireNonNull(userAgent);
 
@@ -70,32 +72,46 @@ public class UserAgent {
 		this.enhancements = m.group(4);
 		if (MPC_CLIENT_AGENT_NAME.equalsIgnoreCase(name)) {
 			handleMpc();
-		} else if (name.contains("bot")) {
-			// drop as we don't care about bot properties
-		} else {
-			handleWeb();
 		}
 	}
 
+	/**
+	 * Breaks down the different MPC properties into explicit properties that can be
+	 * retrieved via getters built into the class. The expected format is defined
+	 * below:
+	 * 
+	 * <p>
+	 * {@code mpc/<mpc version> (Java <java version> <java vendor>; <os name> <os version> <os arch>; <locale>) <eclipse product>/<product version> (<eclipse application>)}
+	 * </p>
+	 */
 	private void handleMpc() {
+		// expected form: (Java <java version> <java vendor>; <os name> <os version> <os
+		// arch>; <locale>)
 		List<String> systemPropList = Splitter.on(';').splitToList(systemProperties);
 		if (systemPropList.size() != 3) {
 			// TODO throw exception?
 		}
 		// expected form example: Java <java version> <vendor>
-		String javaPropStr = systemPropList.get(0);
-		String javaPlatform = javaPropStr.substring(javaPropStr.indexOf(' ') + 1);
-		List<String> javaProps = Splitter.on(' ').limit(2).splitToList(javaPlatform);
-		this.javaVersion = javaProps.get(0);
-		this.javaVendor = javaProps.get(1);
-		
-		// expected form: <OS name> <OS version> <??>
-		String systemPlatform = systemPropList.get(1);
-		this.locale = systemPropList.get(2);
-	}
+		List<String> javaProps = Splitter.on(' ').limit(3).splitToList(systemPropList.get(0));
+		if (javaProps.size() != 3) {
+			// TODO throw exception?
+		}
+		this.javaVersion = javaProps.get(1);
+		this.javaVendor = javaProps.get(2);
+
+		// expected form: <OS name> <OS version> <OS arch>
+		List<String> systemProps = Splitter.on(' ').limit(3).splitToList(systemPropList.get(1));
+		if (systemProps.size() != 3) {
+			// TODO throw exception?
+		}
+		this.os = systemProps.get(0);
+		this.osVersion = systemProps.get(1);
 
-	private void handleWeb() {
+		// get the current locale
+		this.locale = systemPropList.get(2);
 
+		// expected form: <eclipse product>/<product version>
+		List<String> platformProps = Splitter.on('/').limit(3).splitToList(platform);
 	}
 
 	/**
diff --git a/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java b/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java
index 12ff8a9ef8b7403568d2e44970af818d05e328bc..9638a310f0b82cae15586ac7a9fc984673df4590 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java
@@ -21,6 +21,7 @@ public final class DatabaseFieldNames {
 	public static final String DOCID = "_id";
 	public static final String URL = "url";
 	public static final String NAME = "name";
+	public static final String OS = "os";
 	
 	// listing fields
 	public static final String LISTING_TEASER = "teaser";
@@ -43,7 +44,8 @@ public final class DatabaseFieldNames {
 	public static final String LISTING_TAGS = "tags";
 	public static final String CATEGORY_IDS = "category_ids";
 	public static final String LISTING_CATEGORIES = "categories";
-	public static final String MAINTAINERS = "maintainers";
+	public static final String FEATURE_ID = "feature_id";
+	public static final String INSTALL_STATE = "install_state";
 
 	// catalog fields
 	public static final String CATALOG_TABS = "tabs";
@@ -53,6 +55,17 @@ public final class DatabaseFieldNames {
 	public static final String CATALOG_DESCRIPTION = "description";
 	public static final String CATALOG_DEPENDENCIES_REPOSITORY = "dependencies_repository";
 	
+	// category fields
+	public static final String MARKET_IDS = "market_ids";
+	
+	public static final String INSTALL_JAVA_VERSION = "java_version";
+	public static final String INSTALL_VERSION = "version";
+	public static final String INSTALL_LISTING_ID = "listing_id";
+	public static final String INSTALL_DATE = "date";
+	public static final String ECLIPSE_VERSION = "eclipse_version";
+	public static final String FEATURE_IDS = "feature_ids";
+	public static final String LOCALE = "locale";
+	
 	private DatabaseFieldNames() {
 	}
 }