def autocomplete(self, line):
        """Given a line, return a list of suggestions."""
        current_length = len(line)
        self._current_line = line
        if current_length == 1 and self._last_position > 1:
            # Reset state.  This is likely from a user completing
            # a previous command.
            self.reset()
        elif current_length < self._last_position:
            # The user has hit backspace.  We'll need to check
            # the current words.
            return self._handle_backspace()
        elif not line:
            return []
        elif current_length != self._last_position + 1:
            return self._complete_from_full_parse()

        # This position is important.  We only update the _last_position
        # after we've checked the special cases above where that value
        # matters.
        self._last_position = len(line)
        if line and not line.strip():
            # Special case, the user hits a space on a new line so
            # we autocomplete all the top level commands.
            return self._current['commands']

        last_word = line.split()[-1]
        if last_word in self.arg_metadata or last_word in self._global_options:
            # The last thing we completed was an argument, record
            # this as self.last_arg
            self.last_option = last_word
        if line[-1] == ' ':
            # At this point the user has autocompleted a command
            # or an argument and has hit space.  If they've
            # just completed a command, we need to change the
            # current context and traverse into the subcommand.
            # "ec2 "
            #      ^--here, need to traverse into "ec2"
            #
            # Otherwise:
            # "ec2 --no-validate-ssl "
            #                        ^-- here, stay on "ec2" context.
            if not last_word.startswith('-'):
                next_command = self._current['children'].get(last_word)
                if next_command is not None:
                    self._current = next_command
                    self._current_name = last_word
                    self.cmd_path.append(self._current_name)
            elif last_word in self.arg_metadata and \
                    self.arg_metadata[last_word]['example']:
                # Then this is an arg with a shorthand example so we'll
                # suggest that example.
                return [self.arg_metadata[last_word]['example']]
            # Even if we don't change context, we still want to
            # autocomplete all the commands for the current context
            # in either of the above two cases.
            return self._current['commands'][:]
        elif last_word.startswith('-'):
            # TODO: cache this for the duration of the current context.
            # We don't need to recompute this until the args are
            # different.
            all_args = self._get_all_args()
            if self.match_fuzzy:
                return fuzzy_search(last_word, all_args)
            else:
                return substring_search(last_word, all_args)
        if self.match_fuzzy:
            return fuzzy_search(last_word, self._current['commands'])
        else:
            return substring_search(last_word, self._current['commands'])
Given a line, return a list of suggestions.