Given an invocation string, determine which part is the path, the program,
        and the args.

def parse_invocation(self, invocation, controller_tag):
        """
        Given an invocation string, determine which part is the path, the program,
        and the args.
        """
        if invocation.endswith('/'):
            invocation = invocation[:-1]
        if not invocation.startswith('/'):
            invocation = '/' + invocation
        if invocation == '':
            invocation = '/'

        all_programs = self.get_urls(controllers=[controller_tag])

        matching_paths = set()
        for program_path in sorted(all_programs):
            if invocation.startswith(program_path):
                matching_paths.add(program_path)

        longest = ""
        for path in matching_paths:
            longest = path if len(path) > len(longest) else longest

        matching_path = longest

        program = self.get_program(matching_path, controller=controller_tag)

        if not matching_path:
            raise ProgramNotFound("Can't find %s" % invocation)

        program_name = matching_path.split('/')[-1]
        path = "/".join(matching_path.split('/')[:-1]) + '/'
        args_fragment = invocation[len(matching_path):]

        superformat = None
        if args_fragment.startswith('.'):
            # args_fragment will be something like ".html/arg1/arg2" or just ".html"
            superformat = args_fragment.split('/')[0][1:]
            args = args_fragment.split('/')[1:]
            args_fragment = '/'.join(args)
        else:
            args = args_fragment.split("/")[1:] if args_fragment else []
            args_fragment = args_fragment[1:] if (args_fragment and args_fragment[0] =='/') else args_fragment

        return {
            'program': program,
            'program_name': program_name,
            'superformat': superformat,
            'superformat_mime': super_accept_to_mimetype(superformat),
            'args': args,
            'raw_args': args_fragment,
            'path': path,
            'invocation': invocation,
        }