diff --git a/settings.gradle b/settings.gradle
index b92434f..5444b81 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -13,6 +13,9 @@
 include ':support-mediarouter-v7'
 project(':support-mediarouter-v7').projectDir = new File(rootDir, 'v7/mediarouter')
 
+include ':support-palette-v7'
+project(':support-palette-v7').projectDir = new File(rootDir, 'v7/palette')
+
 include ':support-recyclerview-v7'
 project(':support-recyclerview-v7').projectDir = new File(rootDir, 'v7/recyclerview')
 
diff --git a/v7/palette/.classpath b/v7/palette/.classpath
new file mode 100644
index 0000000..43cb38c
--- /dev/null
+++ b/v7/palette/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path="src"/>
+    <classpathentry kind="src" path="gen"/>
+    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+    <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+    <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/v7/palette/.project b/v7/palette/.project
new file mode 100644
index 0000000..76e11a6
--- /dev/null
+++ b/v7/palette/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+    <name>android-support-v7-palette</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+    </natures>
+</projectDescription>
diff --git a/v7/palette/Android.mk b/v7/palette/Android.mk
new file mode 100644
index 0000000..8d75853
--- /dev/null
+++ b/v7/palette/Android.mk
@@ -0,0 +1,22 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Here is the final static library that apps can link against.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v7-palette
+LOCAL_SDK_VERSION := 7
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/v7/palette/AndroidManifest.xml b/v7/palette/AndroidManifest.xml
new file mode 100644
index 0000000..20e14c2
--- /dev/null
+++ b/v7/palette/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.support.v7.palette">
+    <uses-sdk android:minSdkVersion="7"/>
+    <application>
+    </application>
+</manifest>
diff --git a/v7/palette/README.txt b/v7/palette/README.txt
new file mode 100644
index 0000000..4a8b5e4
--- /dev/null
+++ b/v7/palette/README.txt
@@ -0,0 +1 @@
+Library Project including Palette for color extraction from images
diff --git a/v7/palette/build.gradle b/v7/palette/build.gradle
new file mode 100644
index 0000000..3d195ff
--- /dev/null
+++ b/v7/palette/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'android-library'
+
+archivesBaseName = 'palette-v7'
+
+android {
+    compileSdkVersion 7
+    buildToolsVersion "19.0.1"
+
+    sourceSets {
+        main.manifest.srcFile 'AndroidManifest.xml'
+        main.java.srcDir 'src'
+    }
+}
diff --git a/v7/palette/project.properties b/v7/palette/project.properties
new file mode 100644
index 0000000..1e106c3
--- /dev/null
+++ b/v7/palette/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-7
+android.library=true
\ No newline at end of file
diff --git a/v7/palette/src/android/support/v7/graphics/ColorCutQuantizer.java b/v7/palette/src/android/support/v7/graphics/ColorCutQuantizer.java
new file mode 100644
index 0000000..2e1ce30
--- /dev/null
+++ b/v7/palette/src/android/support/v7/graphics/ColorCutQuantizer.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.graphics;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.util.SparseIntArray;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.PriorityQueue;
+
+/**
+ * An color quantizer based on the Median-cut algorithm, but optimized for picking out distinct
+ * colors rather than representation colors.
+ *
+ * The color space is represented as a 3-dimensional cube with each dimension being an RGB
+ * component. The cube is then repeatedly divided until we have reduced the color space to the
+ * requested number of colors. An average color is then generated from each cube.
+ *
+ * What makes this different to median-cut is that median-cut divided cubes so that all of the cubes
+ * have roughly the same population, where this quantizer divides boxes based on their color volume.
+ * This means that the color space is divided into distinct colors, rather than representative
+ * colors.
+ */
+final class ColorCutQuantizer {
+
+    private static final String LOG_TAG = ColorCutQuantizer.class.getSimpleName();
+
+    private final float[] mTempHsl = new float[3];
+
+    private static final int BLACK_FILTER = 22;
+    private static final int WHITE_FILTER = 237;
+
+    private static final int COMPONENT_RED = -3;
+    private static final int COMPONENT_GREEN = -2;
+    private static final int COMPONENT_BLUE = -1;
+
+    private final int[] mColors;
+    private final SparseIntArray mColorPopulations;
+
+    private final List<PaletteItem> mQuantizedColors;
+
+    /**
+     * Factory-method to generate a {@link ColorCutQuantizer} from a {@link Bitmap} object.
+     *
+     * @param bitmap Bitmap to extract the pixel data from
+     * @param maxColors The maximum number of colors that should be in the result palette.
+     */
+    static ColorCutQuantizer fromBitmap(Bitmap bitmap, int maxColors) {
+        final int width = bitmap.getWidth();
+        final int height = bitmap.getHeight();
+
+        final int[] rgbPixels = new int[width * height];
+        bitmap.getPixels(rgbPixels, 0, width, 0, 0, width, height);
+
+        return new ColorCutQuantizer(rgbPixels, maxColors);
+    }
+
+    /**
+     * Private constructor.
+     *
+     * @param pixels array of rgb packed ints
+     * @param maxColors The maximum number of colors that should be in the result palette.
+     */
+    ColorCutQuantizer(int[] pixels, int maxColors) {
+        final ColorHistogram colorHist = new ColorHistogram(pixels);
+        final int rawColorCount = colorHist.getNumberOfColors();
+        final int[] rawColors = colorHist.getColors();
+        final int[] rawColorCounts = colorHist.getColorCounts();
+
+        // First, lets pack the populations into a SparseIntArray so that they can be easily
+        // retrieved without knowing a color's index
+        mColorPopulations = new SparseIntArray(rawColorCount);
+        for (int i = 0; i < rawColors.length; i++) {
+            mColorPopulations.append(rawColors[i], rawColorCounts[i]);
+        }
+
+        // Now go through all of the colors and keep those which we do not want to ignore
+        mColors = new int[rawColorCount];
+        int validColorCount = 0;
+        for (int color : rawColors) {
+            if (!shouldIgnoreColor(color)) {
+                mColors[validColorCount++] = color;
+            }
+        }
+
+        if (validColorCount <= maxColors) {
+            // The image has fewer colors than the maximum requested, so just return the colors
+            mQuantizedColors = new ArrayList<PaletteItem>();
+            for (final int color : mColors) {
+                mQuantizedColors.add(new PaletteItem(color, mColorPopulations.get(color)));
+            }
+        } else {
+            // We need use quantization to reduce the number of colors
+            mQuantizedColors = quantizePixels(validColorCount - 1, maxColors);
+        }
+    }
+
+    /**
+     * @return the list of quantized colors
+     */
+    List<PaletteItem> getQuantizedColors() {
+        return mQuantizedColors;
+    }
+
+    private List<PaletteItem> quantizePixels(int maxColorIndex, int maxColors) {
+        // Create the priority queue which is sorted by volume descending. This means we always
+        // split the largest box in the queue
+        final PriorityQueue<Vbox> pq = new PriorityQueue<Vbox>(maxColors, VBOX_COMPARATOR_VOLUME);
+
+        // To start, offer a box which contains all of the colors
+        pq.offer(new Vbox(0, maxColorIndex));
+
+        // Now go through the boxes, splitting them until we have reached maxColors or there are no
+        // more boxes to split
+        splitBoxes(pq, maxColors);
+
+        // Finally, return the average colors of the color boxes
+        return generateAverageColors(pq);
+    }
+
+    /**
+     * Iterate through the {@link java.util.Queue}, popping
+     * {@link ColorCutQuantizer.Vbox} objects from the queue
+     * and splitting them. Once split, the new box and the remaining box are offered back to the
+     * queue.
+     *
+     * @param queue {@link java.util.PriorityQueue} to poll for boxes
+     * @param maxSize Maximum amount of boxes to split
+     */
+    private void splitBoxes(final PriorityQueue<Vbox> queue, final int maxSize) {
+        while (queue.size() < maxSize) {
+            final Vbox vbox = queue.poll();
+
+            if (vbox != null && vbox.canSplit()) {
+                // First split the box, and offer the result
+                queue.offer(vbox.splitBox());
+                // Then offer the box back
+                queue.offer(vbox);
+            } else {
+                // If we get here then there are no more boxes to split, so return
+                return;
+            }
+        }
+    }
+
+    private List<PaletteItem> generateAverageColors(Collection<Vbox> vboxes) {
+        ArrayList<PaletteItem> colors = new ArrayList<PaletteItem>(vboxes.size());
+        for (Vbox vbox : vboxes) {
+            PaletteItem color = vbox.getAverageColor();
+            if (!shouldIgnoreColor(color)) {
+                // As we're averaging a color box, we can still get colors which we do not want, so
+                // we check again here
+                colors.add(color);
+            }
+        }
+        return colors;
+    }
+
+    /**
+     * Represents a tightly fitting box around a color space.
+     */
+    private class Vbox {
+        private int lowerIndex;
+        private int upperIndex;
+
+        private int minRed, maxRed;
+        private int minGreen, maxGreen;
+        private int minBlue, maxBlue;
+
+        Vbox(int lowerIndex, int upperIndex) {
+            this.lowerIndex = lowerIndex;
+            this.upperIndex = upperIndex;
+            fitBox();
+        }
+
+        int getVolume() {
+            return (maxRed - minRed + 1) * (maxGreen - minGreen + 1) * (maxBlue - minBlue + 1);
+        }
+
+        boolean canSplit() {
+            return getColorCount() > 1;
+        }
+
+        int getColorCount() {
+            return upperIndex - lowerIndex;
+        }
+
+        /**
+         * Recomputes the boundaries of this box to tightly fit the colors within the box.
+         */
+        void fitBox() {
+            // Reset the min and max to opposite values
+            minRed = minGreen = minBlue = 0xFF;
+            maxRed = maxGreen = maxBlue = 0x0;
+
+            for (int i = lowerIndex; i <= upperIndex; i++) {
+                final int color = mColors[i];
+                int r = Color.red(color);
+                int g = Color.green(color);
+                int b = Color.blue(color);
+                if (r > maxRed) {
+                    maxRed = r;
+                }
+                if (r < minRed) {
+                    minRed = r;
+                }
+                if (g > maxGreen) {
+                    maxGreen = g;
+                }
+                if (g < minGreen) {
+                    minGreen = g;
+                }
+                if (b > maxBlue) {
+                    maxBlue = b;
+                }
+                if (b < minBlue) {
+                    minBlue = b;
+                }
+            }
+        }
+
+        /**
+         * Split this color box at the mid-point along it's longest dimension
+         *
+         * @return the new ColorBox
+         */
+        Vbox splitBox() {
+            if (!canSplit()) {
+                throw new IllegalStateException("Can not split a box with only 1 color");
+            }
+
+            // find median along the longest dimension
+            final int splitPoint = findSplitPoint();
+
+            Vbox newBox = new Vbox(splitPoint + 1, upperIndex);
+
+            // Now change this box's upperIndex and recompute the color boundaries
+            upperIndex = splitPoint;
+            fitBox();
+
+            return newBox;
+        }
+
+        /**
+         * @return the dimension which this box is largest in
+         */
+        int getLongestColorDimension() {
+            final int redLength = maxRed - minRed;
+            final int greenLength = maxGreen - minGreen;
+            final int blueLength = maxBlue - minBlue;
+
+            if (redLength >= greenLength && redLength >= blueLength) {
+                return COMPONENT_RED;
+            } else if (greenLength >= redLength && greenLength >= blueLength) {
+                return COMPONENT_GREEN;
+            } else {
+                return COMPONENT_BLUE;
+            }
+        }
+
+        /**
+         * Finds the point within this box's lowerIndex and upperIndex index of where to split.
+         *
+         * This is calculated by finding the longest color dimension, and then sorting the
+         * sub-array based on that dimension value in each color. The colors are then iterated over
+         * until a color is found with at least the midpoint of the whole box's dimension midpoint.
+         *
+         * @return the index of the colors array to split from
+         */
+        int findSplitPoint() {
+            final int longestDimension = getLongestColorDimension();
+
+            // We need to sort the colors in this box based on the longest color dimension.
+            // As we can't use a Comparator to define the sort logic, we modify each color so that
+            // it's most significant is the desired dimension
+            modifySignificantOctet(longestDimension, lowerIndex, upperIndex);
+
+            // Now sort...
+            Arrays.sort(mColors, lowerIndex, upperIndex + 1);
+
+            // Now revert all of the colors so that they are packed as RGB again
+            modifySignificantOctet(longestDimension, lowerIndex, upperIndex);
+
+            final int dimensionMidPoint = midPoint(longestDimension);
+
+            for (int i = lowerIndex; i < upperIndex; i++)  {
+                final int color = mColors[i];
+
+                switch (longestDimension) {
+                    case COMPONENT_RED:
+                        if (Color.red(color) >= dimensionMidPoint) {
+                            return i;
+                        }
+                        break;
+                    case COMPONENT_GREEN:
+                        if (Color.green(color) >= dimensionMidPoint) {
+                            return i;
+                        }
+                        break;
+                    case COMPONENT_BLUE:
+                        if (Color.blue(color) > dimensionMidPoint) {
+                            return i;
+                        }
+                        break;
+                }
+            }
+
+            return lowerIndex;
+        }
+
+        /**
+         * @return the average color of this box.
+         */
+        PaletteItem getAverageColor() {
+            int redSum = 0;
+            int greenSum = 0;
+            int blueSum = 0;
+            int totalPopulation = 0;
+
+            for (int i = lowerIndex; i <= upperIndex; i++) {
+                final int color = mColors[i];
+                final int colorPopulation = mColorPopulations.get(color);
+
+                totalPopulation += colorPopulation;
+                redSum += colorPopulation * Color.red(color);
+                greenSum += colorPopulation * Color.green(color);
+                blueSum += colorPopulation * Color.blue(color);
+            }
+
+            final int redAverage = Math.round(redSum / (float) totalPopulation);
+            final int greenAverage = Math.round(greenSum / (float) totalPopulation);
+            final int blueAverage = Math.round(blueSum / (float) totalPopulation);
+
+            return new PaletteItem(redAverage, greenAverage, blueAverage, totalPopulation);
+        }
+
+        /**
+         * @return the midpoint of this box in the given {@code dimension}
+         */
+        int midPoint(int dimension) {
+            switch (dimension) {
+                case COMPONENT_RED:
+                default:
+                    return (minRed + maxRed) / 2;
+                case COMPONENT_GREEN:
+                    return (minGreen + maxGreen) / 2;
+                case COMPONENT_BLUE:
+                    return (minBlue + maxBlue) / 2;
+            }
+        }
+    }
+
+    /**
+     * Modify the significant octet in a packed color int. Allows sorting based on the value of a
+     * single color component.
+     *
+     * @see Vbox#findSplitPoint()
+     */
+    private void modifySignificantOctet(final int dimension, int lowIndex, int highIndex) {
+        switch (dimension) {
+            case COMPONENT_RED:
+                // Already in RGB, no need to do anything
+                break;
+            case COMPONENT_GREEN:
+                // We need to do a RGB to GRB swap, or vice-versa
+                for (int i = lowIndex; i <= highIndex; i++) {
+                    final int color = mColors[i];
+                    mColors[i] = Color.rgb((color >> 8) & 0xFF, (color >> 16) & 0xFF, color & 0xFF);
+                }
+                break;
+            case COMPONENT_BLUE:
+                // We need to do a RGB to BGR swap, or vice-versa
+                for (int i = lowIndex; i <= highIndex; i++) {
+                    final int color = mColors[i];
+                    mColors[i] = Color.rgb(color & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF);
+                }
+                break;
+        }
+    }
+
+    private boolean shouldIgnoreColor(PaletteItem color) {
+        return isWhite(color.getRgb()) || isBlack(color.getRgb()) || isSkinTone(color.getRgb());
+    }
+
+    private boolean shouldIgnoreColor(int color) {
+        return isWhite(color) || isBlack(color) || isSkinTone(color);
+    }
+
+    /**
+     * @return true if the color represents a color which is close to black.
+     */
+    private boolean isBlack(int color) {
+        return ((Color.red(color) + Color.green(color) + Color.blue(color)) / 3f) <= BLACK_FILTER;
+    }
+
+    /**
+     * @return true if the color represents a color which is close to white.
+     */
+    private boolean isWhite(int color) {
+        return ((Color.red(color) + Color.green(color) + Color.blue(color)) / 3f) >= WHITE_FILTER;
+    }
+
+    /**
+     * @return true if the color represents a skin tone.
+     */
+    private boolean isSkinTone(int color) {
+        ColorUtils.RGBtoHSL(Color.red(color), Color.green(color), Color.blue(color), mTempHsl);
+        return mTempHsl[0] >= 10f && mTempHsl[0] <= 37f && mTempHsl[1] <= 0.82f;
+    }
+
+    private static final Comparator<Vbox> VBOX_COMPARATOR_VOLUME = new Comparator<Vbox>() {
+        @Override
+        public int compare(Vbox lhs, Vbox rhs) {
+            return rhs.getVolume() - lhs.getVolume();
+        }
+    };
+
+}
diff --git a/v7/palette/src/android/support/v7/graphics/ColorHistogram.java b/v7/palette/src/android/support/v7/graphics/ColorHistogram.java
new file mode 100644
index 0000000..a196f0a
--- /dev/null
+++ b/v7/palette/src/android/support/v7/graphics/ColorHistogram.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.graphics;
+
+import java.util.Arrays;
+
+/**
+ * Class which provides a histogram for RGB values.
+ */
+final class ColorHistogram {
+
+    private final int[] mColors;
+    private final int[] mColorCounts;
+    private final int mNumberColors;
+
+    /**
+     * A new {@link ColorHistogram} instance.
+     *
+     * @param imagePixels array of image contents
+     */
+    ColorHistogram(final int[] imagePixels) {
+        // Lets take a copy of the original pixels
+        final int[] pixels = new int[imagePixels.length];
+        System.arraycopy(imagePixels, 0, pixels, 0, pixels.length);
+
+        // Sort the pixels to enable counting below
+        Arrays.sort(pixels);
+
+        mNumberColors = countDistinctColors(pixels);
+
+        // Create arrays
+        mColors = new int[mNumberColors];
+        mColorCounts = new int[mNumberColors];
+
+        countFrequencies(pixels);
+    }
+
+    /**
+     * @return number of distinct colors in the image.
+     */
+    int getNumberOfColors() {
+        return mNumberColors;
+    }
+
+    /**
+     * @return an array containing all of the distinct colors in the image.
+     */
+    int[] getColors() {
+        return mColors;
+    }
+
+    /**
+     * @return an array containing the frequency of a distinct colors within the image.
+     */
+    int[] getColorCounts() {
+        return mColorCounts;
+    }
+
+    static int countDistinctColors(final int[] pixels) {
+        if (pixels.length == 0) {
+            return 0;
+        }
+
+        // If we have at least 1 pixel, we have a minimum of 1 color
+        int colorCount = 1;
+        int currentColor = pixels[0];
+
+        // Now iterate from the second pixel to the end, population distinct colors
+        for (int i = 1; i < pixels.length; i++) {
+            // If we encounter a new color, increase the population
+            if (pixels[i] != currentColor) {
+                currentColor = pixels[i];
+                colorCount++;
+            }
+        }
+
+        return colorCount;
+    }
+
+    private void countFrequencies(final int[] pixels) {
+        if (pixels.length == 0) {
+            return;
+        }
+
+        int currentColorIndex = 0;
+        int currentColor = pixels[0];
+
+        mColors[currentColorIndex] = currentColor;
+        mColorCounts[currentColorIndex] = 1;
+
+        // Now iterate from the second pixel to the end, population distinct colors
+        for (int i = 1; i < pixels.length; i++) {
+            if (pixels[i] == currentColor) {
+                // We've hit the same color as before, increase population
+                mColorCounts[currentColorIndex]++;
+            } else {
+                // We've hit a new color, increase index
+                currentColor = pixels[i];
+
+                currentColorIndex++;
+                mColors[currentColorIndex] = currentColor;
+                mColorCounts[currentColorIndex] = 1;
+            }
+        }
+    }
+
+}
diff --git a/v7/palette/src/android/support/v7/graphics/ColorUtils.java b/v7/palette/src/android/support/v7/graphics/ColorUtils.java
new file mode 100644
index 0000000..34b075e
--- /dev/null
+++ b/v7/palette/src/android/support/v7/graphics/ColorUtils.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.graphics;
+
+import android.graphics.Color;
+
+final class ColorUtils {
+
+    private ColorUtils() {}
+
+    /**
+     * @return luma value according to to XYZ color space in the range 0.0 - 1.0
+     */
+    static float calculateXyzLuma(int color) {
+        return (0.2126f * Color.red(color) +
+                0.7152f * Color.green(color) +
+                0.0722f * Color.blue(color)) / 255f;
+    }
+
+    static float calculateContrast(int color1, int color2) {
+        return Math.abs(ColorUtils.calculateXyzLuma(color1) - ColorUtils.calculateXyzLuma(color2));
+    }
+
+    static void RGBtoHSL(int r, int g, int b, float[] hsl) {
+        final float rf = r / 255f;
+        final float gf = g / 255f;
+        final float bf = b / 255f;
+
+        final float max = Math.max(rf, Math.max(gf, bf));
+        final float min = Math.min(rf, Math.min(gf, bf));
+        final float deltaMaxMin = max - min;
+
+        float h, s;
+        float l = (max + min) / 2f;
+
+        if (max == min) {
+            // Monochromatic
+            h = s = 0f;
+        } else {
+            if (max == rf) {
+                h = ((gf - bf) / deltaMaxMin) % 6f;
+            } else if (max == gf) {
+                h = ((bf - rf) / deltaMaxMin) + 2f;
+            } else {
+                h = ((rf - gf) / deltaMaxMin) + 4f;
+            }
+
+            s =  deltaMaxMin / (1f - Math.abs(2f * l - 1f));
+        }
+
+        hsl[0] = (h * 60f) % 360f;
+        hsl[1] = s;
+        hsl[2] = l;
+    }
+
+    static int HSLtoRGB (float[] hsl) {
+        final float h = hsl[0];
+        final float s = hsl[1];
+        final float l = hsl[2];
+
+        final float c = (1f - Math.abs(2 * l - 1f)) * s;
+        final float m = l - 0.5f * c;
+        final float x = c * (1f - Math.abs((h / 60f % 2f) - 1f));
+
+        final int hueSegment = (int) h / 60;
+
+        int r = 0, g = 0, b = 0;
+
+        switch (hueSegment) {
+            case 0:
+                r = Math.round(255 * (c + m));
+                g = Math.round(255 * (x + m));
+                b = Math.round(255 * m);
+                break;
+            case 1:
+                r = Math.round(255 * (x + m));
+                g = Math.round(255 * (c + m));
+                b = Math.round(255 * m);
+                break;
+            case 2:
+                r = Math.round(255 * m);
+                g = Math.round(255 * (c + m));
+                b = Math.round(255 * (x + m));
+                break;
+            case 3:
+                r = Math.round(255 * m);
+                g = Math.round(255 * (x + m));
+                b = Math.round(255 * (c + m));
+                break;
+            case 4:
+                r = Math.round(255 * (x + m));
+                g = Math.round(255 * m);
+                b = Math.round(255 * (c + m));
+                break;
+            case 5:
+            case 6:
+                r = Math.round(255 * (c + m));
+                g = Math.round(255 * m);
+                b = Math.round(255 * (x + m));
+                break;
+        }
+
+        r = Math.max(0, Math.min(255, r));
+        g = Math.max(0, Math.min(255, g));
+        b = Math.max(0, Math.min(255, b));
+
+        return Color.rgb(r, g, b);
+    }
+
+}
diff --git a/v7/palette/src/android/support/v7/graphics/Palette.java b/v7/palette/src/android/support/v7/graphics/Palette.java
new file mode 100644
index 0000000..9e57760
--- /dev/null
+++ b/v7/palette/src/android/support/v7/graphics/Palette.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.graphics;
+
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A helper class to extract prominent colors from an image.
+ * <p>
+ * A number of colors with different profiles are extracted from the image:
+ * <ul>
+ *     <li>Vibrant</li>
+ *     <li>Vibrant Dark</li>
+ *     <li>Vibrant Light</li>
+ *     <li>Muted</li>
+ *     <li>Muted Dark</li>
+ *     <li>Muted Light</li>
+ * </ul>
+ * These can be retrieved from the appropriate getter method.
+ *
+ * <p>
+ * Instances can be created with the synchronous factory methods {@link #generate(Bitmap)} and
+ * {@link #generate(Bitmap, int)}.
+ * <p>
+ * These should be called on a background thread, ideally the one in
+ * which you load your images on. Sometimes that is not possible, so asynchronous factory methods
+ * have also been provided: {@link #generateAsync(Bitmap, PaletteAsyncListener)} and
+ * {@link #generateAsync(Bitmap, int, PaletteAsyncListener)}. These can be used as so:
+ *
+ * <pre>
+ * Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
+ *     @Override
+ *     public void onGenerated(Palette palette) {
+ *         // Do something with colors...
+ *     }
+ * });
+ * </pre>
+ */
+public final class Palette {
+
+    /**
+     * Listener to be used with {@link #generateAsync(Bitmap, PaletteAsyncListener)} or
+     * {@link #generateAsync(Bitmap, int, PaletteAsyncListener)}
+     */
+    public interface PaletteAsyncListener {
+
+        /**
+         * Called when the {@link Palette} has been generated.
+         */
+        void onGenerated(Palette palette);
+    }
+
+    private static final int CALCULATE_BITMAP_MIN_DIMENSION = 100;
+    private static final int DEFAULT_CALCULATE_NUMBER_COLORS = 16;
+
+    private static final float TARGET_DARK_LUMA = 0.26f;
+    private static final float MAX_DARK_LUMA = 0.45f;
+
+    private static final float MIN_LIGHT_LUMA = 0.55f;
+    private static final float TARGET_LIGHT_LUMA = 0.74f;
+
+    private static final float MIN_NORMAL_LUMA = 0.3f;
+    private static final float TARGET_NORMAL_LUMA = 0.5f;
+    private static final float MAX_NORMAL_LUMA = 0.7f;
+
+    private static final float TARGET_MUTED_SATURATION = 0.3f;
+    private static final float MAX_MUTED_SATURATION = 0.4f;
+
+    private static final float TARGET_VIBRANT_SATURATION = 1f;
+    private static final float MIN_VIBRANT_SATURATION = 0.35f;
+
+    private final List<PaletteItem> mPallete;
+    private final int mHighestPopulation;
+
+    private PaletteItem mVibrantColor;
+    private PaletteItem mMutedColor;
+
+    private PaletteItem mDarkVibrantColor;
+    private PaletteItem mDarkMutedColor;
+
+    private PaletteItem mLightVibrantColor;
+    private PaletteItem mLightMutedColor;
+
+    /**
+     * Generate a {@link Palette} from a {@link Bitmap} using the default number of colors.
+     */
+    public static Palette generate(Bitmap bitmap) {
+        return generate(bitmap, DEFAULT_CALCULATE_NUMBER_COLORS);
+    }
+
+    /**
+     * Generate a {@link Palette} from a {@link Bitmap} using the specified {@code numColors}.
+     * Good values for {@code numColors} depend on the source image type.
+     * For landscapes, a good values are in the range 12-16. For images which are largely made up
+     * of people's faces then this value should be increased to 24-32.
+     *
+     * @param numColors The maximum number of colors in the generated palette. Increasing this
+     *                  number will increase the time needed to compute the values.
+     */
+    public static Palette generate(Bitmap bitmap, int numColors) {
+        if (bitmap == null) {
+            throw new IllegalArgumentException("bitmap can not be null");
+        }
+
+        // First we'll scale down the bitmap so it's shortest dimension is 100px
+        final Bitmap scaledBitmap = scaleBitmapDown(bitmap);
+
+        // Now generate a quantizer from the Bitmap
+        ColorCutQuantizer quantizer = ColorCutQuantizer.fromBitmap(scaledBitmap, numColors);
+
+        // If created a new bitmap, recycle it
+        if (scaledBitmap != bitmap) {
+            scaledBitmap.recycle();
+        }
+
+        // Now return a ColorExtractor instance
+        return new Palette(quantizer.getQuantizedColors());
+    }
+
+    /**
+     * Generate a {@link Palette} asynchronously. {@link PaletteAsyncListener#onGenerated(Palette)}
+     * will be called with the created instance. The resulting {@link Palette} is the same as
+     * what would be created by calling {@link #generate(Bitmap)}.
+     *
+     * @param listener Listener to be invoked when the {@link Palette} has been generated.
+     *
+     * @return the {@link android.os.AsyncTask} used to asynchronously generate the instance.
+     */
+    public static AsyncTask<Void, Void, Palette> generateAsync(
+            Bitmap bitmap, PaletteAsyncListener listener) {
+        return generateAsync(bitmap, DEFAULT_CALCULATE_NUMBER_COLORS, listener);
+    }
+
+    /**
+     * Generate a {@link Palette} asynchronously. {@link PaletteAsyncListener#onGenerated(Palette)}
+     * will be called with the created instance. The resulting {@link Palette} is the same as what
+     * would be created by calling {@link #generate(Bitmap, int)}.
+     *
+     * @param listener Listener to be invoked when the {@link Palette} has been generated.
+     *
+     * @return the {@link android.os.AsyncTask} used to asynchronously generate the instance.
+     */
+    public static AsyncTask<Void, Void, Palette> generateAsync(
+            final Bitmap bitmap, final int numColors, final PaletteAsyncListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener can not be null");
+        }
+
+        AsyncTask<Void, Void, Palette> task = new AsyncTask<Void, Void, Palette>() {
+            @Override
+            protected Palette doInBackground(Void... voids) {
+                return generate(bitmap, numColors);
+            }
+
+            @Override
+            protected void onPostExecute(Palette colorExtractor) {
+                super.onPostExecute(colorExtractor);
+                listener.onGenerated(colorExtractor);
+            }
+        };
+        task.execute();
+        return task;
+    }
+
+    private Palette(List<PaletteItem> palette) {
+        mPallete = palette;
+        mHighestPopulation = findMaxPopulation();
+
+        mVibrantColor = findColor(TARGET_NORMAL_LUMA, MIN_NORMAL_LUMA, MAX_NORMAL_LUMA,
+                TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f);
+
+        mLightVibrantColor = findColor(TARGET_LIGHT_LUMA, MIN_LIGHT_LUMA, 1f,
+                TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f);
+
+        mDarkVibrantColor = findColor(TARGET_DARK_LUMA, 0f, MAX_DARK_LUMA,
+                TARGET_VIBRANT_SATURATION, MIN_VIBRANT_SATURATION, 1f);
+
+        mMutedColor = findColor(TARGET_NORMAL_LUMA, MIN_NORMAL_LUMA, MAX_NORMAL_LUMA,
+                TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION);
+
+        mLightMutedColor = findColor(TARGET_LIGHT_LUMA, MIN_LIGHT_LUMA, 1f,
+                TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION);
+
+        mDarkMutedColor = findColor(TARGET_DARK_LUMA, 0f, MAX_DARK_LUMA,
+                TARGET_MUTED_SATURATION, 0f, MAX_MUTED_SATURATION);
+
+        // Now try and generate any missing colors
+        generateEmptyColors();
+    }
+
+    /**
+     * The total palette of colors which make up the image.
+     */
+    public List<PaletteItem> getPallete() {
+        return Collections.unmodifiableList(mPallete);
+    }
+
+    /**
+     * Returns the most vibrant color in the image. Might be null.
+     */
+    public PaletteItem getVibrantColor() {
+        return mVibrantColor;
+    }
+
+    /**
+     * Returns a light and vibrant color from the image. Might be null.
+     */
+    public PaletteItem getLightVibrantColor() {
+        return mLightVibrantColor;
+    }
+
+    /**
+     * Returns a dark and vibrant color from the image. Might be null.
+     */
+    public PaletteItem getDarkVibrantColor() {
+        return mDarkVibrantColor;
+    }
+
+    /**
+     * Returns a muted color from the image. Might be null.
+     */
+    public PaletteItem getMutedColor() {
+        return mMutedColor;
+    }
+
+    /**
+     * Returns a muted and light color from the image. Might be null.
+     */
+    public PaletteItem getLightMutedColor() {
+        return mLightMutedColor;
+    }
+
+    /**
+     * Returns a muted and dark color from the image. Might be null.
+     */
+    public PaletteItem getDarkMutedColor() {
+        return mDarkMutedColor;
+    }
+
+    /**
+     * @return true if we have already selected {@code item}
+     */
+    private boolean isAlreadySelected(PaletteItem item) {
+        return mVibrantColor == item || mDarkVibrantColor == item || mLightVibrantColor == item ||
+                mMutedColor == item || mDarkMutedColor == item || mLightMutedColor == item;
+    }
+
+    private PaletteItem findColor(float targetLuma, float minLuma, float maxLuma,
+                                float targetSaturation, float minSaturation, float maxSaturation) {
+        PaletteItem max = null;
+        float maxValue = 0f;
+
+        for (PaletteItem paletteItem : mPallete) {
+            final float sat = paletteItem.getHsl()[1];
+            final float luma = paletteItem.getHsl()[2];
+
+            if (sat >= minSaturation && sat <= maxSaturation &&
+                    luma >= minLuma && luma <= maxLuma &&
+                    !isAlreadySelected(paletteItem)) {
+                float thisValue = createComparisonValue(sat, targetSaturation, luma, targetLuma,
+                        paletteItem.getPopulation(), mHighestPopulation);
+                if (max == null || thisValue > maxValue) {
+                    max = paletteItem;
+                    maxValue = thisValue;
+                }
+            }
+        }
+
+        return max;
+    }
+
+    /**
+     * Try and generate any missing colors from the colors we did find.
+     */
+    private void generateEmptyColors() {
+        if (mVibrantColor == null) {
+            // If we do not have a vibrant color...
+            if (mDarkVibrantColor != null) {
+                // ...but we do have a dark vibrant, generate the value by modifying the luma
+                final float[] newHsl = copyHslValues(mDarkVibrantColor);
+                newHsl[2] = TARGET_NORMAL_LUMA;
+                mVibrantColor = new PaletteItem(ColorUtils.HSLtoRGB(newHsl), 0);
+            }
+        }
+
+        if (mDarkVibrantColor == null) {
+            // If we do not have a dark vibrant color...
+            if (mVibrantColor != null) {
+                // ...but we do have a vibrant, generate the value by modifying the luma
+                final float[] newHsl = copyHslValues(mVibrantColor);
+                newHsl[2] = TARGET_DARK_LUMA;
+                mDarkVibrantColor = new PaletteItem(ColorUtils.HSLtoRGB(newHsl), 0);
+            }
+        }
+    }
+
+    /**
+     * Find the {@link PaletteItem} with the highest population value and return the population.
+     */
+    private int findMaxPopulation() {
+        int population = 0;
+        for (PaletteItem item : mPallete) {
+            population = Math.max(population, item.getPopulation());
+        }
+        return population;
+    }
+
+    /**
+     * Scale the bitmap down so that it's smallest dimension is
+     * {@value #CALCULATE_BITMAP_MIN_DIMENSION}px. If {@code bitmap} is smaller than this, than it
+     * is returned.
+     */
+    private static Bitmap scaleBitmapDown(Bitmap bitmap) {
+        final int minDimension = Math.min(bitmap.getWidth(), bitmap.getHeight());
+
+        if (minDimension <= CALCULATE_BITMAP_MIN_DIMENSION) {
+            // If the bitmap is small enough already, just return it
+            return bitmap;
+        }
+
+        final float scaleRatio = CALCULATE_BITMAP_MIN_DIMENSION / (float) minDimension;
+        return Bitmap.createScaledBitmap(bitmap,
+                Math.round(bitmap.getWidth() * scaleRatio),
+                Math.round(bitmap.getHeight() * scaleRatio),
+                false);
+    }
+
+    private static float createComparisonValue(float saturation, float targetSaturation,
+            float luma, float targetLuma,
+            int population, int highestPopulation) {
+        return weightedMean(
+                invertDiff(saturation, targetSaturation), 3f,
+                invertDiff(luma, targetLuma), 6.5f,
+                population / (float) highestPopulation, 0.5f
+        );
+    }
+
+    /**
+     * Copy a {@link PaletteItem}'s HSL values into a new float[].
+     */
+    private static float[] copyHslValues(PaletteItem color) {
+        final float[] newHsl = new float[3];
+        System.arraycopy(color.getHsl(), 0, newHsl, 0, 3);
+        return newHsl;
+    }
+
+    /**
+     * Returns a value in the range 0-1. 1 is returned when {@code value} equals the
+     * {@code targetValue} and then decreases as the absolute difference between {@code value} and
+     * {@code targetValue} increases.
+     *
+     * @param value the item's value
+     * @param targetValue the value which we desire
+     */
+    private static float invertDiff(float value, float targetValue) {
+        return 1f - Math.abs(value - targetValue);
+    }
+
+    private static float weightedMean(float... values) {
+        float sum = 0f;
+        float sumWeight = 0f;
+
+        for (int i = 0; i < values.length; i += 2) {
+            float value = values[i];
+            float weight = values[i + 1];
+
+            sum += (value * weight);
+            sumWeight += weight;
+        }
+
+        return sum / sumWeight;
+    }
+
+}
diff --git a/v7/palette/src/android/support/v7/graphics/PaletteItem.java b/v7/palette/src/android/support/v7/graphics/PaletteItem.java
new file mode 100644
index 0000000..ce73059
--- /dev/null
+++ b/v7/palette/src/android/support/v7/graphics/PaletteItem.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.graphics;
+
+import android.graphics.Color;
+
+import java.util.Arrays;
+
+/**
+ * Represents a color generated from an image's palette. The RGB color can be retrieved by
+ * calling {@link #getRgb()}.
+ */
+public final class PaletteItem {
+
+    final int red, green, blue;
+    final int rgb;
+    final int population;
+
+    private float[] hsl;
+
+    PaletteItem(int rgbColor, int population) {
+        this.red = Color.red(rgbColor);
+        this.green = Color.green(rgbColor);
+        this.blue = Color.blue(rgbColor);
+        this.rgb = rgbColor;
+        this.population = population;
+    }
+
+    PaletteItem(int red, int green, int blue, int population) {
+        this.red = red;
+        this.green = green;
+        this.blue = blue;
+        this.rgb = Color.rgb(red, green, blue);
+        this.population = population;
+    }
+
+    /**
+     * @return this item's RGB color value
+     */
+    public int getRgb() {
+        return rgb;
+    }
+
+    /**
+     * Return this item's HSL values.
+     *     hsv[0] is Hue [0 .. 360)
+     *     hsv[1] is Saturation [0...1]
+     *     hsv[2] is Lightness [0...1]
+     */
+    public float[] getHsl() {
+        if (hsl == null) {
+            // Lazily generate HSL values from RGB
+            hsl = new float[3];
+            ColorUtils.RGBtoHSL(red, green, blue, hsl);
+        }
+        return hsl;
+    }
+
+    /**
+     * @return the number of pixels represented by this color
+     */
+    int getPopulation() {
+        return population;
+    }
+
+    public String toString() {
+        return new StringBuilder(getClass().getSimpleName()).append(" ")
+                .append("[").append(Integer.toHexString(getRgb())).append(']')
+                .append("[HSL: ").append(Arrays.toString(getHsl())).append(']')
+                .append("[Population: ").append(population).append(']').toString();
+    }
+}
