class SQLCompletionProvider extends CompletionProviderBase {

    public List<Completion> getCompletionsAtIndex(JTextComponent jTextComponent, int charIndex) {
        UpdateParserThread fetchingParserTmp = fetchingParser;
        if(fetchingParserTmp != null) {
            if(!fetchingParserTmp.isDone()) {
                try {
                    // Wait until update is done
                    fetchingParserTmp.get(UPDATE_TIMEOUT, TimeUnit.MILLISECONDS);
                } catch (Exception ex) {
                    return new ArrayList<>();
                }
            } else {
                parser = fetchingParserTmp.getParser();
            }
        } if(parser == null) {
            return new ArrayList<>();
        }
        //Completion completion = new BasicCompletion(this, token);
        List<Completion> completionList = new LinkedList<Completion>();

        // Extract the statement at this position
        DocumentSQLReader documentReader = new DocumentSQLReader(jTextComponent.getDocument(), true);
        String statement = "";
        while(documentReader.hasNext() && documentReader.getPosition() + statement.length() < charIndex) {
            statement = documentReader.next();
        }
        // Last word for filtering results
        int completionPosition = charIndex - documentReader.getPosition();
        String partialStatement = LTRIM.matcher(statement.substring(0, completionPosition)).replaceAll("");
        // Ask parser for completion list
        // Left trim the string
        Map<String,String> autoComplete = parser.getNextTokenList(partialStatement);
        for(Map.Entry<String, String> entry : autoComplete.entrySet()) {
            String token =  entry.getKey().substring(entry.getKey().indexOf("#") + 1);
            Completion completion = new BnfAutoCompletion(this, token, entry.getValue());
            completionList.add(completion);
        }

        // Update table list if it has not be done more than UPDATE_INTERVAL ms ago
        long now = System.currentTimeMillis();
        if(lastUpdate + UPDATE_INTERVAL < now) {
            try {
                updateParser(dataSource, false);
            } catch (Exception ex) {
                log.warn("Could not update auto-completion engine", ex);
            }
        }
        return completionList;
    }

    public  SQLCompletionProvider(DataSource dataSource, boolean immediateInit);

}