diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 92fdbde..7f34593 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -19,12 +19,13 @@
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Point;
-import android.graphics.PointF;
 import android.os.Build;
 import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.WindowManager;
+
 import com.android.launcher3.util.Thunk;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -34,61 +35,36 @@
     // This is a static that we use for the default icon size on a 4/5-inch phone
     private static float DEFAULT_ICON_SIZE_DP = 60;
 
-    private static final ArrayList<InvariantDeviceProfile> sDeviceProfiles = new ArrayList<>();
-    static {
-        sDeviceProfiles.add(new InvariantDeviceProfile("Super Short Stubby",
-                255, 300,  2, 3, 2, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
-        sDeviceProfiles.add(new InvariantDeviceProfile("Shorter Stubby",
-                255, 400,  3, 3, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
-        sDeviceProfiles.add(new InvariantDeviceProfile("Short Stubby",
-                275, 420,  3, 4, 3, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
-        sDeviceProfiles.add(new InvariantDeviceProfile("Stubby",
-                255, 450,  3, 4, 3, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
-        sDeviceProfiles.add(new InvariantDeviceProfile("Nexus S",
-                296, 491.33f,  4, 4, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
-        sDeviceProfiles.add(new InvariantDeviceProfile("Nexus 4",
-                335, 567,  4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
-        sDeviceProfiles.add(new InvariantDeviceProfile("Nexus 5",
-                359, 567,  4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
-        sDeviceProfiles.add(new InvariantDeviceProfile("Large Phone",
-                406, 694,  5, 5, 4, 4,  64, 14.4f,  5, 56, R.xml.default_workspace_5x5));
-        // The tablet profile is odd in that the landscape orientation
-        // also includes the nav bar on the side
-        sDeviceProfiles.add(new InvariantDeviceProfile("Nexus 7",
-                575, 904,  5, 6, 4, 5, 72, 14.4f,  7, 60, R.xml.default_workspace_5x6));
-        // Larger tablet profiles always have system bars on the top & bottom
-        sDeviceProfiles.add(new InvariantDeviceProfile("Nexus 10",
-                727, 1207,  5, 6, 4, 5, 76, 14.4f,  7, 64, R.xml.default_workspace_5x6));
-        sDeviceProfiles.add(new InvariantDeviceProfile("20-inch Tablet",
-                1527, 2527,  7, 7, 6, 6, 100, 20,  7, 72, R.xml.default_workspace_4x4));
-    }
+    // Constants that affects the interpolation curve between statically defined device profile
+    // buckets.
+    private static float KNEARESTNEIGHBOR = 3;
+    private static float WEIGHT_POWER = 5;
 
-    private class DeviceProfileQuery {
-        InvariantDeviceProfile profile;
-        float widthDps;
-        float heightDps;
-        float value;
-        PointF dimens;
-
-        DeviceProfileQuery(InvariantDeviceProfile p, float v) {
-            widthDps = p.minWidthDps;
-            heightDps = p.minHeightDps;
-            value = v;
-            dimens = new PointF(widthDps, heightDps);
-            profile = p;
-        }
-    }
+    // used to offset float not being able to express extremely small weights in extreme cases.
+    private static float WEIGHT_EFFICIENT = 100000f;
 
     // Profile-defining invariant properties
     String name;
     float minWidthDps;
     float minHeightDps;
+
+    /**
+     * Number of icons per row and column in the workspace.
+     */
     public int numRows;
     public int numColumns;
+
+    /**
+     * Number of icons per row and column in the folder.
+     */
     public int numFolderRows;
     public int numFolderColumns;
     float iconSize;
     float iconTextSize;
+
+    /**
+     * Number of icons inside the hotseat area.
+     */
     float numHotseatIcons;
     float hotseatIconSize;
     int defaultLayoutId;
@@ -102,6 +78,12 @@
     InvariantDeviceProfile() {
     }
 
+    public InvariantDeviceProfile(InvariantDeviceProfile p) {
+        this(p.name, p.minWidthDps, p.minHeightDps, p.numRows, p.numColumns,
+                p.numFolderRows, p.numFolderColumns, p.iconSize, p.iconTextSize, p.numHotseatIcons,
+                p.hotseatIconSize, p.defaultLayoutId);
+    }
+
     InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc,
             float is, float its, float hs, float his, int dlId) {
         // Ensure that we have an odd number of hotseat items (since we need to place all apps)
@@ -134,21 +116,16 @@
         Point largestSize = new Point();
         display.getCurrentSizeRange(smallestSize, largestSize);
 
+        // This guarantees that width < height
         minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y), dm);
         minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y), dm);
 
-        ArrayList<DeviceProfileQuery> points =
-                new ArrayList<DeviceProfileQuery>();
+        ArrayList<InvariantDeviceProfile> closestProfiles =
+                findClosestDeviceProfiles(minWidthDps, minHeightDps, getPredefinedDeviceProfiles());
+        InvariantDeviceProfile interpolatedDeviceProfileOut =
+                invDistWeightedInterpolate(minWidthDps,  minHeightDps, closestProfiles);
 
-        // Find the closes profile given the width/height
-        for (InvariantDeviceProfile p : sDeviceProfiles) {
-            points.add(new DeviceProfileQuery(p, 0f));
-        }
-
-        InvariantDeviceProfile closestProfile =
-                findClosestDeviceProfile(minWidthDps, minHeightDps, points);
-
-        // The following properties are inherited directly from the nearest archetypal profile
+        InvariantDeviceProfile closestProfile = closestProfiles.get(0);
         numRows = closestProfile.numRows;
         numColumns = closestProfile.numColumns;
         numHotseatIcons = closestProfile.numHotseatIcons;
@@ -157,24 +134,9 @@
         numFolderRows = closestProfile.numFolderRows;
         numFolderColumns = closestProfile.numFolderColumns;
 
-
-        // The following properties are interpolated based on proximity to nearby archetypal
-        // profiles
-        points.clear();
-        for (InvariantDeviceProfile p : sDeviceProfiles) {
-            points.add(new DeviceProfileQuery(p, p.iconSize));
-        }
-        iconSize = invDistWeightedInterpolate(minWidthDps, minHeightDps, points);
-        points.clear();
-        for (InvariantDeviceProfile p : sDeviceProfiles) {
-            points.add(new DeviceProfileQuery(p, p.iconTextSize));
-        }
-        iconTextSize = invDistWeightedInterpolate(minWidthDps, minHeightDps, points);
-        points.clear();
-        for (InvariantDeviceProfile p : sDeviceProfiles) {
-            points.add(new DeviceProfileQuery(p, p.hotseatIconSize));
-        }
-        hotseatIconSize = invDistWeightedInterpolate(minWidthDps, minHeightDps, points);
+        iconSize = interpolatedDeviceProfileOut.iconSize;
+        iconTextSize = interpolatedDeviceProfileOut.iconTextSize;
+        hotseatIconSize = interpolatedDeviceProfileOut.hotseatIconSize;
 
         // If the partner customization apk contains any grid overrides, apply them
         // Supported overrides: numRows, numColumns, iconSize
@@ -182,7 +144,7 @@
 
         Point realSize = new Point();
         display.getRealSize(realSize);
-        // The real size never changes. smallSide and largeSize will remain the
+        // The real size never changes. smallSide and largeSide will remain the
         // same in any orientation.
         int smallSide = Math.min(realSize.x, realSize.y);
         int largeSide = Math.max(realSize.x, realSize.y);
@@ -193,84 +155,112 @@
                 smallSide, largeSide, false /* isLandscape */);
     }
 
+    ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles() {
+        ArrayList<InvariantDeviceProfile> predefinedDeviceProfiles = new ArrayList<>();
+        // width, height, #rows, #columns, #folder rows, #folder columns,
+        // iconSize, iconTextSize, #hotseat, #hotseatIconSize, defaultLayoutId.
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Super Short Stubby",
+                255, 300,     2, 3, 2, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Shorter Stubby",
+                255, 400,     3, 3, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Short Stubby",
+                275, 420,     3, 4, 3, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Stubby",
+                255, 450,     3, 4, 3, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus S",
+                296, 491.33f, 4, 4, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 4",
+                335, 567,     4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 5",
+                359, 567,     4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Large Phone",
+                406, 694,     5, 5, 4, 4,  64, 14.4f,  5, 56, R.xml.default_workspace_5x5));
+        // The tablet profile is odd in that the landscape orientation
+        // also includes the nav bar on the side
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 7",
+                575, 904,     5, 6, 4, 5, 72, 14.4f,  7, 60, R.xml.default_workspace_5x6));
+        // Larger tablet profiles always have system bars on the top & bottom
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 10",
+                727, 1207,    5, 6, 4, 5, 76, 14.4f,  7, 64, R.xml.default_workspace_5x6));
+        predefinedDeviceProfiles.add(new InvariantDeviceProfile("20-inch Tablet",
+                1527, 2527,   7, 7, 6, 6, 100, 20,  7, 72, R.xml.default_workspace_4x4));
+        return predefinedDeviceProfiles;
+    }
+
+
     /**
      * Apply any Partner customization grid overrides.
      *
      * Currently we support: all apps row / column count.
      */
-    private void applyPartnerDeviceProfileOverrides(Context ctx, DisplayMetrics dm) {
-        Partner p = Partner.get(ctx.getPackageManager());
+    private void applyPartnerDeviceProfileOverrides(Context context, DisplayMetrics dm) {
+        Partner p = Partner.get(context.getPackageManager());
         if (p != null) {
             p.applyInvariantDeviceProfileOverrides(this, dm);
         }
     }
 
-    @Thunk float dist(PointF p0, PointF p1) {
-        return (float) Math.sqrt((p1.x - p0.x)*(p1.x-p0.x) +
-                (p1.y-p0.y)*(p1.y-p0.y));
+    @Thunk float dist(float x0, float y0, float x1, float y1) {
+        return (float) Math.hypot(x1 - x0, y1 - y0);
     }
 
-    private float weight(PointF a, PointF b,
-                        float pow) {
-        float d = dist(a, b);
-        if (d == 0f) {
-            return Float.POSITIVE_INFINITY;
-        }
-        return (float) (1f / Math.pow(d, pow));
-    }
-
-    /** Returns the closest device profile given the width and height and a list of profiles */
-    private InvariantDeviceProfile findClosestDeviceProfile(float width, float height,
-                                                   ArrayList<DeviceProfileQuery> points) {
-        return findClosestDeviceProfiles(width, height, points).get(0).profile;
-    }
-
-    /** Returns the closest device profiles ordered by closeness to the specified width and height */
-    private ArrayList<DeviceProfileQuery> findClosestDeviceProfiles(float width, float height,
-                                                   ArrayList<DeviceProfileQuery> points) {
-        final PointF xy = new PointF(width, height);
+    /**
+     * Returns the closest device profiles ordered by closeness to the specified width and height
+     */
+    // Package private visibility for testing.
+    ArrayList<InvariantDeviceProfile> findClosestDeviceProfiles(
+            final float width, final float height, ArrayList<InvariantDeviceProfile> points) {
 
         // Sort the profiles by their closeness to the dimensions
-        ArrayList<DeviceProfileQuery> pointsByNearness = points;
-        Collections.sort(pointsByNearness, new Comparator<DeviceProfileQuery>() {
-            public int compare(DeviceProfileQuery a, DeviceProfileQuery b) {
-                return (int) (dist(xy, a.dimens) - dist(xy, b.dimens));
+        ArrayList<InvariantDeviceProfile> pointsByNearness = points;
+        Collections.sort(pointsByNearness, new Comparator<InvariantDeviceProfile>() {
+            public int compare(InvariantDeviceProfile a, InvariantDeviceProfile b) {
+                return (int) (dist(width, height, a.minWidthDps, a.minHeightDps)
+                        - dist(width, height, b.minWidthDps, b.minHeightDps));
             }
         });
 
         return pointsByNearness;
     }
 
-    private float invDistWeightedInterpolate(float width, float height,
-                ArrayList<DeviceProfileQuery> points) {
-        float sum = 0;
+    // Package private visibility for testing.
+    InvariantDeviceProfile invDistWeightedInterpolate(float width, float height,
+                ArrayList<InvariantDeviceProfile> points) {
         float weights = 0;
-        float pow = 5;
-        float kNearestNeighbors = 3;
-        final PointF xy = new PointF(width, height);
 
-        ArrayList<DeviceProfileQuery> pointsByNearness = findClosestDeviceProfiles(width, height,
-                points);
-
-        for (int i = 0; i < pointsByNearness.size(); ++i) {
-            DeviceProfileQuery p = pointsByNearness.get(i);
-            if (i < kNearestNeighbors) {
-                float w = weight(xy, p.dimens, pow);
-                if (w == Float.POSITIVE_INFINITY) {
-                    return p.value;
-                }
-                weights += w;
-            }
+        InvariantDeviceProfile p = points.get(0);
+        if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
+            return p;
         }
 
-        for (int i = 0; i < pointsByNearness.size(); ++i) {
-            DeviceProfileQuery p = pointsByNearness.get(i);
-            if (i < kNearestNeighbors) {
-                float w = weight(xy, p.dimens, pow);
-                sum += w * p.value / weights;
-            }
+        InvariantDeviceProfile out = new InvariantDeviceProfile();
+        for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) {
+            p = new InvariantDeviceProfile(points.get(i));
+            float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
+            weights += w;
+            out.add(p.multiply(w));
         }
-
-        return sum;
+        return out.multiply(1.0f/weights);
     }
-}
+
+    private void add(InvariantDeviceProfile p) {
+        iconSize += p.iconSize;
+        iconTextSize += p.iconTextSize;
+        hotseatIconSize += p.hotseatIconSize;
+    }
+
+    private InvariantDeviceProfile multiply(float w) {
+        iconSize *= w;
+        iconTextSize *= w;
+        hotseatIconSize *= w;
+        return this;
+    }
+
+    private float weight(float x0, float y0, float x1, float y1, float pow) {
+        float d = dist(x0, y0, x1, y1);
+        if (Float.compare(d, 0f) == 0) {
+            return Float.POSITIVE_INFINITY;
+        }
+        return (float) (WEIGHT_EFFICIENT / Math.pow(d, pow));
+    }
+}
\ No newline at end of file
