Rewritten based on AOSP ICS/JB source code