public static function parseActionMethods($con)
    {
        $refClass = new ReflectionClass($con);
        $methodMap = [];

        // build up parent class list
        $parentClasses = [];
        $parentClasses[] = $parentClassRef = $refClass;
        while ($parent = $parentClassRef->getParentClass()) {
            $parentClasses[] = $parent;
            $parentClassRef = $parent;
        }

        // iterate methods from parent class actions
        foreach (array_reverse($parentClasses) as $class) {
            foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {

                // Ignore class methods that doesn't have Action in suffix
                if (!preg_match('/Action$/', $method->getName())) {
                    continue;
                }
                if (in_array($method->getName(), [ 'runAction', 'hasAction' ])) {
                    continue;
                }

                $meta = array('class' => $class->getName());
                $annotations = self::parseMethodAnnotation($method);

                // If it's empty, then fetch annotations from parent methods
                if (empty($annotations)) {
                    if (isset($methodMap[$method->getName()])) {
                        $annotations = $methodMap[$method->getName()][0];
                    }
                }
                // always update method Map
                $methodMap[$method->getName()] = array($annotations, $meta);
            }
        }
        // TODO: see if we can cache it.
        return $methodMap;
    }