Rewritten to support API 9+