Started working on the new version of the solver for MISC2012.
diff --git a/org.eclipse.equinox.p2.cudf/pom.xml b/org.eclipse.equinox.p2.cudf/pom.xml
index d463afe..1e044dd 100644
--- a/org.eclipse.equinox.p2.cudf/pom.xml
+++ b/org.eclipse.equinox.p2.cudf/pom.xml
@@ -52,7 +52,7 @@
 
 	<groupId>org.eclipse.equinox</groupId>
 	<artifactId>org.eclipse.equinox.p2.cudf</artifactId>
-	<version>1.14-SNAPSHOT</version>
+	<version>1.15-SNAPSHOT</version>
 
 
 	<organization>
@@ -67,16 +67,17 @@
 	</repositories>
 	<dependencies>
 		<dependency>
-			<groupId>org.sat4j</groupId>
-			<artifactId>org.sat4j.pb</artifactId>
-			<version>2.3.1-SNAPSHOT</version>
-		</dependency>
-		<dependency>
 			<groupId>org.eclipse.core</groupId>
 			<artifactId>org.eclipse.core.jobs</artifactId>
 			<version>3.5.0.v20100515</version>
 		</dependency>
 		<dependency>
+                       <groupId>org.sat4j</groupId>
+                       <artifactId>org.sat4j.pb</artifactId>
+                       <version>2.3.3-SNAPSHOT</version>
+               </dependency>
+               <dependency>
+
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
 			<version>3.8.2</version>
@@ -162,4 +163,4 @@
 			</plugin>
 		</plugins>
 	</build>
-</project>
\ No newline at end of file
+</project>
diff --git a/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/Parser.java b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/Parser.java
index fecac76..a05c50f 100644
--- a/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/Parser.java
+++ b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/Parser.java
@@ -11,6 +11,7 @@
 
 import java.io.*;
 import java.util.*;
+import java.util.zip.GZIPInputStream;
 import org.eclipse.equinox.p2.cudf.metadata.*;
 import org.eclipse.equinox.p2.cudf.query.*;
 import org.eclipse.equinox.p2.cudf.solver.ProfileChangeRequest;
@@ -51,10 +52,19 @@
 
 	public ProfileChangeRequest parse(File file, boolean includeRecommends, String sumProperty) {
 		try {
-			return parse(new FileInputStream(file), includeRecommends, sumProperty);
+			InputStream in = new FileInputStream(file);
+			if (file.getName().endsWith(".gz")) {
+				in = new GZIPInputStream(in);
+			} else if (file.getName().endsWith(".bz2")) {
+				in = Runtime.getRuntime().exec("bunzip2 -c " + file.getAbsolutePath()).getInputStream();
+			}
+			return parse(in, includeRecommends, sumProperty);
 		} catch (FileNotFoundException e) {
 			e.printStackTrace();
 			return null;
+		} catch (IOException e) {
+			e.printStackTrace();
+			return null;
 		}
 	}
 
diff --git a/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/OptimizationFunction.java b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/OptimizationFunction.java
index 3d50796..089498e 100644
--- a/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/OptimizationFunction.java
+++ b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/OptimizationFunction.java
@@ -29,6 +29,8 @@
 	protected List nouptodateVariables = new ArrayList();
 	protected List newVariables = new ArrayList();
 	protected List unmetVariables = new ArrayList();
+	protected List upVariables = new ArrayList();
+	protected List downVariables = new ArrayList();
 	protected List optionalityVariables;
 	protected List optionalityPairs;
 
@@ -127,6 +129,84 @@
 		}
 	}
 
+	protected void changed2012(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
+		Set s = slice.entrySet();
+		for (Iterator iterator = s.iterator(); iterator.hasNext();) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			if (entry.getKey() == metaIu.getId())
+				continue;
+			Collection versions = ((HashMap) entry.getValue()).values();
+			Object[] changed = new Object[versions.size()];
+			int i = 0;
+			for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
+				InstallableUnit iu = (InstallableUnit) iterator2.next();
+				changed[i++] = iu.isInstalled() ? dependencyHelper.not(iu) : iu;
+			}
+			for (Object obj : changed) {
+				changeVariables.add(obj);
+				weightedObjects.add(WeightedObject.newWO(obj, weight));
+			}
+		}
+	}
+
+	protected void up(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
+		Set s = slice.entrySet();
+		for (Iterator iterator = s.iterator(); iterator.hasNext();) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			if (entry.getKey() == metaIu.getId())
+				continue;
+			Collection versions = ((HashMap) entry.getValue()).values();
+			List changed = null;
+			int i = 0;
+			boolean pkgInstalled = false;
+			for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
+				InstallableUnit iu = (InstallableUnit) iterator2.next();
+				if (iu.isInstalled()) {
+					changed = new ArrayList();
+					pkgInstalled = true;
+				} else {
+					if (pkgInstalled) {
+						changed.add(iu);
+					}
+				}
+			}
+			if (changed != null) {
+				for (Object obj : changed) {
+					upVariables.add(obj);
+					weightedObjects.add(WeightedObject.newWO(obj, weight));
+				}
+			}
+		}
+	}
+
+	protected void down(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
+		Set s = slice.entrySet();
+		for (Iterator iterator = s.iterator(); iterator.hasNext();) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			if (entry.getKey() == metaIu.getId())
+				continue;
+			Collection versions = ((HashMap) entry.getValue()).values();
+			List changed = new ArrayList();
+			int i = 0;
+			boolean pkgInstalled = false;
+			for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
+				InstallableUnit iu = (InstallableUnit) iterator2.next();
+				if (iu.isInstalled()) {
+					pkgInstalled = true;
+					break;
+				} else {
+					changed.add(iu);
+				}
+			}
+			if (pkgInstalled) {
+				for (Object obj : changed) {
+					downVariables.add(obj);
+					weightedObjects.add(WeightedObject.newWO(obj, weight));
+				}
+			}
+		}
+	}
+
 	protected void uptodate(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
 		Set s = slice.entrySet();
 		for (Iterator iterator = s.iterator(); iterator.hasNext();) {
diff --git a/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/Projector.java b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/Projector.java
index 5bcda20..609f39c 100644
--- a/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/Projector.java
+++ b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/Projector.java
@@ -175,7 +175,7 @@
 
 	private OptimizationFunction getOptimizationFactory(String optFunctionName) {
 		OptimizationFunction function = null;
-		function = new UserDefinedOptimizationFunction(optFunctionName);
+		function = new UserDefinedOptimizationFunction2012(optFunctionName);
 		Log.println("Optimization function: " + function.getName());
 		function.slice = slice;
 		function.noopVariables = noopVariables;
diff --git a/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/UserDefinedOptimizationFunction2012.java b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/UserDefinedOptimizationFunction2012.java
new file mode 100644
index 0000000..53005a5
--- /dev/null
+++ b/org.eclipse.equinox.p2.cudf/src/main/java/org/eclipse/equinox/p2/cudf/solver/UserDefinedOptimizationFunction2012.java
@@ -0,0 +1,225 @@
+package org.eclipse.equinox.p2.cudf.solver;
+
+import java.math.BigInteger;
+import java.util.*;
+import org.eclipse.equinox.p2.cudf.Options;
+import org.eclipse.equinox.p2.cudf.metadata.InstallableUnit;
+import org.sat4j.pb.tools.WeightedObject;
+import org.sat4j.specs.IVec;
+
+public class UserDefinedOptimizationFunction2012 extends UserDefinedOptimizationFunction {
+
+	private String optfunction;
+
+	public UserDefinedOptimizationFunction2012(String optfunction) {
+		super(optfunction);
+		this.optfunction = optfunction;
+	}
+
+	public List createOptimizationFunction(InstallableUnit metaIu) {
+		List weightedObjects = new ArrayList();
+		List objects = new ArrayList();
+		BigInteger weight = BigInteger.valueOf(slice.size() + 1);
+		String[] criteria = optfunction.split(",");
+		BigInteger currentWeight = weight.pow(criteria.length - 1);
+		int formermaxvarid = dependencyHelper.getSolver().nextFreeVarId(false);
+		int newmaxvarid;
+		boolean maximizes;
+		Object thing;
+		for (int i = 0; i < criteria.length; i++) {
+			if (criteria[i].endsWith("new")) {
+				weightedObjects.clear();
+				niou(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+				currentWeight = currentWeight.divide(weight);
+			} else if (criteria[i].endsWith("removed")) {
+				weightedObjects.clear();
+				removed(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+				currentWeight = currentWeight.divide(weight);
+			} else if (criteria[i].endsWith("notuptodate")) {
+				weightedObjects.clear();
+				notuptodate(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+				currentWeight = currentWeight.divide(weight);
+			} else if (criteria[i].endsWith("unsat_recommends")) {
+				weightedObjects.clear();
+				optional(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+				currentWeight = currentWeight.divide(weight);
+			} else if (criteria[i].endsWith("versionchanged")) {
+				weightedObjects.clear();
+				versionChanged(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+			} else if (criteria[i].endsWith("changed")) {
+				weightedObjects.clear();
+				changed2012(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+				currentWeight = currentWeight.divide(weight);
+			} else if (criteria[i].endsWith("up")) {
+				weightedObjects.clear();
+				up(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+				currentWeight = currentWeight.divide(weight);
+			} else if (criteria[i].endsWith("down")) {
+				weightedObjects.clear();
+				down(weightedObjects, criteria[i].startsWith("+") ? currentWeight.negate() : currentWeight, metaIu);
+				currentWeight = currentWeight.divide(weight);
+			} else if (criteria[i].contains("sum")) {
+				weightedObjects.clear();
+				sum(weightedObjects, criteria[i].charAt(0) == '-', metaIu, Options.extractSumProperty(criteria[i]));
+				dependencyHelper.addWeightedCriterion(weightedObjects);
+				System.out.println("# criteria " + criteria[i].substring(1) + " size is " + weightedObjects.size());
+				continue;
+			} else {
+				System.out.println("Skipping unknown criteria:" + criteria[i]);
+			}
+			objects.clear();
+			maximizes = criteria[i].startsWith("+");
+			for (Iterator it = weightedObjects.iterator(); it.hasNext();) {
+				thing = ((WeightedObject) it.next()).thing;
+				if (maximizes) {
+					thing = dependencyHelper.not(thing);
+				}
+				objects.add(thing);
+			}
+			dependencyHelper.addCriterion(objects);
+			newmaxvarid = dependencyHelper.getSolver().nextFreeVarId(false);
+			System.out.println("# criteria " + criteria[i].substring(1) + " size is " + objects.size() + " using new vars " + formermaxvarid + " to " + newmaxvarid);
+			formermaxvarid = newmaxvarid;
+		}
+		weightedObjects.clear();
+		return null;
+	}
+
+	public String getName() {
+		return "User defined:" + optfunction;
+	}
+
+	public void printSolutionValue() {
+		int counter;
+		List proof = new ArrayList();
+		String[] criteria = optfunction.split(",");
+		for (int i = 0; i < criteria.length; i++) {
+			if (criteria[i].endsWith("new")) {
+				proof.clear();
+				counter = 0;
+				for (int j = 0; j < newVariables.size(); j++) {
+					Object var = newVariables.get(j);
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString().substring(18));
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Newly installed packages: " + proof);
+				continue;
+			}
+			if (criteria[i].endsWith("removed")) {
+				proof.clear();
+				counter = 0;
+				for (int j = 0; j < removalVariables.size(); j++) {
+					Object var = removalVariables.get(j);
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString().substring(18));
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Removed packages: " + proof);
+				continue;
+			}
+			if (criteria[i].endsWith("notuptodate")) {
+				proof.clear();
+				counter = 0;
+				for (int j = 0; j < nouptodateVariables.size(); j++) {
+					Object var = nouptodateVariables.get(j);
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString().substring(18));
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Not up-to-date packages: " + proof);
+				continue;
+			}
+			if (criteria[i].endsWith("recommended") || criteria[i].endsWith("unsat_recommends")) {
+				proof.clear();
+				counter = 0;
+				for (Iterator it = unmetVariables.iterator(); it.hasNext();) {
+					Object var = it.next();
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString().substring(18));
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Not installed recommended packages: " + proof);
+				continue;
+			}
+			if (criteria[i].endsWith("versionchanged")) {
+				proof.clear();
+				counter = 0;
+				for (int j = 0; j < versionChangeVariables.size(); j++) {
+					Object var = versionChangeVariables.get(j);
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString().substring(18));
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Packages with version change: " + proof);
+				continue;
+			}
+			if (criteria[i].endsWith("changed")) {
+				proof.clear();
+				counter = 0;
+				for (int j = 0; j < changeVariables.size(); j++) {
+					Object var = changeVariables.get(j);
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString());
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Changed packages: " + proof);
+				continue;
+			}
+			if (criteria[i].endsWith("up")) {
+				proof.clear();
+				counter = 0;
+				for (int j = 0; j < upVariables.size(); j++) {
+					Object var = upVariables.get(j);
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString().substring(18));
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Upgraded packages: " + proof);
+				continue;
+			}
+			if (criteria[i].endsWith("down")) {
+				proof.clear();
+				counter = 0;
+				for (int j = 0; j < downVariables.size(); j++) {
+					Object var = downVariables.get(j);
+					if (dependencyHelper.getBooleanValueFor(var)) {
+						counter++;
+						proof.add(var.toString().substring(18));
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + counter);
+				System.out.println("# Downgraded packages: " + proof);
+				continue;
+			}
+			if (criteria[i].contains("sum")) {
+				String sumpProperty = Options.extractSumProperty(criteria[i]);
+				long sum = 0;
+				IVec sol = dependencyHelper.getSolution();
+				for (Iterator it = sol.iterator(); it.hasNext();) {
+					Object element = it.next();
+					if (element instanceof InstallableUnit) {
+						InstallableUnit iu = (InstallableUnit) element;
+						sum += iu.getSumProperty();
+					}
+				}
+				System.out.println("# " + criteria[i] + " criteria value: " + sum);
+				continue;
+			}
+		}
+	}
+}