diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..219c63c
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="volley" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/custom_rules.xml b/custom_rules.xml
new file mode 100644
index 0000000..1b94e5d
--- /dev/null
+++ b/custom_rules.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="volley-rules" default="help">
+
+  <!-- A rule to generate the JAR for inclusion in an Android
+       application. Output file will be bin/volley.jar -->
+  <target name="jar" depends="-compile">
+    <jar destfile="bin/volley.jar"
+         basedir="bin/classes" />
+  </target>
+</project>
diff --git a/proguard-project.txt b/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/project.properties b/project.properties
index 730e911..28341e2 100644
--- a/project.properties
+++ b/project.properties
@@ -9,3 +9,7 @@
 
 # Project target.
 target=android-14
+
+# Make sure to pass a valid value to renderscript
+# https://code.google.com/p/android/issues/detail?id=40487
+renderscript.opt.level=O0
diff --git a/src/com/android/volley/toolbox/DiskBasedCache.java b/src/com/android/volley/toolbox/DiskBasedCache.java
index 75bf4d1..9559a02 100644
--- a/src/com/android/volley/toolbox/DiskBasedCache.java
+++ b/src/com/android/volley/toolbox/DiskBasedCache.java
@@ -456,8 +456,8 @@
                     ? Collections.<String, String>emptyMap()
                     : new HashMap<String, String>(size);
             for (int i = 0; i < size; i++) {
-                String key = ois.readUTF();
-                String value = ois.readUTF();
+                String key = ois.readUTF().intern();
+                String value = ois.readUTF().intern();
                 result.put(key, value);
             }
             return result;
diff --git a/src/com/android/volley/toolbox/HurlStack.java b/src/com/android/volley/toolbox/HurlStack.java
index bbfb12a..97f94f0 100644
--- a/src/com/android/volley/toolbox/HurlStack.java
+++ b/src/com/android/volley/toolbox/HurlStack.java
@@ -146,13 +146,20 @@
     }
 
     /**
+     * Create an {@link HttpURLConnection} for the specified {@code url}.
+     */
+    protected HttpURLConnection createConnection(URL url) throws IOException {
+        return (HttpURLConnection) url.openConnection();
+    }
+
+    /**
      * Opens an {@link HttpURLConnection} with parameters.
      * @param url
      * @return an open connection
      * @throws IOException
      */
     private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException {
-        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        HttpURLConnection connection = createConnection(url);
 
         int timeoutMs = request.getTimeoutMs();
         connection.setConnectTimeout(timeoutMs);
diff --git a/src/com/android/volley/toolbox/ImageLoader.java b/src/com/android/volley/toolbox/ImageLoader.java
new file mode 100755
index 0000000..5735edd
--- /dev/null
+++ b/src/com/android/volley/toolbox/ImageLoader.java
@@ -0,0 +1,461 @@
+/**
+ * Copyright (C) 2013 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 com.android.volley.toolbox;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.os.Handler;
+import android.os.Looper;
+import android.widget.ImageView;
+
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response.ErrorListener;
+import com.android.volley.Response.Listener;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.ImageRequest;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+/**
+ * Helper that handles loading and caching images from remote URLs.
+ *
+ * The simple way to use this class is to call {@link ImageLoader#get(String, ImageListener)}
+ * and to pass in the default image listener provided by
+ * {@link ImageLoader#getImageListener(ImageView, int, int)}. Note that all function calls to
+ * this class must be made from the main thead, and all responses will be delivered to the main
+ * thread as well.
+ */
+public class ImageLoader {
+    /** RequestQueue for dispatching ImageRequests onto. */
+    private final RequestQueue mRequestQueue;
+
+    /** Amount of time to wait after first response arrives before delivering all responses. */
+    private int mBatchResponseDelayMs = 100;
+
+    /** The cache implementation to be used as an L1 cache before calling into volley. */
+    private final ImageCache mCache;
+
+    /**
+     * HashMap of Cache keys -> BatchedImageRequest used to track in-flight requests so
+     * that we can coalesce multiple requests to the same URL into a single network request.
+     */
+    private final HashMap<String, BatchedImageRequest> mInFlightRequests =
+            new HashMap<String, BatchedImageRequest>();
+
+    /** HashMap of the currently pending responses (waiting to be delivered). */
+    private final HashMap<String, BatchedImageRequest> mBatchedResponses =
+            new HashMap<String, BatchedImageRequest>();
+
+    /** Handler to the main thread. */
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    /** Runnable for in-flight response delivery. */
+    private Runnable mRunnable;
+
+    /**
+     * Simple cache adapter interface. If provided to the ImageLoader, it
+     * will be used as an L1 cache before dispatch to Volley. Implementations
+     * must not block. Implementation with an LruCache is recommended.
+     */
+    public interface ImageCache {
+        public Bitmap getBitmap(String url);
+        public void putBitmap(String url, Bitmap bitmap);
+    }
+
+    /**
+     * Constructs a new ImageLoader.
+     * @param queue The RequestQueue to use for making image requests.
+     * @param imageCache The cache to use as an L1 cache.
+     */
+    public ImageLoader(RequestQueue queue, ImageCache imageCache) {
+        mRequestQueue = queue;
+        mCache = imageCache;
+    }
+
+    /**
+     * The default implementation of ImageListener which handles basic functionality
+     * of showing a default image until the network response is received, at which point
+     * it will switch to either the actual image or the error image.
+     * @param imageView The imageView that the listener is associated with.
+     * @param defaultImageResId Default image resource ID to use, or 0 if it doesn't exist.
+     * @param errorImageResId Error image resource ID to use, or 0 if it doesn't exist.
+     */
+    public static ImageListener getImageListener(final ImageView view,
+            final int defaultImageResId, final int errorImageResId) {
+        return new ImageListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+                if (errorImageResId != 0) {
+                    view.setImageResource(errorImageResId);
+                }
+            }
+
+            @Override
+            public void onResponse(ImageContainer response, boolean isImmediate) {
+                if (response.getBitmap() != null) {
+                    view.setImageBitmap(response.getBitmap());
+                } else if (defaultImageResId != 0) {
+                    view.setImageResource(defaultImageResId);
+                }
+            }
+        };
+    }
+
+    /**
+     * Interface for the response handlers on image requests.
+     *
+     * The call flow is this:
+     * 1. Upon being  attached to a request, onResponse(response, true) will
+     * be invoked to reflect any cached data that was already available. If the
+     * data was available, response.getBitmap() will be non-null.
+     *
+     * 2. After a network response returns, only one of the following cases will happen:
+     *   - onResponse(response, false) will be called if the image was loaded.
+     *   or
+     *   - onErrorResponse will be called if there was an error loading the image.
+     */
+    public interface ImageListener extends ErrorListener {
+        /**
+         * Listens for non-error changes to the loading of the image request.
+         *
+         * @param response Holds all information pertaining to the request, as well
+         * as the bitmap (if it is loaded).
+         * @param isImmediate True if this was called during ImageLoader.get() variants.
+         * This can be used to differentiate between a cached image loading and a network
+         * image loading in order to, for example, run an animation to fade in network loaded
+         * images.
+         */
+        public void onResponse(ImageContainer response, boolean isImmediate);
+    }
+
+    /**
+     * Checks if the item is available in the cache.
+     * @param requestUrl The url of the remote image
+     * @param maxWidth The maximum width of the returned image.
+     * @param maxHeight The maximum height of the returned image.
+     * @return True if the item exists in cache, false otherwise.
+     */
+    public boolean isCached(String requestUrl, int maxWidth, int maxHeight) {
+        throwIfNotOnMainThread();
+
+        String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight);
+        return mCache.getBitmap(cacheKey) != null;
+    }
+
+    /**
+     * Returns an ImageContainer for the requested URL.
+     *
+     * The ImageContainer will contain either the specified default bitmap or the loaded bitmap.
+     * If the default was returned, the {@link ImageLoader} will be invoked when the
+     * request is fulfilled.
+     *
+     * @param requestUrl The URL of the image to be loaded.
+     * @param defaultImage Optional default image to return until the actual image is loaded.
+     */
+    public ImageContainer get(String requestUrl, final ImageListener listener) {
+        return get(requestUrl, listener, 0, 0);
+    }
+
+    /**
+     * Issues a bitmap request with the given URL if that image is not available
+     * in the cache, and returns a bitmap container that contains all of the data
+     * relating to the request (as well as the default image if the requested
+     * image is not available).
+     * @param requestUrl The url of the remote image
+     * @param imageListener The listener to call when the remote image is loaded
+     * @param maxWidth The maximum width of the returned image.
+     * @param maxHeight The maximum height of the returned image.
+     * @return A container object that contains all of the properties of the request, as well as
+     *     the currently available image (default if remote is not loaded).
+     */
+    public ImageContainer get(String requestUrl, ImageListener imageListener,
+            int maxWidth, int maxHeight) {
+        // only fulfill requests that were initiated from the main thread.
+        throwIfNotOnMainThread();
+
+        final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight);
+
+        // Try to look up the request in the cache of remote images.
+        Bitmap cachedBitmap = mCache.getBitmap(cacheKey);
+        if (cachedBitmap != null) {
+            // Return the cached bitmap.
+            ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null);
+            imageListener.onResponse(container, true);
+            return container;
+        }
+
+        // The bitmap did not exist in the cache, fetch it!
+        ImageContainer imageContainer =
+                new ImageContainer(null, requestUrl, cacheKey, imageListener);
+
+        // Update the caller to let them know that they should use the default bitmap.
+        imageListener.onResponse(imageContainer, true);
+
+        // Check to see if a request is already in-flight.
+        BatchedImageRequest request = mInFlightRequests.get(cacheKey);
+        if (request != null) {
+            // If it is, add this request to the list of listeners.
+            request.addContainer(imageContainer);
+            return imageContainer;
+        }
+
+        // The request is not already in flight. Send the new request to the network and
+        // track it.
+        Request<?> newRequest =
+            new ImageRequest(requestUrl, new Listener<Bitmap>() {
+                @Override
+                public void onResponse(Bitmap response) {
+                    onGetImageSuccess(cacheKey, response);
+                }
+            }, maxWidth, maxHeight,
+            Config.RGB_565, new ErrorListener() {
+                @Override
+                public void onErrorResponse(VolleyError error) {
+                    onGetImageError(cacheKey, error);
+                }
+            });
+
+        mRequestQueue.add(newRequest);
+        mInFlightRequests.put(cacheKey,
+                new BatchedImageRequest(newRequest, imageContainer));
+        return imageContainer;
+    }
+
+    /**
+     * Sets the amount of time to wait after the first response arrives before delivering all
+     * responses. Batching can be disabled entirely by passing in 0.
+     * @param newBatchedResponseDelayMs The time in milliseconds to wait.
+     */
+    public void setBatchedResponseDelay(int newBatchedResponseDelayMs) {
+        mBatchResponseDelayMs = newBatchedResponseDelayMs;
+    }
+
+    /**
+     * Handler for when an image was successfully loaded.
+     * @param cacheKey The cache key that is associated with the image request.
+     * @param response The bitmap that was returned from the network.
+     */
+    private void onGetImageSuccess(String cacheKey, Bitmap response) {
+        // cache the image that was fetched.
+        mCache.putBitmap(cacheKey, response);
+
+        // remove the request from the list of in-flight requests.
+        BatchedImageRequest request = mInFlightRequests.remove(cacheKey);
+
+        if (request != null) {
+            // Update the response bitmap.
+            request.mResponseBitmap = response;
+
+            // Send the batched response
+            batchResponse(cacheKey, request, null);
+        }
+    }
+
+    /**
+     * Handler for when an image failed to load.
+     * @param cacheKey The cache key that is associated with the image request.
+     */
+    private void onGetImageError(String cacheKey, VolleyError error) {
+        // Notify the requesters that something failed via a null result.
+        // Remove this request from the list of in-flight requests.
+        BatchedImageRequest request = mInFlightRequests.remove(cacheKey);
+
+        if (request != null) {
+            // Send the batched response
+            batchResponse(cacheKey, request, error);
+        }
+    }
+
+    /**
+     * Container object for all of the data surrounding an image request.
+     */
+    public class ImageContainer {
+        /**
+         * The most relevant bitmap for the container. If the image was in cache, the
+         * Holder to use for the final bitmap (the one that pairs to the requested URL).
+         */
+        private Bitmap mBitmap;
+
+        private final ImageListener mListener;
+
+        /** The cache key that was associated with the request */
+        private final String mCacheKey;
+
+        /** The request URL that was specified */
+        private final String mRequestUrl;
+
+        /**
+         * Constructs a BitmapContainer object.
+         * @param bitmap The final bitmap (if it exists).
+         * @param requestUrl The requested URL for this container.
+         * @param cacheKey The cache key that identifies the requested URL for this container.
+         */
+        public ImageContainer(Bitmap bitmap, String requestUrl,
+                String cacheKey, ImageListener listener) {
+            mBitmap = bitmap;
+            mRequestUrl = requestUrl;
+            mCacheKey = cacheKey;
+            mListener = listener;
+        }
+
+        /**
+         * Releases interest in the in-flight request (and cancels it if no one else is listening).
+         */
+        public void cancelRequest() {
+            if (mListener == null) {
+                return;
+            }
+
+            BatchedImageRequest request = mInFlightRequests.get(mCacheKey);
+            if (request != null) {
+                boolean canceled = request.removeContainerAndCancelIfNecessary(this);
+                if (canceled) {
+                    mInFlightRequests.remove(mCacheKey);
+                }
+            } else {
+                // check to see if it is already batched for delivery.
+                request = mBatchedResponses.get(mCacheKey);
+                if (request != null) {
+                    request.removeContainerAndCancelIfNecessary(this);
+                    if (request.mContainers.size() == 0) {
+                        mBatchedResponses.remove(mCacheKey);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Returns the bitmap associated with the request URL if it has been loaded, null otherwise.
+         */
+        public Bitmap getBitmap() {
+            return mBitmap;
+        }
+
+        /**
+         * Returns the requested URL for this container.
+         */
+        public String getRequestUrl() {
+            return mRequestUrl;
+        }
+    }
+
+    /**
+     * Wrapper class used to map a Request to the set of active ImageContainer objects that are
+     * interested in its results.
+     */
+    private class BatchedImageRequest {
+        /** The request being tracked */
+        private final Request<?> mRequest;
+
+        /** The result of the request being tracked by this item */
+        private Bitmap mResponseBitmap;
+
+        /** List of all of the active ImageContainers that are interested in the request */
+        private final LinkedList<ImageContainer> mContainers = new LinkedList<ImageContainer>();
+
+        /**
+         * Constructs a new BatchedImageRequest object
+         * @param request The request being tracked
+         * @param container The ImageContainer of the person who initiated the request.
+         */
+        public BatchedImageRequest(Request<?> request, ImageContainer container) {
+            mRequest = request;
+            mContainers.add(container);
+        }
+
+        /**
+         * Adds another ImageContainer to the list of those interested in the results of
+         * the request.
+         */
+        public void addContainer(ImageContainer container) {
+            mContainers.add(container);
+        }
+
+        /**
+         * Detatches the bitmap container from the request and cancels the request if no one is
+         * left listening.
+         * @param container The container to remove from the list
+         * @return True if the request was canceled, false otherwise.
+         */
+        public boolean removeContainerAndCancelIfNecessary(ImageContainer container) {
+            mContainers.remove(container);
+            if (mContainers.size() == 0) {
+                mRequest.cancel();
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Starts the runnable for batched delivery of responses if it is not already started.
+     * @param cacheKey The cacheKey of the response being delivered.
+     * @param request The BatchedImageRequest to be delivered.
+     * @param error The volley error associated with the request (if applicable).
+     */
+    private void batchResponse(String cacheKey, BatchedImageRequest request,
+            final VolleyError error) {
+        mBatchedResponses.put(cacheKey, request);
+        // If we don't already have a batch delivery runnable in flight, make a new one.
+        // Note that this will be used to deliver responses to all callers in mBatchedResponses.
+        if (mRunnable == null) {
+            mRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    for (BatchedImageRequest bir : mBatchedResponses.values()) {
+                        for (ImageContainer container : bir.mContainers) {
+                            // If one of the callers in the batched request canceled the request
+                            // after the response was received but before it was delivered,
+                            // skip them.
+                            if (container.mListener == null) {
+                                continue;
+                            }
+                            if (error == null) {
+                                container.mBitmap = bir.mResponseBitmap;
+                                container.mListener.onResponse(container, false);
+                            } else {
+                                container.mListener.onErrorResponse(error);
+                            }
+                        }
+                    }
+                    mBatchedResponses.clear();
+                    mRunnable = null;
+                }
+
+            };
+            // Post the runnable.
+            mHandler.postDelayed(mRunnable, mBatchResponseDelayMs);
+        }
+    }
+
+    private void throwIfNotOnMainThread() {
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            throw new IllegalStateException("ImageLoader must be invoked from the main thread.");
+        }
+    }
+    /**
+     * Creates a cache key for use with the L1 cache.
+     * @param url The URL of the request.
+     * @param maxWidth The max-width of the output.
+     * @param maxHeight The max-height of the output.
+     */
+    private static String getCacheKey(String url, int maxWidth, int maxHeight) {
+        return new StringBuilder(url.length() + 12).append("#W").append(maxWidth)
+                .append("#H").append(maxHeight).append(url).toString();
+    }
+}
diff --git a/src/com/android/volley/toolbox/NetworkImageView.java b/src/com/android/volley/toolbox/NetworkImageView.java
new file mode 100644
index 0000000..0d1d6be
--- /dev/null
+++ b/src/com/android/volley/toolbox/NetworkImageView.java
@@ -0,0 +1,197 @@
+/**
+ * Copyright (C) 2013 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 com.android.volley.toolbox;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.ImageLoader.ImageContainer;
+import com.android.volley.toolbox.ImageLoader.ImageListener;
+
+/**
+ * Handles fetching an image from a URL as well as the life-cycle of the
+ * associated request.
+ */
+public class NetworkImageView extends ImageView {
+    /** The URL of the network image to load */
+    private String mUrl;
+
+    /**
+     * Resource ID of the image to be used as a placeholder until the network image is loaded.
+     */
+    private int mDefaultImageId;
+
+    /**
+     * Resource ID of the image to be used if the network response fails.
+     */
+    private int mErrorImageId;
+
+    /** Local copy of the ImageLoader. */
+    private ImageLoader mImageLoader;
+
+    /** Current ImageContainer. (either in-flight or finished) */
+    private ImageContainer mImageContainer;
+
+    public NetworkImageView(Context context) {
+        this(context, null);
+    }
+
+    public NetworkImageView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public NetworkImageView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Sets URL of the image that should be loaded into this view. Note that calling this will
+     * immediately either set the cached image (if available) or the default image specified by
+     * {@link NetworkImageView#setDefaultImageResId(int)} on the view.
+     *
+     * NOTE: If applicable, {@link NetworkImageView#setDefaultImageResId(int)} and
+     * {@link NetworkImageView#setErrorImageResId(int)} should be called prior to calling
+     * this function.
+     *
+     * @param url The URL that should be loaded into this ImageView.
+     * @param imageLoader ImageLoader that will be used to make the request.
+     */
+    public void setImageUrl(String url, ImageLoader imageLoader) {
+        mUrl = url;
+        mImageLoader = imageLoader;
+        // The URL has potentially changed. See if we need to load it.
+        loadImageIfNecessary(false);
+    }
+
+    /**
+     * Sets the default image resource ID to be used for this view until the attempt to load it
+     * completes.
+     */
+    public void setDefaultImageResId(int defaultImage) {
+        mDefaultImageId = defaultImage;
+    }
+
+    /**
+     * Sets the error image resource ID to be used for this view in the event that the image
+     * requested fails to load.
+     */
+    public void setErrorImageResId(int errorImage) {
+        mErrorImageId = errorImage;
+    }
+
+    /**
+     * Loads the image for the view if it isn't already loaded.
+     * @param isInLayoutPass True if this was invoked from a layout pass, false otherwise.
+     */
+    private void loadImageIfNecessary(final boolean isInLayoutPass) {
+        int width = getWidth();
+        int height = getHeight();
+
+        // if the view's bounds aren't known yet, hold off on loading the image.
+        if (width == 0 && height == 0) {
+            return;
+        }
+
+        // if the URL to be loaded in this view is empty, cancel any old requests and clear the
+        // currently loaded image.
+        if (TextUtils.isEmpty(mUrl)) {
+            if (mImageContainer != null) {
+                mImageContainer.cancelRequest();
+                mImageContainer = null;
+            }
+            setImageBitmap(null);
+            return;
+        }
+
+        // if there was an old request in this view, check if it needs to be canceled.
+        if (mImageContainer != null && mImageContainer.getRequestUrl() != null) {
+            if (mImageContainer.getRequestUrl().equals(mUrl)) {
+                // if the request is from the same URL, return.
+                return;
+            } else {
+                // if there is a pre-existing request, cancel it if it's fetching a different URL.
+                mImageContainer.cancelRequest();
+                setImageBitmap(null);
+            }
+        }
+
+        // The pre-existing content of this view didn't match the current URL. Load the new image
+        // from the network.
+        ImageContainer newContainer = mImageLoader.get(mUrl,
+                new ImageListener() {
+                    @Override
+                    public void onErrorResponse(VolleyError error) {
+                        if (mErrorImageId != 0) {
+                            setImageResource(mErrorImageId);
+                        }
+                    }
+
+                    @Override
+                    public void onResponse(final ImageContainer response, boolean isImmediate) {
+                        // If this was an immediate response that was delivered inside of a layout
+                        // pass do not set the image immediately as it will trigger a requestLayout
+                        // inside of a layout. Instead, defer setting the image by posting back to
+                        // the main thread.
+                        if (isImmediate && isInLayoutPass) {
+                            post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    onResponse(response, false);
+                                }
+                            });
+                            return;
+                        }
+
+                        if (response.getBitmap() != null) {
+                            setImageBitmap(response.getBitmap());
+                        } else if (mDefaultImageId != 0) {
+                            setImageResource(mDefaultImageId);
+                        }
+                    }
+                });
+
+        // update the ImageContainer to be the new bitmap container.
+        mImageContainer = newContainer;
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        loadImageIfNecessary(true);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        if (mImageContainer != null) {
+            // If the view was bound to an image request, cancel it and clear
+            // out the image from the view.
+            mImageContainer.cancelRequest();
+            setImageBitmap(null);
+            // also clear out the container so we can reload the image if necessary.
+            mImageContainer = null;
+        }
+        super.onDetachedFromWindow();
+    }
+
+    @Override
+    protected void drawableStateChanged() {
+        super.drawableStateChanged();
+        invalidate();
+    }
+}
diff --git a/src/com/android/volley/toolbox/Volley.java b/src/com/android/volley/toolbox/Volley.java
index bba1153..1304045 100644
--- a/src/com/android/volley/toolbox/Volley.java
+++ b/src/com/android/volley/toolbox/Volley.java
@@ -36,9 +36,10 @@
      * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
      *
      * @param context A {@link Context} to use for creating the cache dir.
+     * @param stack An {@link HttpStack} to use for the network, or null for default.
      * @return A started {@link RequestQueue} instance.
      */
-    public static RequestQueue newRequestQueue(Context context) {
+    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
         File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
 
         String userAgent = "volley/0";
@@ -50,13 +51,14 @@
         } catch (NameNotFoundException e) {
         }
 
-        HttpStack stack;
-        if (Build.VERSION.SDK_INT >= 9) {
-            stack = new HurlStack();
-        } else {
-            // Prior to Gingerbread, HttpUrlConnection was unreliable.
-            // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
-            stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
+        if (stack == null) {
+            if (Build.VERSION.SDK_INT >= 9) {
+                stack = new HurlStack();
+            } else {
+                // Prior to Gingerbread, HttpUrlConnection was unreliable.
+                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
+                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
+            }
         }
 
         Network network = new BasicNetwork(stack);
@@ -66,4 +68,14 @@
 
         return queue;
     }
+
+    /**
+     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
+     *
+     * @param context A {@link Context} to use for creating the cache dir.
+     * @return A started {@link RequestQueue} instance.
+     */
+    public static RequestQueue newRequestQueue(Context context) {
+        return newRequestQueue(context, null);
+    }
 }
