// Path: src/org/gololang/netbeans/api/completion/util/CompletionContext.java
// public class CompletionContext {
//     
//     private final ParserResult parserResult;
//     private final FileObject sourceFile;
//     
//     private final String prefix;
//     private int anchor;
//     
//     public final int lexOffset;
//     public final BaseDocument doc;
//    
//     
//     public CompletionContext(
//             ParserResult parseResult,
//             String prefix,
//             int anchor,
//             int lexOffset,
//             BaseDocument doc) {
// 
//         this.parserResult = parseResult;
//         this.sourceFile = parseResult.getSnapshot().getSource().getFileObject();
//         this.prefix = prefix;
//         this.anchor = anchor;
//         this.lexOffset = lexOffset;
//         this.doc = doc;
//         
//     }
// 
//     public String getPrefix() {
//         return prefix;
//     }
// 
//     public int getAnchor() {
//         return anchor;
//     }
// 
//     public ParserResult getParserResult() {
//         return parserResult;
//     }
// 
//     public FileObject getSourceFile() {
//         return sourceFile;
//     }
//     
//     public boolean isAnchorInFunction() {
//         return isAnchorInFunction(anchor);
//     }
//     
//     public boolean isAnchorInFunction(int anAnchor) {
//         GoloModule module = ((GoloParser.GoloParserResult) parserResult).getModule();
// 
//         Set<GoloFunction> functions = module.getFunctions();
//         for (GoloFunction fn : functions) {
//             if (!fn.getName().startsWith("__$$_") && fn.hasASTNode()) {
//                 GoloASTNode astNode = fn.getASTNode();
//                 OffsetRange range = GoloASTUtils.getRange(astNode, doc);
//                 if (range.containsInclusive(anAnchor)) {
//                     return true;
//                 }
//             }
//         }
//         return false;
//     }
//     
//     public List<File> getGoloFiles(FileObject sourceFile) {
//         Project owner = FileOwnerQuery.getOwner(sourceFile);
//         return getGoloFiles(owner.getProjectDirectory().getPath());
//     }
//     
//     public List<File> getGoloFiles(String dir) {
//          List<File> goloFiles = new ArrayList<>();
//         File file = new File(dir);
//         if (!file.exists()) {
//             System.out.println("Error: " + file.getAbsolutePath() + " does not exist.");
//         } else if (file.isDirectory()) {
//             File[] directoryFiles = file.listFiles();
//             if (directoryFiles != null) {
//                 for (File directoryFile : directoryFiles) {
//                     goloFiles.addAll(getGoloFiles(directoryFile.getAbsolutePath()));
//                 }
//             }
//         } else if (file.getName().endsWith(".golo")) {
//             goloFiles.add(file);
//         }
//         return goloFiles;
//     }
//     
//     private static URLClassLoader primaryClassLoader(List<String> classpath) throws MalformedURLException {
//         URL[] urls = new URL[classpath.size()];
//         int index = 0;
//         for (String element : classpath) {
//             urls[index] = new File(element).toURI().toURL();
//             index = index + 1;
//         }
//         return new URLClassLoader(urls);
//     }
//     
//     public GoloClassLoader getGoloClassLoader() {
//         List<String> classpath = new ArrayList<>();
//         classpath.add(".");
//         return getGoloClassLoader(classpath);
//     }
//     
//     public GoloClassLoader getGoloClassLoader(List<String> classpath) {
//         GoloClassLoader classLoader = null;
//         try {
//             URLClassLoader primaryClassLoader;
//             primaryClassLoader = primaryClassLoader(classpath);
//             classLoader = new GoloClassLoader(primaryClassLoader);
//         } catch (MalformedURLException ex) {
//             Exceptions.printStackTrace(ex);
//         }
//         return classLoader;
//     }
//     
//     public Map<Class<?>, FileObject> loadGoloFiles(FileObject sourceFile, GoloClassLoader loader) throws Throwable {
//         Project owner = FileOwnerQuery.getOwner(sourceFile);
//         return loadGoloFiles(owner.getProjectDirectory().getPath(), loader);
//     }
//     
//     public Map<Class<?>, FileObject> loadGoloFiles(String goloFile, GoloClassLoader loader) throws Throwable {
//         Map<Class<?>, FileObject> result = new HashMap<>();
//         List<File> goloFiles = getGoloFiles(goloFile);
//         if (goloFiles != null) {
//             for (File file : goloFiles) {
//                 try (FileInputStream in = new FileInputStream(file)) {
//                     Class<?> loadedClass = loader.load(file.getName(), in);
//                     result.put(loadedClass, FileUtil.toFileObject(file));
//                 } catch (GoloCompilationException e) {
//                 }
//             }
//         }
//         
//         return result;
//     }
// }


import org.gololang.netbeans.api.completion.util.CompletionContext;
import java.util.ArrayList;
import java.util.List;
import org.netbeans.modules.csl.api.CompletionProposal;
    private final NamedAugmentationCompletion namedAugmentationCompletion;
    
    public ProposalsCollector() {
        proposals = new ArrayList<>();
        keywordCompletion = new KeywordCompletion();
        functionCompletion = new FunctionCompletion();
        importMethodCompletion = new ImportCompletion();
        parameterCompletion = new ParameterCompletion();
        variableCompletion = new VariableCompletion();
        documentationCompletion = new DocumentationCompletion();
        moduleCompletion = new ModuleCompletion();
        namedAugmentationCompletion = new NamedAugmentationCompletion();
    }
    
    public void completeKeywords(CompletionContext completionRequest) {
        keywordCompletion.complete(proposals, completionRequest, completionRequest.getAnchor());
    }

    public void completeMethods(CompletionContext completionRequest) {
        functionCompletion.complete(proposals, completionRequest, completionRequest.getAnchor());
    }
    
    public List<CompletionProposal> getProposals() {
        return proposals;
    }

    public void completeMethodsFromImports(CompletionContext context) {
        importMethodCompletion.complete(proposals, context, context.getAnchor());
    }
    
// Path: src/org/gololang/netbeans/api/completion/util/CompletionContext.java
// public class CompletionContext {
//     
//     private final ParserResult parserResult;
//     private final FileObject sourceFile;
//     
//     private final String prefix;
//     private int anchor;
//     
//     public final int lexOffset;
//     public final BaseDocument doc;
//    
//     
//     public CompletionContext(
//             ParserResult parseResult,
//             String prefix,
//             int anchor,
//             int lexOffset,
//             BaseDocument doc) {
// 
//         this.parserResult = parseResult;
//         this.sourceFile = parseResult.getSnapshot().getSource().getFileObject();
//         this.prefix = prefix;
//         this.anchor = anchor;
//         this.lexOffset = lexOffset;
//         this.doc = doc;
//         
//     }
// 
//     public String getPrefix() {
//         return prefix;
//     }
// 
//     public int getAnchor() {
//         return anchor;
//     }
// 
//     public ParserResult getParserResult() {
//         return parserResult;
//     }
// 
//     public FileObject getSourceFile() {
//         return sourceFile;
//     }
//     
//     public boolean isAnchorInFunction() {
//         return isAnchorInFunction(anchor);
//     }
//     
//     public boolean isAnchorInFunction(int anAnchor) {
//         GoloModule module = ((GoloParser.GoloParserResult) parserResult).getModule();
// 
//         Set<GoloFunction> functions = module.getFunctions();
//         for (GoloFunction fn : functions) {
//             if (!fn.getName().startsWith("__$$_") && fn.hasASTNode()) {
//                 GoloASTNode astNode = fn.getASTNode();
//                 OffsetRange range = GoloASTUtils.getRange(astNode, doc);
//                 if (range.containsInclusive(anAnchor)) {
//                     return true;
//                 }
//             }
//         }
//         return false;
//     }
//     
//     public List<File> getGoloFiles(FileObject sourceFile) {
//         Project owner = FileOwnerQuery.getOwner(sourceFile);
//         return getGoloFiles(owner.getProjectDirectory().getPath());
//     }
//     
//     public List<File> getGoloFiles(String dir) {
//          List<File> goloFiles = new ArrayList<>();
//         File file = new File(dir);
//         if (!file.exists()) {
//             System.out.println("Error: " + file.getAbsolutePath() + " does not exist.");
//         } else if (file.isDirectory()) {
//             File[] directoryFiles = file.listFiles();
//             if (directoryFiles != null) {
//                 for (File directoryFile : directoryFiles) {
//                     goloFiles.addAll(getGoloFiles(directoryFile.getAbsolutePath()));
//                 }
//             }
//         } else if (file.getName().endsWith(".golo")) {
//             goloFiles.add(file);
//         }
//         return goloFiles;
//     }
//     
//     private static URLClassLoader primaryClassLoader(List<String> classpath) throws MalformedURLException {
//         URL[] urls = new URL[classpath.size()];
//         int index = 0;
//         for (String element : classpath) {
//             urls[index] = new File(element).toURI().toURL();
//             index = index + 1;
//         }
//         return new URLClassLoader(urls);
//     }
//     
//     public GoloClassLoader getGoloClassLoader() {
//         List<String> classpath = new ArrayList<>();
//         classpath.add(".");
//         return getGoloClassLoader(classpath);
//     }
//     
//     public GoloClassLoader getGoloClassLoader(List<String> classpath) {
//         GoloClassLoader classLoader = null;
//         try {
//             URLClassLoader primaryClassLoader;
//             primaryClassLoader = primaryClassLoader(classpath);
//             classLoader = new GoloClassLoader(primaryClassLoader);
//         } catch (MalformedURLException ex) {
//             Exceptions.printStackTrace(ex);
//         }
//         return classLoader;
//     }
//     
//     public Map<Class<?>, FileObject> loadGoloFiles(FileObject sourceFile, GoloClassLoader loader) throws Throwable {
//         Project owner = FileOwnerQuery.getOwner(sourceFile);
//         return loadGoloFiles(owner.getProjectDirectory().getPath(), loader);
//     }
//     
//     public Map<Class<?>, FileObject> loadGoloFiles(String goloFile, GoloClassLoader loader) throws Throwable {
//         Map<Class<?>, FileObject> result = new HashMap<>();
//         List<File> goloFiles = getGoloFiles(goloFile);
//         if (goloFiles != null) {
//             for (File file : goloFiles) {
//                 try (FileInputStream in = new FileInputStream(file)) {
//                     Class<?> loadedClass = loader.load(file.getName(), in);
//                     result.put(loadedClass, FileUtil.toFileObject(file));
//                 } catch (GoloCompilationException e) {
//                 }
//             }
//         }
//         
//         return result;
//     }
// }


// Path: src/org/gololang/netbeans/editor/completion/ProposalsCollector.java
import org.gololang.netbeans.api.completion.util.CompletionContext;
import java.util.ArrayList;
import java.util.List;
import org.netbeans.modules.csl.api.CompletionProposal;

    private final NamedAugmentationCompletion namedAugmentationCompletion;
    
    public ProposalsCollector() {
        proposals = new ArrayList<>();
        keywordCompletion = new KeywordCompletion();
        functionCompletion = new FunctionCompletion();
        importMethodCompletion = new ImportCompletion();
        parameterCompletion = new ParameterCompletion();
        variableCompletion = new VariableCompletion();
        documentationCompletion = new DocumentationCompletion();
        moduleCompletion = new ModuleCompletion();
        namedAugmentationCompletion = new NamedAugmentationCompletion();
    }
    
    public void completeKeywords(CompletionContext completionRequest) {
        keywordCompletion.complete(proposals, completionRequest, completionRequest.getAnchor());
    }

    public void completeMethods(CompletionContext completionRequest) {
        functionCompletion.complete(proposals, completionRequest, completionRequest.getAnchor());
    }
    
    public List<CompletionProposal> getProposals() {
        return proposals;
    }

    public void completeMethodsFromImports(CompletionContext context) {
        importMethodCompletion.complete(proposals, context, context.getAnchor());
    }
    
    public void completeParameters(CompletionContext context) {