diff --git a/src/com/android/datetimepicker/date/DayPickerView.java b/src/com/android/datetimepicker/date/DayPickerView.java
index 1b0e871..fcd1d8c 100644
--- a/src/com/android/datetimepicker/date/DayPickerView.java
+++ b/src/com/android/datetimepicker/date/DayPickerView.java
@@ -347,4 +347,59 @@
     public void onDateChanged() {
         goTo(mController.getSelectedDay(), false, true, true);
     }
+
+    /**
+     * Attempts to return the date that has accessibility focus.
+     *
+     * @return The date that has accessibility focus, or {@code null} if no date
+     *         has focus.
+     */
+    private CalendarDay findAccessibilityFocus() {
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (child instanceof SimpleMonthView) {
+                final CalendarDay focus = ((SimpleMonthView) child).getAccessibilityFocus();
+                if (focus != null) {
+                    // Clear focus to avoid ListView bug in Jelly Bean MR1.
+                    ((SimpleMonthView) child).clearAccessibilityFocus();
+                    return focus;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Attempts to restore accessibility focus to a given date. No-op if
+     * {@code day} is {@code null}.
+     *
+     * @param day The date that should receive accessibility focus
+     * @return {@code true} if focus was restored
+     */
+    private boolean restoreAccessibilityFocus(CalendarDay day) {
+        if (day == null) {
+            return false;
+        }
+
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (child instanceof SimpleMonthView) {
+                if (((SimpleMonthView) child).restoreAccessibilityFocus(day)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    protected void layoutChildren() {
+        final CalendarDay focusedDay = findAccessibilityFocus();
+        super.layoutChildren();
+        restoreAccessibilityFocus(focusedDay);
+    }
 }
diff --git a/src/com/android/datetimepicker/date/SimpleMonthAdapter.java b/src/com/android/datetimepicker/date/SimpleMonthAdapter.java
index 6d3ef7a..84be210 100644
--- a/src/com/android/datetimepicker/date/SimpleMonthAdapter.java
+++ b/src/com/android/datetimepicker/date/SimpleMonthAdapter.java
@@ -18,28 +18,26 @@
 
 import android.content.Context;
 import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
 import android.view.View;
-import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
 import android.widget.AbsListView.LayoutParams;
 import android.widget.BaseAdapter;
 
+import com.android.datetimepicker.date.SimpleMonthView.OnDayClickListener;
+
 import java.util.Calendar;
 import java.util.HashMap;
 
 /**
  * An adapter for a list of {@link SimpleMonthView} items.
  */
-public class SimpleMonthAdapter extends BaseAdapter implements OnTouchListener {
+public class SimpleMonthAdapter extends BaseAdapter implements OnDayClickListener {
 
     private static final String TAG = "SimpleMonthAdapter";
 
     private final Context mContext;
     private final DatePickerController mController;
 
-    private GestureDetector mGestureDetector;
     private CalendarDay mSelectedDay;
 
     protected static int WEEK_7_OVERHANG_HEIGHT = 7;
@@ -121,7 +119,6 @@
      * Set up the gesture detector and selected time
      */
     protected void init() {
-        mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
         mSelectedDay = new CalendarDay(System.currentTimeMillis());
     }
 
@@ -156,7 +153,7 @@
                     LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             v.setLayoutParams(params);
             v.setClickable(true);
-            v.setOnTouchListener(this);
+            v.setOnDayClickListener(this);
         }
         if (drawingParams == null) {
             drawingParams = new HashMap<String, Integer>();
@@ -190,15 +187,10 @@
     }
 
     @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        if (mGestureDetector.onTouchEvent(event)) {
-            CalendarDay day = ((SimpleMonthView) v).getDayFromLocation(event.getX(), event.getY());
-            if (day != null) {
-                onDayTapped(day);
-            }
-            return true;
+    public void onDayClick(SimpleMonthView view, CalendarDay day) {
+        if (day != null) {
+            onDayTapped(day);
         }
-        return false;
     }
 
     /**
@@ -211,15 +203,4 @@
         mController.onDayOfMonthSelected(day.year, day.month, day.day);
         setSelectedDay(day);
     }
-
-    /**
-     * This is here so we can identify single tap events and set the selected
-     * day correctly
-     */
-    protected class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
-        @Override
-        public boolean onSingleTapUp(MotionEvent e) {
-            return true;
-        }
-    }
 }
diff --git a/src/com/android/datetimepicker/date/SimpleMonthView.java b/src/com/android/datetimepicker/date/SimpleMonthView.java
index c3a4346..bcb592f 100644
--- a/src/com/android/datetimepicker/date/SimpleMonthView.java
+++ b/src/com/android/datetimepicker/date/SimpleMonthView.java
@@ -22,17 +22,29 @@
 import android.graphics.Paint;
 import android.graphics.Paint.Align;
 import android.graphics.Paint.Style;
+import android.graphics.Rect;
 import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
+import android.text.format.DateUtils;
 import android.text.format.Time;
+import android.util.SparseArray;
+import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 import com.android.datetimepicker.R;
 import com.android.datetimepicker.Utils;
 import com.android.datetimepicker.date.SimpleMonthAdapter.CalendarDay;
+import com.googlecode.eyesfree.utils.TouchExplorationHelper;
 
 import java.security.InvalidParameterException;
 import java.util.Calendar;
+import java.util.Formatter;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -119,6 +131,9 @@
     protected Paint mSelectedCirclePaint;
     protected Paint mMonthDayLabelPaint;
 
+    private final Formatter mFormatter;
+    private final StringBuilder mStringBuilder;
+
     // The Julian day of the first day displayed by this item
     protected int mFirstJulianDay = -1;
     // The month of the first day in this week
@@ -152,9 +167,15 @@
 
     private final Calendar mCalendar;
     private final Calendar mDayLabelCalendar;
+    private final MonthViewNodeProvider mNodeProvider;
 
     private int mNumRows = DEFAULT_NUM_ROWS;
 
+    // Optional listener for handling day click actions
+    private OnDayClickListener mOnDayClickListener;
+    // Whether to prevent setting the accessibility delegate
+    private boolean mLockAccessibilityDelegate;
+
     protected int mDayTextColor;
     protected int mTodayNumberColor;
     protected int mMonthTitleColor;
@@ -176,6 +197,9 @@
         mMonthTitleColor = res.getColor(R.color.white);
         mMonthTitleBGColor = res.getColor(R.color.circle_background);
 
+        mStringBuilder = new StringBuilder(50);
+        mFormatter = new Formatter(mStringBuilder, Locale.getDefault());
+
         MINI_DAY_NUMBER_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.day_number_size);
         MONTH_LABEL_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.month_label_size);
         MONTH_DAY_LABEL_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.month_day_label_text_size);
@@ -185,10 +209,52 @@
 
         mRowHeight = (res.getDimensionPixelOffset(R.dimen.date_picker_view_animator_height)
                 - MONTH_HEADER_SIZE) / MAX_NUM_ROWS;
+
+        // Set up accessibility components.
+        mNodeProvider = new MonthViewNodeProvider(context, this);
+        ViewCompat.setAccessibilityDelegate(this, mNodeProvider.getAccessibilityDelegate());
+        ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
+        mLockAccessibilityDelegate = true;
+
         // Sets up any standard paints that will be used
         initView();
     }
 
+    @Override
+    public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
+        // Workaround for a JB MR1 issue where accessibility delegates on
+        // top-level ListView items are overwritten.
+        if (!mLockAccessibilityDelegate) {
+            super.setAccessibilityDelegate(delegate);
+        }
+    }
+
+    public void setOnDayClickListener(OnDayClickListener listener) {
+        mOnDayClickListener = listener;
+    }
+
+    @Override
+    public boolean onHoverEvent(MotionEvent event) {
+        // First right-of-refusal goes the touch exploration helper.
+        if (mNodeProvider.onHover(this, event)) {
+            return true;
+        }
+        return super.onHoverEvent(event);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_UP:
+                final CalendarDay day = getDayFromLocation(event.getX(), event.getY());
+                if (day != null) {
+                    onDayClick(day);
+                }
+                break;
+        }
+        return true;
+    }
+
     /**
      * Sets up the text and style properties for painting. Override this if you
      * want to use a different paint.
@@ -301,6 +367,9 @@
             }
         }
         mNumRows = calculateNumRows();
+
+        // Invalidate cached accessibility information.
+        mNodeProvider.invalidateParent();
     }
 
     public void reuse() {
@@ -330,17 +399,22 @@
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         mWidth = w;
+
+        // Invalidate cached accessibility information.
+        mNodeProvider.invalidateParent();
     }
 
     private void drawMonthTitle(Canvas canvas) {
         int x = (mWidth + 2 * mPadding) / 2;
         int y = (MONTH_HEADER_SIZE - MONTH_DAY_LABEL_TEXT_SIZE) / 2 + (MONTH_LABEL_TEXT_SIZE / 3);
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append(mCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG,
-                Locale.getDefault()));
-        sbuf.append(" ");
-        sbuf.append(String.format("%d", mYear));
-        canvas.drawText(sbuf.toString(), x, y, mMonthTitlePaint);
+        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR
+                | DateUtils.FORMAT_NO_MONTH_DAY;
+
+        mStringBuilder.setLength(0);
+        long millis = mCalendar.getTimeInMillis();
+        String title = DateUtils.formatDateRange(getContext(), mFormatter, millis, millis, flags,
+                Time.getCurrentTimezone()).toString();
+        canvas.drawText(title, x, y, mMonthTitlePaint);
     }
 
     private void drawMonthDayLabels(Canvas canvas) {
@@ -421,4 +495,190 @@
         return new CalendarDay(mYear, mMonth, day);
     }
 
+    /**
+     * Called when the user clicks on a day. Handles callbacks to the
+     * {@link OnDayClickListener} if one is set.
+     *
+     * @param day A time object representing the day that was clicked
+     */
+    private void onDayClick(CalendarDay day) {
+        if (mOnDayClickListener != null) {
+            mOnDayClickListener.onDayClick(this, day);
+        }
+
+        // This is a no-op if accessibility is turned off.
+        mNodeProvider.sendEventForItem(day, AccessibilityEvent.TYPE_VIEW_CLICKED);
+    }
+
+    /**
+     * @return The date that has accessibility focus, or {@code null} if no date
+     *         has focus
+     */
+    public CalendarDay getAccessibilityFocus() {
+        return mNodeProvider.getFocusedItem();
+    }
+
+    /**
+     * Clears accessibility focus within the view. No-op if the view does not
+     * contain accessibility focus.
+     */
+    public void clearAccessibilityFocus() {
+        mNodeProvider.clearFocusedItem();
+    }
+
+    /**
+     * Attempts to restore accessibility focus to the specified date.
+     *
+     * @param day The date which should receive focus
+     * @return {@code false} if the date is not valid for this month view, or
+     *         {@code true} if the date received focus
+     */
+    public boolean restoreAccessibilityFocus(CalendarDay day) {
+        if ((day.year != mYear) || (day.month != mMonth) || (day.day > mNumCells)) {
+            return false;
+        }
+
+        mNodeProvider.setFocusedItem(day);
+        return true;
+    }
+
+    /**
+     * Provides a virtual view hierarchy for interfacing with an accessibility
+     * service.
+     */
+    private class MonthViewNodeProvider extends TouchExplorationHelper<CalendarDay> {
+        private final SparseArray<CalendarDay> mCachedItems = new SparseArray<CalendarDay>();
+        private final Rect mTempRect = new Rect();
+
+        public MonthViewNodeProvider(Context context, View parent) {
+            super(context, parent);
+        }
+
+        @Override
+        public void invalidateItem(CalendarDay item) {
+            super.invalidateItem(item);
+            mCachedItems.delete(getIdForItem(item));
+        }
+
+        @Override
+        public void invalidateParent() {
+            super.invalidateParent();
+            mCachedItems.clear();
+        }
+
+        @Override
+        protected boolean performActionForItem(CalendarDay item, int action, Bundle arguments) {
+            switch (action) {
+                case AccessibilityNodeInfo.ACTION_CLICK:
+                    onDayClick(item);
+                    return true;
+            }
+
+            return false;
+        }
+
+        @Override
+        protected void populateEventForItem(CalendarDay item, AccessibilityEvent event) {
+            event.setContentDescription(getItemDescription(item));
+        }
+
+        @Override
+        protected void populateNodeForItem(CalendarDay item, AccessibilityNodeInfoCompat node) {
+            getItemBounds(item, mTempRect);
+
+            node.setContentDescription(getItemDescription(item));
+            node.setBoundsInParent(mTempRect);
+            node.addAction(AccessibilityNodeInfo.ACTION_CLICK);
+
+            if (item.day == mSelectedDay) {
+                node.setSelected(true);
+            }
+        }
+
+        @Override
+        protected void getVisibleItems(List<CalendarDay> items) {
+            // TODO: Optimize, only return items visible within parent bounds.
+            for (int day = 1; day <= mNumCells; day++) {
+                items.add(getItemForId(day));
+            }
+        }
+
+        @Override
+        protected CalendarDay getItemAt(float x, float y) {
+            return getDayFromLocation(x, y);
+        }
+
+        @Override
+        protected int getIdForItem(CalendarDay item) {
+            return item.day;
+        }
+
+        @Override
+        protected CalendarDay getItemForId(int id) {
+            if ((id < 1) || (id > mNumCells)) {
+                return null;
+            }
+
+            final CalendarDay item;
+            if (mCachedItems.indexOfKey(id) >= 0) {
+                item = mCachedItems.get(id);
+            } else {
+                item = new CalendarDay(mYear, mMonth, id);
+                mCachedItems.put(id, item);
+            }
+
+            return item;
+        }
+
+        /**
+         * Calculates the bounding rectangle of a given time object.
+         *
+         * @param item The time object to calculate bounds for
+         * @param rect The rectangle in which to store the bounds
+         */
+        private void getItemBounds(CalendarDay item, Rect rect) {
+            final int offsetX = mPadding;
+            final int offsetY = MONTH_HEADER_SIZE;
+            final int cellHeight = mRowHeight;
+            final int cellWidth = ((mWidth - (2 * mPadding)) / mNumDays);
+            final int index = ((item.day - 1) + findDayOffset());
+            final int row = (index / mNumDays);
+            final int column = (index % mNumDays);
+            final int x = (offsetX + (column * cellWidth));
+            final int y = (offsetY + (row * cellHeight));
+
+            rect.set(x, y, (x + cellWidth), (y + cellHeight));
+        }
+
+        /**
+         * Generates a description for a given time object. Since this
+         * description will be spoken, the components are ordered by descending
+         * specificity as DAY MONTH YEAR.
+         *
+         * @param item The time object to generate a description for
+         * @return A description of the time object
+         */
+        private CharSequence getItemDescription(CalendarDay item) {
+            final StringBuffer sbuf = new StringBuffer();
+            sbuf.append(String.format("%d", item.day));
+            sbuf.append(" ");
+            sbuf.append(mCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG,
+                    Locale.getDefault()));
+            sbuf.append(" ");
+            sbuf.append(String.format("%d", mYear));
+
+            if (item.day == mSelectedDay) {
+                return getContext().getString(R.string.item_is_selected, sbuf);
+            }
+
+            return sbuf;
+        }
+    }
+
+    /**
+     * Handles callbacks when the user clicks on a time object.
+     */
+    public interface OnDayClickListener {
+        public void onDayClick(SimpleMonthView view, CalendarDay day);
+    }
 }
diff --git a/src/com/googlecode/eyesfree/utils/TouchExplorationHelper.java b/src/com/googlecode/eyesfree/utils/TouchExplorationHelper.java
new file mode 100644
index 0000000..b9df653
--- /dev/null
+++ b/src/com/googlecode/eyesfree/utils/TouchExplorationHelper.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.utils;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.support.v4.view.AccessibilityDelegateCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
+import android.support.v4.view.accessibility.AccessibilityRecordCompat;
+import android.text.TextUtils;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public abstract class TouchExplorationHelper<T> extends AccessibilityNodeProviderCompat
+        implements View.OnHoverListener {
+    /** Virtual node identifier value for invalid nodes. */
+    public static final int INVALID_ID = Integer.MIN_VALUE;
+
+    private final Rect mTempScreenRect = new Rect();
+    private final Rect mTempParentRect = new Rect();
+    private final Rect mTempVisibleRect = new Rect();
+    private final int[] mTempGlobalRect = new int[2];
+
+    private final AccessibilityManager mManager;
+
+    private View mParentView;
+    private int mFocusedItemId = INVALID_ID;
+    private T mCurrentItem = null;
+
+    /**
+     * Constructs a new touch exploration helper.
+     *
+     * @param context The parent context.
+     */
+    public TouchExplorationHelper(Context context, View parentView) {
+        mManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
+        mParentView = parentView;
+    }
+
+    /**
+     * @return The current accessibility focused item, or {@code null} if no
+     *         item is focused.
+     */
+    public T getFocusedItem() {
+        return getItemForId(mFocusedItemId);
+    }
+
+    /**
+     * Clears the current accessibility focused item.
+     */
+    public void clearFocusedItem() {
+        final int itemId = mFocusedItemId;
+        if (itemId == INVALID_ID) {
+            return;
+        }
+
+        performAction(itemId, AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
+    }
+
+    /**
+     * Requests accessibility focus be placed on the specified item.
+     *
+     * @param item The item to place focus on.
+     */
+    public void setFocusedItem(T item) {
+        final int itemId = getIdForItem(item);
+        if (itemId == INVALID_ID) {
+            return;
+        }
+
+        performAction(itemId, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null);
+    }
+
+    /**
+     * Invalidates cached information about the parent view.
+     * <p>
+     * You <b>must</b> call this method after adding or removing items from the
+     * parent view.
+     * </p>
+     */
+    public void invalidateParent() {
+        mParentView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+    }
+
+    /**
+     * Invalidates cached information for a particular item.
+     * <p>
+     * You <b>must</b> call this method when any of the properties set in
+     * {@link #populateNodeForItem(Object, AccessibilityNodeInfoCompat)} have
+     * changed.
+     * </p>
+     *
+     * @param item
+     */
+    public void invalidateItem(T item) {
+        sendEventForItem(item, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+    }
+
+    /**
+     * Populates an event of the specified type with information about an item
+     * and attempts to send it up through the view hierarchy.
+     *
+     * @param item The item for which to send an event.
+     * @param eventType The type of event to send.
+     * @return {@code true} if the event was sent successfully.
+     */
+    public boolean sendEventForItem(T item, int eventType) {
+        if (!mManager.isEnabled()) {
+            return false;
+        }
+
+        final AccessibilityEvent event = getEventForItem(item, eventType);
+        final ViewGroup group = (ViewGroup) mParentView.getParent();
+
+        return group.requestSendAccessibilityEvent(mParentView, event);
+    }
+
+    @Override
+    public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) {
+        if (virtualViewId == View.NO_ID) {
+            return getNodeForParent();
+        }
+
+        final T item = getItemForId(virtualViewId);
+        if (item == null) {
+            return null;
+        }
+
+        final AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain();
+        populateNodeForItemInternal(item, node);
+        return node;
+    }
+
+    @Override
+    public boolean performAction(int virtualViewId, int action, Bundle arguments) {
+        if (virtualViewId == View.NO_ID) {
+            return ViewCompat.performAccessibilityAction(mParentView, action, arguments);
+        }
+
+        final T item = getItemForId(virtualViewId);
+        if (item == null) {
+            return false;
+        }
+
+        boolean handled = false;
+
+        switch (action) {
+            case AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS:
+                if (mFocusedItemId != virtualViewId) {
+                    mFocusedItemId = virtualViewId;
+                    sendEventForItem(item, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
+                    handled = true;
+                }
+                break;
+            case AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
+                if (mFocusedItemId == virtualViewId) {
+                    mFocusedItemId = INVALID_ID;
+                    sendEventForItem(item, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+                    handled = true;
+                }
+                break;
+        }
+
+        handled |= performActionForItem(item, action, arguments);
+
+        return handled;
+    }
+
+    @Override
+    public boolean onHover(View view, MotionEvent event) {
+        if (!mManager.isTouchExplorationEnabled()) {
+            return false;
+        }
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_HOVER_ENTER:
+            case MotionEvent.ACTION_HOVER_MOVE:
+                final T item = getItemAt(event.getX(), event.getY());
+                setCurrentItem(item);
+                return true;
+            case MotionEvent.ACTION_HOVER_EXIT:
+                setCurrentItem(null);
+                return true;
+        }
+
+        return false;
+    }
+
+    private void setCurrentItem(T item) {
+        if (mCurrentItem == item) {
+            return;
+        }
+
+        if (mCurrentItem != null) {
+            sendEventForItem(mCurrentItem, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+        }
+
+        mCurrentItem = item;
+
+        if (mCurrentItem != null) {
+            sendEventForItem(mCurrentItem, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+        }
+    }
+
+    private AccessibilityEvent getEventForItem(T item, int eventType) {
+        final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
+        final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event);
+        final int virtualDescendantId = getIdForItem(item);
+
+        // Ensure the client has good defaults.
+        event.setEnabled(true);
+
+        // Allow the client to populate the event.
+        populateEventForItem(item, event);
+
+        if (event.getText().isEmpty() && TextUtils.isEmpty(event.getContentDescription())) {
+            throw new RuntimeException(
+                    "You must add text or a content description in populateEventForItem()");
+        }
+
+        // Don't allow the client to override these properties.
+        event.setClassName(item.getClass().getName());
+        event.setPackageName(mParentView.getContext().getPackageName());
+        record.setSource(mParentView, virtualDescendantId);
+
+        return event;
+    }
+
+    private AccessibilityNodeInfoCompat getNodeForParent() {
+        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(mParentView);
+        ViewCompat.onInitializeAccessibilityNodeInfo(mParentView, info);
+
+        final LinkedList<T> items = new LinkedList<T>();
+        getVisibleItems(items);
+
+        for (T item : items) {
+            final int virtualDescendantId = getIdForItem(item);
+            info.addChild(mParentView, virtualDescendantId);
+        }
+
+        return info;
+    }
+
+    private AccessibilityNodeInfoCompat populateNodeForItemInternal(
+            T item, AccessibilityNodeInfoCompat node) {
+        final int virtualDescendantId = getIdForItem(item);
+
+        // Ensure the client has good defaults.
+        node.setEnabled(true);
+
+        // Allow the client to populate the node.
+        populateNodeForItem(item, node);
+
+        if (TextUtils.isEmpty(node.getText()) && TextUtils.isEmpty(node.getContentDescription())) {
+            throw new RuntimeException(
+                    "You must add text or a content description in populateNodeForItem()");
+        }
+
+        // Don't allow the client to override these properties.
+        node.setPackageName(mParentView.getContext().getPackageName());
+        node.setClassName(item.getClass().getName());
+        node.setParent(mParentView);
+        node.setSource(mParentView, virtualDescendantId);
+
+        if (mFocusedItemId == virtualDescendantId) {
+            node.addAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+        } else {
+            node.addAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
+        }
+
+        node.getBoundsInParent(mTempParentRect);
+        if (mTempParentRect.isEmpty()) {
+            throw new RuntimeException("You must set parent bounds in populateNodeForItem()");
+        }
+
+        // Set the visibility based on the parent bound.
+        if (intersectVisibleToUser(mTempParentRect)) {
+            node.setVisibleToUser(true);
+            node.setBoundsInParent(mTempParentRect);
+        }
+
+        // Calculate screen-relative bound.
+        mParentView.getLocationOnScreen(mTempGlobalRect);
+        final int offsetX = mTempGlobalRect[0];
+        final int offsetY = mTempGlobalRect[1];
+        mTempScreenRect.set(mTempParentRect);
+        mTempScreenRect.offset(offsetX, offsetY);
+        node.setBoundsInScreen(mTempScreenRect);
+
+        return node;
+    }
+
+    /**
+     * Computes whether the specified {@link Rect} intersects with the visible
+     * portion of its parent {@link View}. Modifies {@code localRect} to
+     * contain only the visible portion.
+     *
+     * @param localRect A rectangle in local (parent) coordinates.
+     * @return Whether the specified {@link Rect} is visible on the screen.
+     */
+    private boolean intersectVisibleToUser(Rect localRect) {
+        // Missing or empty bounds mean this view is not visible.
+        if ((localRect == null) || localRect.isEmpty()) {
+            return false;
+        }
+
+        // Attached to invisible window means this view is not visible.
+        if (mParentView.getWindowVisibility() != View.VISIBLE) {
+            return false;
+        }
+
+        // An invisible predecessor or one with alpha zero means
+        // that this view is not visible to the user.
+        Object current = this;
+        while (current instanceof View) {
+            final View view = (View) current;
+            // We have attach info so this view is attached and there is no
+            // need to check whether we reach to ViewRootImpl on the way up.
+            if ((view.getAlpha() <= 0) || (view.getVisibility() != View.VISIBLE)) {
+                return false;
+            }
+            current = view.getParent();
+        }
+
+        // If no portion of the parent is visible, this view is not visible.
+        if (!mParentView.getLocalVisibleRect(mTempVisibleRect)) {
+            return false;
+        }
+
+        // Check if the view intersects the visible portion of the parent.
+        return localRect.intersect(mTempVisibleRect);
+    }
+
+    public AccessibilityDelegateCompat getAccessibilityDelegate() {
+        return mDelegate;
+    }
+
+    private final AccessibilityDelegateCompat mDelegate = new AccessibilityDelegateCompat() {
+        @Override
+        public void onInitializeAccessibilityEvent(View view, AccessibilityEvent event) {
+            super.onInitializeAccessibilityEvent(view, event);
+            event.setClassName(view.getClass().getName());
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(View view, AccessibilityNodeInfoCompat info) {
+            super.onInitializeAccessibilityNodeInfo(view, info);
+            info.setClassName(view.getClass().getName());
+        }
+
+        @Override
+        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View host) {
+            return TouchExplorationHelper.this;
+        }
+    };
+
+    /**
+     * Performs an accessibility action on the specified item. See
+     * {@link AccessibilityNodeInfoCompat#performAction(int, Bundle)}.
+     * <p>
+     * The helper class automatically handles focus management resulting from
+     * {@link AccessibilityNodeInfoCompat#ACTION_ACCESSIBILITY_FOCUS} and
+     * {@link AccessibilityNodeInfoCompat#ACTION_CLEAR_ACCESSIBILITY_FOCUS}, so
+     * typically a developer only needs to handle actions added manually in the
+     * {{@link #populateNodeForItem(Object, AccessibilityNodeInfoCompat)}
+     * method.
+     * </p>
+     *
+     * @param item The item on which to perform the action.
+     * @param action The accessibility action to perform.
+     * @param arguments Arguments for the action, or optionally {@code null}.
+     * @return {@code true} if the action was performed successfully.
+     */
+    protected abstract boolean performActionForItem(T item, int action, Bundle arguments);
+
+    /**
+     * Populates an event with information about the specified item.
+     * <p>
+     * At a minimum, a developer must populate the event text by doing one of
+     * the following:
+     * <ul>
+     * <li>appending text to {@link AccessibilityEvent#getText()}</li>
+     * <li>populating a description with
+     * {@link AccessibilityEvent#setContentDescription(CharSequence)}</li>
+     * </ul>
+     * </p>
+     *
+     * @param item The item for which to populate the event.
+     * @param event The event to populate.
+     */
+    protected abstract void populateEventForItem(T item, AccessibilityEvent event);
+
+    /**
+     * Populates a node with information about the specified item.
+     * <p>
+     * At a minimum, a developer must:
+     * <ul>
+     * <li>populate the event text using
+     * {@link AccessibilityNodeInfoCompat#setText(CharSequence)} or
+     * {@link AccessibilityNodeInfoCompat#setContentDescription(CharSequence)}
+     * </li>
+     * <li>set the item's parent-relative bounds using
+     * {@link AccessibilityNodeInfoCompat#setBoundsInParent(Rect)}
+     * </ul>
+     *
+     * @param item The item for which to populate the node.
+     * @param node The node to populate.
+     */
+    protected abstract void populateNodeForItem(T item, AccessibilityNodeInfoCompat node);
+
+    /**
+     * Populates a list with the parent view's visible items.
+     * <p>
+     * The result of this method is cached until the developer calls
+     * {@link #invalidateParent()}.
+     * </p>
+     *
+     * @param items The list to populate with visible items.
+     */
+    protected abstract void getVisibleItems(List<T> items);
+
+    /**
+     * Returns the item under the specified parent-relative coordinates.
+     *
+     * @param x The parent-relative x coordinate.
+     * @param y The parent-relative y coordinate.
+     * @return The item under coordinates (x,y).
+     */
+    protected abstract T getItemAt(float x, float y);
+
+    /**
+     * Returns the unique identifier for an item. If the specified item does not
+     * exist, returns {@link #INVALID_ID}.
+     * <p>
+     * This result of this method must be consistent with
+     * {@link #getItemForId(int)}.
+     * </p>
+     *
+     * @param item The item whose identifier to return.
+     * @return A unique identifier, or {@link #INVALID_ID}.
+     */
+    protected abstract int getIdForItem(T item);
+
+    /**
+     * Returns the item for a unique identifier. If the specified item does not
+     * exist, returns {@code null}.
+     *
+     * @param id The identifier for the item to return.
+     * @return An item, or {@code null}.
+     */
+    protected abstract T getItemForId(int id);
+}
