// Path: volley/src/main/java/com/android/fancyblurdemo/volley/VolleyError.java
// @SuppressWarnings("serial")
// public class VolleyError extends Exception {
//     public final NetworkResponse networkResponse;
// 
//     public VolleyError() {
//         networkResponse = null;
//     }
// 
//     public VolleyError(NetworkResponse response) {
//         networkResponse = response;
//     }
// 
//     public VolleyError(String exceptionMessage) {
//        super(exceptionMessage);
//        networkResponse = null;
//     }
// 
//     public VolleyError(String exceptionMessage, Throwable reason) {
//         super(exceptionMessage, reason);
//         networkResponse = null;
//     }
// 
//     public VolleyError(Throwable cause) {
//         super(cause);
//         networkResponse = null;
//     }
// }
// 
// Path: volley/src/main/java/com/android/fancyblurdemo/volley/toolbox/ImageLoader.java
// 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;
//     }
// }
// 
// Path: volley/src/main/java/com/android/fancyblurdemo/volley/toolbox/ImageLoader.java
// 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);
// }


import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import com.android.fancyblurdemo.volley.VolleyError;
import com.android.fancyblurdemo.volley.toolbox.ImageLoader.ImageContainer;
import com.android.fancyblurdemo.volley.toolbox.ImageLoader.ImageListener;
        // view, hold off on loading the image.
        boolean isFullyWrapContent = wrapWidth && wrapHeight;
        if (width == 0 && height == 0 && !isFullyWrapContent) {
            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;
            }
            setDefaultImageOrNull();
            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();
                setDefaultImageOrNull();
            }
        }

        // Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
// Path: volley/src/main/java/com/android/fancyblurdemo/volley/VolleyError.java
// @SuppressWarnings("serial")
// public class VolleyError extends Exception {
//     public final NetworkResponse networkResponse;
// 
//     public VolleyError() {
//         networkResponse = null;
//     }
// 
//     public VolleyError(NetworkResponse response) {
//         networkResponse = response;
//     }
// 
//     public VolleyError(String exceptionMessage) {
//        super(exceptionMessage);
//        networkResponse = null;
//     }
// 
//     public VolleyError(String exceptionMessage, Throwable reason) {
//         super(exceptionMessage, reason);
//         networkResponse = null;
//     }
// 
//     public VolleyError(Throwable cause) {
//         super(cause);
//         networkResponse = null;
//     }
// }
// 
// Path: volley/src/main/java/com/android/fancyblurdemo/volley/toolbox/ImageLoader.java
// 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;
//     }
// }
// 
// Path: volley/src/main/java/com/android/fancyblurdemo/volley/toolbox/ImageLoader.java
// 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);
// }


// Path: volley/src/main/java/com/android/fancyblurdemo/volley/toolbox/NetworkImageView.java
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import com.android.fancyblurdemo.volley.VolleyError;
import com.android.fancyblurdemo.volley.toolbox.ImageLoader.ImageContainer;
import com.android.fancyblurdemo.volley.toolbox.ImageLoader.ImageListener;

        // view, hold off on loading the image.
        boolean isFullyWrapContent = wrapWidth && wrapHeight;
        if (width == 0 && height == 0 && !isFullyWrapContent) {
            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;
            }
            setDefaultImageOrNull();
            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();
                setDefaultImageOrNull();
            }
        }

        // Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
        int maxWidth = wrapWidth ? 0 : width;