@Override
 public void applyToDependentParsedCode(IParsedCode parsedCode) {
   if (parsedCode == null) {
     throw new IllegalArgumentException("parsedCode argument can't be null!");
   }
   if (parsedCode.getTopNode() instanceof XlsModuleSyntaxNode) {
     XlsModuleSyntaxNode xlsModuleSyntaxNode = (XlsModuleSyntaxNode) parsedCode.getTopNode();
     for (String value : getImports()) {
       xlsModuleSyntaxNode.addImport(value);
     }
   }
 }
  private TableSyntaxNode[] selectAndSortNodes(
      XlsModuleSyntaxNode moduleSyntaxNode,
      ISelector<ISyntaxNode> childSelector,
      Comparator<TableSyntaxNode> nodesComparator) {

    ArrayList<TableSyntaxNode> childSyntaxNodes = new ArrayList<TableSyntaxNode>();

    for (TableSyntaxNode tsn : moduleSyntaxNode.getXlsTableSyntaxNodes()) {

      if (childSelector == null || childSelector.select(tsn)) {
        childSyntaxNodes.add(tsn);
      }
    }

    TableSyntaxNode[] tableSyntaxNodes =
        childSyntaxNodes.toArray(new TableSyntaxNode[childSyntaxNodes.size()]);

    if (nodesComparator != null) {
      try {
        Arrays.sort(tableSyntaxNodes, nodesComparator);
      } catch (Exception e) {
        // ignore sort exceptions.
      }
    }
    return tableSyntaxNodes;
  }
  public IBoundCode bind(IParsedCode parsedCode, IBindingContextDelegator bindingContextDelegator) {

    XlsModuleSyntaxNode moduleNode = (XlsModuleSyntaxNode) parsedCode.getTopNode();

    OpenL openl = null;

    try {
      openl = makeOpenL(moduleNode);
    } catch (OpenConfigurationException ex) {

      OpenlSyntaxNode syntaxNode = moduleNode.getOpenlNode();

      SyntaxNodeException error =
          SyntaxNodeExceptionUtils.createError("Error Creating OpenL", ex, syntaxNode);
      BindHelper.processError(error);

      return BindHelper.makeInvalidCode(parsedCode, syntaxNode, new SyntaxNodeException[] {error});
    }

    IOpenBinder openlBinder = openl.getBinder();
    IBindingContext bindingContext = openlBinder.makeBindingContext();
    bindingContext = BindHelper.delegateContext(bindingContext, bindingContextDelegator);

    if (parsedCode.getExternalParams() != null) {
      bindingContext.setExternalParams(parsedCode.getExternalParams());
    }

    IBoundNode topNode = null;

    if (!parsedCode.getCompiledDependencies().isEmpty()) {
      topNode =
          bindWithDependencies(
              moduleNode, openl, bindingContext, parsedCode.getCompiledDependencies());
    } else {
      topNode = bind(moduleNode, openl, bindingContext);
    }

    return new BoundCode(parsedCode, topNode, bindingContext.getErrors(), 0);
  }
  private TableSyntaxNode[] selectSpreadsheetNodes(
      XlsModuleSyntaxNode moduleSyntaxNode, ISelector<ISyntaxNode> childSelector) {

    ArrayList<TableSyntaxNode> childSyntaxNodes = new ArrayList<TableSyntaxNode>();

    for (TableSyntaxNode tsn : moduleSyntaxNode.getXlsTableSyntaxNodes()) {

      if (childSelector == null || childSelector.select(tsn)) {
        childSyntaxNodes.add(tsn);
      }
    }

    return childSyntaxNodes.toArray(new TableSyntaxNode[childSyntaxNodes.size()]);
  }
  private OpenL makeOpenL(XlsModuleSyntaxNode moduleNode) {

    String openlName = getOpenLName(moduleNode.getOpenlNode());
    Collection<String> imports = moduleNode.getImports();

    if (imports == null) {
      return OpenL.getInstance(openlName, userContext);
    }

    OpenLBuilderImpl builder = new OpenLBuilderImpl();

    builder.setExtendsCategory(openlName);

    String category = openlName + "::" + moduleNode.getModule().getUri();
    builder.setCategory(category);

    addImports(builder, imports);

    builder.setContexts(null, userContext);
    builder.setInheritExtendedConfigurationLoader(true);

    return OpenL.getInstance(category, userContext, builder);
  }
  private IVocabulary makeVocabulary(XlsModuleSyntaxNode moduleNode) {

    final IdentifierNode vocabularyNode = moduleNode.getVocabularyNode();

    if (vocabularyNode == null) {
      return null;
    }

    final ClassLoader userClassLoader = userContext.getUserClassLoader();
    Thread.currentThread().setContextClassLoader(userClassLoader);

    IVocabulary vocabulary =
        (IVocabulary)
            userContext.execute(
                new IExecutable() {

                  public Object execute() {

                    String vocabularyClassName = vocabularyNode.getIdentifier();

                    try {
                      Class<?> vClass = userClassLoader.loadClass(vocabularyClassName);

                      return vClass.newInstance();
                    } catch (Throwable t) {
                      String message =
                          String.format(
                              "Vocabulary type '%s' cannot be loaded", vocabularyClassName);
                      BindHelper.processError(message, vocabularyNode, t);

                      return null;
                    }
                  }
                });
    return vocabulary;
  }
 private void initImports(XlsModuleSyntaxNode xlsModuleSyntaxNode) {
   imports.addAll(xlsModuleSyntaxNode.getImports());
 }