private void addDuplicatedMethodError(
      String message, IOpenMethod method, IOpenMethod existedMethod) {
    ISyntaxNode newMethodSyntaxNode = method.getInfo().getSyntaxNode();
    if (newMethodSyntaxNode instanceof TableSyntaxNode) {
      SyntaxNodeException error =
          SyntaxNodeExceptionUtils.createError(message, newMethodSyntaxNode);
      ((TableSyntaxNode) newMethodSyntaxNode).addError(error);

      try {
        TableSyntaxNode existedMethodSyntaxNode =
            (TableSyntaxNode) existedMethod.getInfo().getSyntaxNode();
        if (existedMethodSyntaxNode != null) {
          existedMethodSyntaxNode.addError(
              SyntaxNodeExceptionUtils.createError(message, existedMethodSyntaxNode));
        }
      } catch (Exception ex) {
        log.warn(
            "Cannot get a syntax node for the method: {}",
            MethodUtil.printMethod(existedMethod, new StringBuilder()),
            ex);
      }

      addError(error);
    } else {
      addError(new DuplicatedMethodException(message, method));
    }
  }
 public void preBind() {
   try {
     preBindeding = true;
     try {
       moduleContext.pushErrors();
       IMemberBoundNode memberBoundNode =
           XlsBinder.this.beginBind(tableSyntaxNode, module, openl, moduleContext);
       childrens[index] = memberBoundNode;
       if (memberBoundNode != null) {
         try {
           memberBoundNode.addTo(module);
         } catch (OpenlNotCheckedException e) {
           SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(e, tableSyntaxNode);
           processError(error, tableSyntaxNode, moduleContext);
         }
       }
     } finally {
       List<SyntaxNodeException> syntaxNodeExceptions = moduleContext.popErrors();
       for (SyntaxNodeException e : syntaxNodeExceptions) {
         addModuleContextError(e); // Workaround for syntax node
         // errors
       }
     }
     if (recursiveOpenMethodPreBinderMethods != null) {
       for (RecursiveOpenMethodPreBinder recursiveOpenMethodPreBinderMethod :
           recursiveOpenMethodPreBinderMethods) {
         recursiveOpenMethodPreBinderMethod.preBind();
       }
     }
   } finally {
     preBindeding = false;
   }
 }
  protected IMemberBoundNode beginBind(
      TableSyntaxNode tableSyntaxNode,
      XlsModuleOpenClass module,
      OpenL openl,
      RulesModuleBindingContext moduleContext) {

    try {
      return preBindXlsNode(tableSyntaxNode, openl, moduleContext, module);

    } catch (SyntaxNodeException error) {
      processError(error, tableSyntaxNode, moduleContext);

      return null;

    } catch (CompositeSyntaxNodeException ex) {

      for (SyntaxNodeException error : ex.getErrors()) {
        processError(error, tableSyntaxNode, moduleContext);
      }

      return null;

    } catch (Throwable t) {

      SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(t, tableSyntaxNode);
      processError(error, tableSyntaxNode, moduleContext);

      return null;
    }
  }
  protected void removeDebugInformation(
      IMemberBoundNode[] boundNodes,
      TableSyntaxNode[] tableSyntaxNodes,
      RulesModuleBindingContext moduleContext) {
    for (int i = 0; i < boundNodes.length; i++) {
      if (boundNodes[i] != null) {
        try {
          boundNodes[i].removeDebugInformation(moduleContext);

        } catch (SyntaxNodeException error) {
          processError(error, tableSyntaxNodes[i], moduleContext);

        } catch (CompositeSyntaxNodeException ex) {

          for (SyntaxNodeException error : ex.getErrors()) {
            processError(error, tableSyntaxNodes[i], moduleContext);
          }

        } catch (Throwable t) {

          SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(t, tableSyntaxNodes[i]);
          processError(error, tableSyntaxNodes[i], moduleContext);
        }
      }
    }
  }
 private OpenMethodHeader addMethodHeaderToContext(
     XlsModuleOpenClass module,
     TableSyntaxNode tableSyntaxNode,
     OpenL openl,
     RulesModuleBindingContext moduleContext,
     IMemberBoundNode[] children,
     int index) {
   try {
     AExecutableNodeBinder aExecutableNodeBinder =
         (AExecutableNodeBinder) getBinderFactory().get(tableSyntaxNode.getType());
     IOpenSourceCodeModule source =
         aExecutableNodeBinder.createHeaderSource(tableSyntaxNode, moduleContext);
     OpenMethodHeader openMethodHeader =
         (OpenMethodHeader) OpenLManager.makeMethodHeader(openl, source, moduleContext);
     XlsBinderExecutableMethodBind xlsBinderExecutableMethodBind =
         new XlsBinderExecutableMethodBind(
             module, openl, tableSyntaxNode, children, index, openMethodHeader, moduleContext);
     moduleContext.addBinderMethod(openMethodHeader, xlsBinderExecutableMethodBind);
     return openMethodHeader;
   } catch (Exception e) {
     SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(e, tableSyntaxNode);
     processError(error, tableSyntaxNode, moduleContext);
   }
   return null;
 }
  private void bindPropertiesForAllTables(
      XlsModuleSyntaxNode moduleNode,
      XlsModuleOpenClass module,
      OpenL openl,
      RulesModuleBindingContext bindingContext) {
    ASelector<ISyntaxNode> propertiesSelector = getSelector(XlsNodeTypes.XLS_PROPERTIES);
    ASelector<ISyntaxNode> otherNodesSelector = getSelector(XlsNodeTypes.XLS_OTHER);
    ISelector<ISyntaxNode> notPropertiesAndNotOtherSelector =
        propertiesSelector.not().and(otherNodesSelector.not());

    TableSyntaxNode[] tableSyntaxNodes = selectNodes(moduleNode, notPropertiesAndNotOtherSelector);

    PropertiesLoader propLoader = new PropertiesLoader(openl, bindingContext, module);
    for (TableSyntaxNode tsn : tableSyntaxNodes) {
      try {
        propLoader.loadProperties(tsn);
      } catch (SyntaxNodeException error) {
        processError(error, tsn, bindingContext);
      } catch (CompositeSyntaxNodeException ex) {
        for (SyntaxNodeException error : ex.getErrors()) {
          processError(error, tsn, bindingContext);
        }
      } catch (Throwable t) {
        SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(t, tsn);
        processError(error, tsn, bindingContext);
      }
    }
  }
  @Override
  public ValidationResult validateTables(
      OpenL openl, TableSyntaxNode[] tableSyntaxNodes, IOpenClass openClass) {
    ValidationResult validationResult = null;

    // Group methods not TableSyntaxNodes as we may have dependent modules,
    // and no sources for them,
    // represented in current module. The only information about dependency
    // methods contains in openClass.
    //
    Map<DimensionPropertiesMethodKey, List<TableSyntaxNode>> groupedMethods =
        groupExecutableMethods(tableSyntaxNodes);

    for (DimensionPropertiesMethodKey key : groupedMethods.keySet()) {
      List<TableSyntaxNode> methodsGroup = groupedMethods.get(key);
      List<TableSyntaxNode> activeExecutableMethodTable = new ArrayList<TableSyntaxNode>();
      int activeTableFoundCount = 0;

      for (TableSyntaxNode executableMethodTable : methodsGroup) {
        if (executableMethodTable.getMember() instanceof TestSuiteMethod) {
          activeTableFoundCount++;
          break;
        }
        if (executableMethodTable.getTableProperties() != null && isActive(executableMethodTable)) {
          activeExecutableMethodTable.add(executableMethodTable);
          activeTableFoundCount++;
        }
      }

      if (activeTableFoundCount > 1) {
        if (validationResult == null) {
          validationResult = new ValidationResult(ValidationStatus.FAIL);
        }
        for (TableSyntaxNode executableMethodTable : activeExecutableMethodTable) {
          SyntaxNodeException exception =
              SyntaxNodeExceptionUtils.createError(ODD_ACTIVE_TABLE_MESSAGE, executableMethodTable);
          executableMethodTable.addError(exception);
          ValidationUtils.addValidationMessage(validationResult, new OpenLErrorMessage(exception));
        }
      }

      if (activeTableFoundCount == 0) {
        if (validationResult == null) {
          validationResult = new ValidationResult(ValidationStatus.SUCCESS);
        }
        // warning is attached to all table syntax node

        for (TableSyntaxNode tsn : methodsGroup) {
          ValidationUtils.addValidationMessage(
              validationResult, new OpenLWarnMessage(NO_ACTIVE_TABLE_MESSAGE, tsn));
        }
      }
    }

    if (validationResult != null) {
      return validationResult;
    } else {
      return ValidationUtils.validationSuccess();
    }
  }
  protected IBoundNode bindInternal(
      XlsModuleSyntaxNode moduleSyntaxNode,
      XlsModuleOpenClass module,
      TableSyntaxNode[] tableSyntaxNodes,
      OpenL openl,
      RulesModuleBindingContext moduleContext) {

    IMemberBoundNode[] children = new IMemberBoundNode[tableSyntaxNodes.length];
    OpenMethodHeader[] openMethodHeaders = new OpenMethodHeader[tableSyntaxNodes.length];

    for (int i = 0;
        i < tableSyntaxNodes.length;
        i++) { // Add methods that should be compiled recursively
      if (isExecutableTableSyntaxNode(tableSyntaxNodes[i])) {
        openMethodHeaders[i] =
            addMethodHeaderToContext(
                module, tableSyntaxNodes[i], openl, moduleContext, children, i);
      }
    }

    for (int i = 0; i < tableSyntaxNodes.length; i++) {
      if (!isExecutableTableSyntaxNode(tableSyntaxNodes[i])) {
        IMemberBoundNode child = beginBind(tableSyntaxNodes[i], module, openl, moduleContext);
        children[i] = child;
        if (child != null) {
          try {
            child.addTo(module);
          } catch (OpenlNotCheckedException e) {
            SyntaxNodeException error =
                SyntaxNodeExceptionUtils.createError(e, tableSyntaxNodes[i]);
            processError(error, tableSyntaxNodes[i], moduleContext);
          }
        }
      }
    }

    for (int i = 0; i < children.length; i++) {
      if (isExecutableTableSyntaxNode(tableSyntaxNodes[i])) {
        moduleContext.preBindMethod(openMethodHeaders[i]);
      }
    }

    for (int i = 0; i < children.length; i++) {
      if (children[i] != null) {
        finilizeBind(children[i], tableSyntaxNodes[i], moduleContext);
      }
    }

    processModuleContextErrors(moduleContext);

    if (moduleContext.isExecutionMode()) {
      removeDebugInformation(children, tableSyntaxNodes, moduleContext);
    }

    return new ModuleNode(moduleSyntaxNode, moduleContext.getModule());
  }
 /**
  * Creates {@link RulesModuleBindingContext} and populates it with types from dependent modules.
  *
  * @param moduleNode just for processing error
  * @param bindingContext
  * @param moduleDependencies
  * @param moduleOpenClass
  * @return {@link RulesModuleBindingContext} created with bindingContext and moduleOpenClass.
  */
 private RulesModuleBindingContext populateBindingContextWithDependencies(
     XlsModuleSyntaxNode moduleNode,
     IBindingContext bindingContext,
     Set<CompiledDependency> moduleDependencies,
     XlsModuleOpenClass moduleOpenClass) {
   RulesModuleBindingContext moduleContext =
       createRulesBindingContext(bindingContext, moduleOpenClass);
   try {
     moduleContext.addTypes(
         filterDependencyTypes(moduleOpenClass.getTypes(), moduleContext.getInternalTypes()));
   } catch (Exception ex) {
     SyntaxNodeException error =
         SyntaxNodeExceptionUtils.createError(
             "Can`t add datatype from dependency", ex, moduleNode);
     BindHelper.processError(error);
   }
   return moduleContext;
 }
  protected void finilizeBind(
      IMemberBoundNode memberBoundNode,
      TableSyntaxNode tableSyntaxNode,
      RulesModuleBindingContext moduleContext) {

    try {
      memberBoundNode.finalizeBind(moduleContext);
    } catch (SyntaxNodeException error) {
      processError(error, tableSyntaxNode, moduleContext);
    } catch (CompositeSyntaxNodeException ex) {
      if (ex.getErrors() != null) {
        for (SyntaxNodeException error : ex.getErrors()) {
          processError(error, tableSyntaxNode, moduleContext);
        }
      }
    } catch (Throwable t) {
      SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(t, tableSyntaxNode);
      processError(error, tableSyntaxNode, moduleContext);
    }
  }
  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);
  }
  /**
   * Common binding cycle.
   *
   * @param moduleNode
   * @param openl
   * @param moduleContext
   * @param moduleOpenClass
   * @param bindingContext
   * @return
   */
  private IBoundNode processBinding(
      XlsModuleSyntaxNode moduleNode,
      OpenL openl,
      RulesModuleBindingContext moduleContext,
      XlsModuleOpenClass moduleOpenClass,
      IBindingContext bindingContext) {

    IVocabulary vocabulary = makeVocabulary(moduleNode);

    if (vocabulary != null) {
      processVocabulary(vocabulary, moduleContext);
    }

    //
    // Selectors
    //
    ASelector<ISyntaxNode> propertiesSelector = getSelector(XlsNodeTypes.XLS_PROPERTIES);
    ASelector<ISyntaxNode> dataTypeSelector = getSelector(XlsNodeTypes.XLS_DATATYPE);

    ISelector<ISyntaxNode> notPropertiesAndNotDatatypeSelector =
        propertiesSelector.not().and(dataTypeSelector.not());

    ISelector<ISyntaxNode> spreadsheetSelector = getSelector(XlsNodeTypes.XLS_SPREADSHEET);
    ISelector<ISyntaxNode> testMethodSelector = getSelector(XlsNodeTypes.XLS_TEST_METHOD);
    ISelector<ISyntaxNode> runMethodSelector = getSelector(XlsNodeTypes.XLS_RUN_METHOD);

    ISelector<ISyntaxNode> commonTablesSelector =
        notPropertiesAndNotDatatypeSelector.and(
            spreadsheetSelector.not().and(testMethodSelector.not().and(runMethodSelector.not())));

    // Bind property node at first.
    //
    TableSyntaxNode[] propertiesNodes = selectNodes(moduleNode, propertiesSelector);
    bindInternal(moduleNode, moduleOpenClass, propertiesNodes, openl, moduleContext);

    bindPropertiesForAllTables(moduleNode, moduleOpenClass, openl, moduleContext);

    IBoundNode topNode = null;

    // Bind datatype nodes.
    TableSyntaxNode[] datatypeNodes = selectNodes(moduleNode, dataTypeSelector);

    /*
     * Processes datatype table nodes before the bind operation. Checks type
     * declarations and finds invalid using of inheritance feature at this
     * step.
     */
    TableSyntaxNode[] processedDatatypeNodes =
        new DatatypesSorter()
            .sort(
                datatypeNodes,
                moduleContext); // Rewrite this sorter with TableSyntaxNodeRelationsUtils

    bindInternal(moduleNode, moduleOpenClass, processedDatatypeNodes, openl, moduleContext);

    // Select nodes excluding Properties, Datatype, Spreadsheet, Test,
    // RunMethod tables
    TableSyntaxNode[] commonTables = selectNodes(moduleNode, commonTablesSelector);

    // Select and sort Spreadsheet tables
    TableSyntaxNode[] spreadsheets = selectSpreadsheetNodes(moduleNode, spreadsheetSelector);
    if (OpenLSystemProperties.isCustomSpreadsheetType(bindingContext.getExternalParams())) {
      try {
        spreadsheets =
            TableSyntaxNodeRelationsUtils.sort(
                spreadsheets, new SpreadsheetTableSyntaxNodeRelationsDeterminer());
      } catch (TableSyntaxNodeCircularDependencyException e) {
        for (TableSyntaxNode tsn : e.getTableSyntaxNodes()) {
          SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(e, tsn);
          processError(error, tsn, moduleContext);
        }
      }
    }

    TableSyntaxNode[] commonAndSpreadsheetTables = ArrayUtils.addAll(commonTables, spreadsheets);
    bindInternal(moduleNode, moduleOpenClass, commonAndSpreadsheetTables, openl, moduleContext);

    // Select Test and RunMethod tables
    TableSyntaxNode[] runTables = selectNodes(moduleNode, runMethodSelector);
    bindInternal(moduleNode, moduleOpenClass, runTables, openl, moduleContext);

    TableSyntaxNode[] testTables = selectNodes(moduleNode, testMethodSelector);
    topNode = bindInternal(moduleNode, moduleOpenClass, testTables, openl, moduleContext);

    if (moduleOpenClass.isUseDescisionTableDispatcher()) {
      DispatcherTablesBuilder dispTableBuilder =
          new DispatcherTablesBuilder((XlsModuleOpenClass) topNode.getType(), moduleContext);
      dispTableBuilder.build();
    }

    ((XlsModuleOpenClass) topNode.getType()).setRulesModuleBindingContext(moduleContext);
    ((XlsModuleOpenClass) topNode.getType()).completeOpenClassBuilding();

    processErrors(moduleOpenClass.getErrors(), bindingContext);

    return topNode;
  }
  @SuppressWarnings("unchecked")
  public static IConditionEvaluator makeEvaluator(
      ICondition condition, IOpenClass methodType, IBindingContext bindingContext)
      throws SyntaxNodeException {

    IParameterDeclaration[] params = condition.getParams();

    switch (params.length) {
      case 1:
        IOpenClass paramType = params[0].getType();

        IOpenCast openCast = bindingContext.getCast(paramType, methodType);

        if (openCast != null) {
          return new EqualsIndexedEvaluator(openCast);
        }

        IAggregateInfo aggregateInfo = paramType.getAggregateInfo();

        if (aggregateInfo.isAggregate(paramType)
            && aggregateInfo.getComponentType(paramType).isAssignableFrom(methodType)) {
          return new ContainsInArrayIndexedEvaluator();
        }

        IRangeAdaptor<? extends Object, ? extends Comparable<?>> rangeAdaptor =
            getRangeAdaptor(methodType, paramType);

        if (rangeAdaptor != null) {
          return new RangeIndexedEvaluator(
              (IRangeAdaptor<Object, ? extends Comparable<Object>>) rangeAdaptor, 1);
        }

        if (JavaOpenClass.BOOLEAN.equals(methodType)
            || JavaOpenClass.getOpenClass(Boolean.class).equals(methodType)) {
          return new DefaultConditionEvaluator();
        }

        break;

      case 2:
        IOpenClass paramType0 = params[0].getType();
        IOpenClass paramType1 = params[1].getType();

        if (methodType == paramType0 && methodType == paramType1) {

          Class<?> clazz = methodType.getInstanceClass();

          if (clazz != short.class
              && clazz != byte.class
              && clazz != int.class
              && clazz != long.class
              && clazz != double.class
              && clazz != float.class
              && !Comparable.class.isAssignableFrom(clazz)) {
            String message = String.format("Type '%s' is not Comparable", methodType.getName());
            throw SyntaxNodeExceptionUtils.createError(
                message, null, null, condition.getSourceCodeModule());
          }

          return new RangeIndexedEvaluator(null, 2);
        }

        aggregateInfo = paramType1.getAggregateInfo();

        if (aggregateInfo.isAggregate(paramType1)
            && aggregateInfo.getComponentType(paramType1) == methodType) {

          BooleanTypeAdaptor booleanTypeAdaptor = BooleanAdaptorFactory.getAdaptor(paramType0);

          if (booleanTypeAdaptor != null) {
            return new ContainsInOrNotInArrayIndexedEvaluator(booleanTypeAdaptor);
          }
        }

        if (JavaOpenClass.BOOLEAN.equals(methodType)
            || JavaOpenClass.getOpenClass(Boolean.class).equals(methodType)) {
          return new DefaultConditionEvaluator();
        }

        break;
    }

    List<String> names = new ArrayList<String>();

    for (IParameterDeclaration parameterDeclaration : params) {

      String name = parameterDeclaration.getType().getName();
      names.add(name);
    }

    String parametersString = StringUtils.join(names, ",");

    String message =
        String.format(
            "Can not make a Condition Evaluator for parameter %s and [%s]",
            methodType.getName(), parametersString);

    throw SyntaxNodeExceptionUtils.createError(
        message, null, null, condition.getSourceCodeModule());
  }
  /**
   * Adds method to <code>XlsModuleOpenClass</code>.
   *
   * @param method method object
   */
  @Override
  public void addMethod(IOpenMethod method) {
    if (method instanceof OpenMethodDispatcher) {
      addDispatcherMethod((OpenMethodDispatcher) method);
      return;
    }
    IOpenMethod m = decorateForMultimoduleDispatching(method);

    // Workaround needed to set the module name in the method while compile
    if (m instanceof AMethod) {
      if (((AMethod) m).getModuleName() == null) {
        XlsMetaInfo metaInfo = getXlsMetaInfo();
        if (metaInfo != null) {
          IOpenSourceCodeModule sourceCodeModule = metaInfo.getXlsModuleNode().getModule();
          if (sourceCodeModule instanceof IModuleInfo) {
            ((AMethod) m).setModuleName(((IModuleInfo) sourceCodeModule).getModuleName());
          }
        }
      }
    }

    // Checks that method already exists in the class. If it already
    // exists then "overload" it using decorator; otherwise - just add to
    // the class.
    //
    IOpenMethod existedMethod =
        getDeclaredMethod(method.getName(), method.getSignature().getParameterTypes());
    if (existedMethod != null) {

      if (!existedMethod.getType().equals(method.getType())) {
        String message =
            String.format(
                "Method \"%s\" with return type \"%s\" has already been defined with another return type (\"%s\")",
                method.getName(),
                method.getType().getDisplayName(0),
                existedMethod.getType().getDisplayName(0));
        addDuplicatedMethodError(message, method, existedMethod);
        return;
      }

      if (method != existedMethod && method instanceof TestSuiteMethod) {
        validateTestSuiteMethod(method, existedMethod);
        return;
      }

      // Checks the instance of existed method. If it's the
      // OpenMethodDecorator then just add the method-candidate to
      // decorator; otherwise - replace existed method with new instance
      // of OpenMethodDecorator for existed method and add new one.
      //
      try {
        if (existedMethod instanceof OpenMethodDispatcher) {
          OpenMethodDispatcher decorator = (OpenMethodDispatcher) existedMethod;
          decorator.addMethod(undecorateForMultimoduleDispatching(m));
        } else {
          if (m != existedMethod) {
            // Create decorator for existed method.
            //
            OpenMethodDispatcher dispatcher = getOpenMethodDispatcher(existedMethod);

            IOpenMethod openMethod = decorateForMultimoduleDispatching(dispatcher);

            overrideMethod(openMethod);

            dispatcher.addMethod(undecorateForMultimoduleDispatching(m));
          }
        }
      } catch (DuplicatedMethodException e) {
        SyntaxNodeException error = null;
        if (m instanceof IMemberMetaInfo) {
          IMemberMetaInfo memberMetaInfo = (IMemberMetaInfo) m;
          if (memberMetaInfo.getSyntaxNode() != null) {
            if (memberMetaInfo.getSyntaxNode() instanceof TableSyntaxNode) {
              error =
                  SyntaxNodeExceptionUtils.createError(
                      e.getMessage(), e, memberMetaInfo.getSyntaxNode());
              ((TableSyntaxNode) memberMetaInfo.getSyntaxNode()).addError(error);
            }
          }
        }
        boolean f = false;
        for (Throwable t : getErrors()) {
          if (t.getMessage().equals(e.getMessage())) {
            f = true;
            break;
          }
        }
        if (!f) {
          if (error != null) {
            addError(error);
          } else {
            addError(e);
          }
        }
      }
    } else {
      // Just wrap original method with dispatcher functionality.
      //

      if (dispatchingValidationEnabled
          && !(m instanceof TestSuiteMethod)
          && dimensionalPropertyPresented(m)) {
        // Create dispatcher for existed method.
        //
        OpenMethodDispatcher dispatcher = getOpenMethodDispatcher(m);

        IOpenMethod openMethod = decorateForMultimoduleDispatching(dispatcher);

        super.addMethod(openMethod);

      } else {
        super.addMethod(m);
      }
    }
  }
  private void addDataTables(CompiledOpenClass dependency) {
    IOpenClass openClass = dependency.getOpenClassWithErrors();

    Map<String, IOpenField> fieldsMap = openClass.getFields();

    Set<String> tableUrls = new HashSet<String>();
    Map<String, IOpenField> fields = getFields();
    for (IOpenField openField : fields.values()) {
      if (openField instanceof DataOpenField) {
        tableUrls.add(((DataOpenField) openField).getTableUri());
      }
    }
    for (String key : fieldsMap.keySet()) {
      IOpenField field = fieldsMap.get(key);
      if (field instanceof DataOpenField) {
        DataOpenField dataOpenField = (DataOpenField) field;
        try {
          String tableUrl = dataOpenField.getTableUri();
          // Test tables are added both as methods and variables.
          if (!tableUrls.contains(tableUrl) && !duplicatedMethodUrls.contains(tableUrl)) {
            boolean containsInDependency = false;
            if (VirtualSourceCodeModule.SOURCE_URI.equals(metaInfo.getSourceUrl())) {
              for (CompiledDependency d : getDependencies()) {
                IOpenClass dependentModuleClass = d.getCompiledOpenClass().getOpenClassWithErrors();
                if (dependentModuleClass instanceof XlsModuleOpenClass) {
                  if (((XlsModuleOpenClass) dependentModuleClass)
                      .duplicatedMethodUrls.contains(tableUrl)) {
                    containsInDependency = true;
                    break;
                  }
                }
              }
            }
            if (!containsInDependency) {
              addField(field);
              tableUrls.add(tableUrl);
            }
          }
        } catch (OpenlNotCheckedException e) {
          SyntaxNodeException error =
              SyntaxNodeExceptionUtils.createError(
                  e.getMessage(), e, dataOpenField.getTable().getTableSyntaxNode());
          addError(error);
        }
      }
    }

    if (openClass instanceof XlsModuleOpenClass) {
      XlsModuleOpenClass xlsModuleOpenClass = (XlsModuleOpenClass) openClass;
      if (xlsModuleOpenClass.getDataBase() != null) {
        for (ITable table : xlsModuleOpenClass.getDataBase().getTables()) {
          if (XlsNodeTypes.XLS_DATA.toString().equals(table.getTableSyntaxNode().getType())) {
            try {
              getDataBase().registerTable(table);
            } catch (DuplicatedTableException e) {
              addError(e);
            } catch (OpenlNotCheckedException e) {
              addError(e);
            }
          }
        }
      }
    }
  }