gt: 		if (cursor == null) {
context: /*
   * Copyright (C) 2009 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.actionbarsherlock.widget;
  
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.List;
  import java.util.WeakHashMap;
  
  import android.app.SearchManager;
  import android.app.SearchableInfo;
  import android.content.ContentResolver;
  import android.content.Context;
  import android.content.pm.PackageManager.NameNotFoundException;
  import android.content.res.ColorStateList;
  import android.content.res.Resources;
  import android.database.Cursor;
  import android.graphics.drawable.Drawable;
  import android.net.Uri;
  import android.os.Bundle;
  import android.support.v4.widget.ResourceCursorAdapter;
  import android.text.Spannable;
  import android.text.SpannableString;
  import android.text.TextUtils;
  import android.text.style.TextAppearanceSpan;
  import android.util.Log;
  import android.util.TypedValue;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.view.ViewGroup;
  import android.widget.ImageView;
  import android.widget.TextView;
  
  import com.actionbarsherlock.R;
  
  /**
   * Provides the contents for the suggestion drop-down list.
   * 
   * @hide
   */
  class SuggestionsAdapter extends ResourceCursorAdapter implements
  		OnClickListener {
  
  	/**
  	 * Cache of the child views of drop-drown list items, to avoid looking up
  	 * the children each time the contents of a list item are changed.
  	 */
  	private final static class ChildViewCache {
  		public final TextView mText1;
  		public final TextView mText2;
  		public final ImageView mIcon1;
  		public final ImageView mIcon2;
  		public final ImageView mIconRefine;
  
  		public ChildViewCache(final View v) {
  			mText1 = (TextView) v.findViewById(android.R.id.text1);
  			mText2 = (TextView) v.findViewById(android.R.id.text2);
  			mIcon1 = (ImageView) v.findViewById(android.R.id.icon1);
  			mIcon2 = (ImageView) v.findViewById(android.R.id.icon2);
  			mIconRefine = (ImageView) v.findViewById(R.id.edit_query);
  		}
  	}
  
  	private static final boolean DBG = false;
  	private static final String LOG_TAG = "SuggestionsAdapter";
  
  	private static final int QUERY_LIMIT = 50;
  	static final int REFINE_NONE = 0;
  	static final int REFINE_BY_ENTRY = 1;
  
  	static final int REFINE_ALL = 2;
  	// private SearchManager mSearchManager;
  	private final SearchableInfo mSearchable;
  	private final SearchView mSearchView;
  	private final Context mProviderContext;
  	private final WeakHashMap<String, Drawable.ConstantState> mOutsideDrawablesCache;
  	private boolean mClosed = false;
  
  	private int mQueryRefinement = REFINE_BY_ENTRY;
  
  	// URL color
  	private ColorStateList mUrlColor;
  
  	static final int INVALID_INDEX = -1;
  
  	/**
  	 * Gets the value of a string column by name.
  	 * 
  	 * @param cursor
  	 *            Cursor to read the value from.
  	 * @param columnName
  	 *            The name of the column to read.
  	 * @return The value of the given column, or <code>null</null>
  	 *         if the cursor does not contain the given column.
  	 */
  	public static String getColumnString(final Cursor cursor,
  			final String columnName) {
  		final int col = cursor.getColumnIndex(columnName);
  		return getStringOrNull(cursor, col);
  	}
  
  	private static String getStringOrNull(final Cursor cursor, final int col) {
  		if (col == INVALID_INDEX) {
  			return null;
  		}
  		try {
  			return cursor.getString(col);
  		} catch (final Exception e) {
  			Log.e(LOG_TAG,
  					"unexpected error retrieving valid column from cursor, "
  							+ "did the remote process die?", e);
  			return null;
  		}
  	}
  
  	// Cached column indexes, updated when the cursor changes.
  	private int mText1Col = INVALID_INDEX;
  	private int mText2Col = INVALID_INDEX;
  	private int mText2UrlCol = INVALID_INDEX;
  
  	// private final Runnable mStartSpinnerRunnable;
  	// private final Runnable mStopSpinnerRunnable;
  
  	private int mIconName1Col = INVALID_INDEX;
  
  	private int mIconName2Col = INVALID_INDEX;
  
  	private int mFlagsCol = INVALID_INDEX;
  
  	/**
  	 * The amount of time we delay in the filter when the user presses the
  	 * delete key.
  	 */
  	// private static final long DELETE_KEY_POST_DELAY = 500L;
  
  	public SuggestionsAdapter(
  			final Context context,
  			final SearchView searchView,
  			final SearchableInfo searchable,
  			final WeakHashMap<String, Drawable.ConstantState> outsideDrawablesCache) {
  		super(context, R.layout.abs__search_dropdown_item_icons_2line, null, // no
  																				// initial
  																				// cursor
  				true); // auto-requery
  		// mSearchManager = (SearchManager)
  		// mContext.getSystemService(Context.SEARCH_SERVICE);
  		mSearchable = searchable;
  		mProviderContext = mContext;
  		mSearchView = searchView;
  
  		mOutsideDrawablesCache = outsideDrawablesCache;
  
  		// mStartSpinnerRunnable = new Runnable() {
  		// public void run() {
  		// // mSearchView.setWorking(true);
  		// }
  		// };
  		//
  		// mStopSpinnerRunnable = new Runnable() {
  		// public void run() {
  		// // mSearchView.setWorking(false);
  		// }
  		// };
  
  		// delay 500ms when deleting
  		// getFilter().setDelayer(new Filter.Delayer() {
  		//
  		// private int mPreviousLength = 0;
  		//
  		// public long getPostingDelay(CharSequence constraint) {
  		// if (constraint == null) return 0;
  		//
  		// long delay = constraint.length() < mPreviousLength ?
  		// DELETE_KEY_POST_DELAY : 0;
  		// mPreviousLength = constraint.length();
  		// return delay;
  		// }
  		// });
  	}
  
  	@Override
  	public void bindView(final View view, final Context context,
  			final Cursor cursor) {
  		final ChildViewCache views = (ChildViewCache) view.getTag();
  
  		int flags = 0;
  		if (mFlagsCol != INVALID_INDEX) {
  			flags = cursor.getInt(mFlagsCol);
  		}
  		if (views.mText1 != null) {
  			final String text1 = getStringOrNull(cursor, mText1Col);
  			setViewText(views.mText1, text1);
  		}
  		if (views.mText2 != null) {
  			// First check TEXT_2_URL
  			CharSequence text2 = getStringOrNull(cursor, mText2UrlCol);
  			if (text2 != null) {
  				text2 = formatUrl(text2);
  			} else {
  				text2 = getStringOrNull(cursor, mText2Col);
  			}
  
  			// If no second line of text is indicated, allow the first line of
  			// text
  			// to be up to two lines if it wants to be.
  			if (TextUtils.isEmpty(text2)) {
  				if (views.mText1 != null) {
  					views.mText1.setSingleLine(false);
  					views.mText1.setMaxLines(2);
  				}
  			} else {
  				if (views.mText1 != null) {
  					views.mText1.setSingleLine(true);
  					views.mText1.setMaxLines(1);
  				}
  			}
  			setViewText(views.mText2, text2);
  		}
  
  		if (views.mIcon1 != null) {
  			setViewDrawable(views.mIcon1, getIcon1(cursor), View.INVISIBLE);
  		}
  		if (views.mIcon2 != null) {
  			setViewDrawable(views.mIcon2, getIcon2(cursor), View.GONE);
  		}
  		if (mQueryRefinement == REFINE_ALL
  				|| (mQueryRefinement == REFINE_BY_ENTRY && (flags & SearchManager.FLAG_QUERY_REFINEMENT) != 0)) {
  			views.mIconRefine.setVisibility(View.VISIBLE);
  			views.mIconRefine.setTag(views.mText1.getText());
  			views.mIconRefine.setOnClickListener(this);
  		} else {
  			views.mIconRefine.setVisibility(View.GONE);
  		}
  	}
  
  	/**
  	 * Cache columns.
  	 */
  	@Override
  	public void changeCursor(final Cursor c) {
  		if (DBG) {
  			Log.d(LOG_TAG, "changeCursor(" + c + ")");
  		}
  
  		if (mClosed) {
  			Log.w(LOG_TAG, "Tried to change cursor after adapter was closed.");
  			if (c != null) {
  				c.close();
  			}
  			return;
  		}
  
  		try {
  			super.changeCursor(c);
  
  			if (c != null) {
  				mText1Col = c
  						.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1);
  				mText2Col = c
  						.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2);
  				mText2UrlCol = c
  						.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL);
  				mIconName1Col = c
  						.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
  				mIconName2Col = c
  						.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2);
  				mFlagsCol = c
  						.getColumnIndex(SearchManager.SUGGEST_COLUMN_FLAGS);
  			}
  		} catch (final Exception e) {
  			Log.e(LOG_TAG, "error changing cursor and caching columns", e);
  		}
  	}
  
  	private Drawable checkIconCache(final String resourceUri) {
  		final Drawable.ConstantState cached = mOutsideDrawablesCache
  				.get(resourceUri);
  		if (cached == null) {
  			return null;
  		}
  		if (DBG) {
  			Log.d(LOG_TAG, "Found icon in cache: " + resourceUri);
  		}
  		return cached.newDrawable();
  	}
  
  	public void close() {
  		if (DBG) {
  			Log.d(LOG_TAG, "close()");
  		}
  		changeCursor(null);
  		mClosed = true;
  	}
  
  	/**
  	 * Gets the text to show in the query field when a suggestion is selected.
  	 * 
  	 * @param cursor
  	 *            The Cursor to read the suggestion data from. The Cursor should
  	 *            already be moved to the suggestion that is to be read from.
  	 * @return The text to show, or <code>null</code> if the query should not be
  	 *         changed when selecting this suggestion.
  	 */
  	@Override
  	public CharSequence convertToString(final Cursor cursor) {
  