@Test
  public void testNotProcessingInheritPropertiesForTableType() {
    String tableName = "Rules void hello2(int hour)";
    TableSyntaxNode resultTsn = findTable(tableName);
    if (resultTsn != null) {
      ITableProperties tableProperties = resultTsn.getTableProperties();
      assertNotNull(tableProperties);

      Map<String, Object> categoryProperties = tableProperties.getPropertiesAppliedForCategory();
      assertTrue(categoryProperties.size() == 5);
      // check that we have all properties from category level
      assertEquals(
          InheritanceLevel.CATEGORY.getDisplayName(), (String) categoryProperties.get("scope"));
      assertEquals("My Category", (String) categoryProperties.get("category"));
      assertEquals("newLob", (String) categoryProperties.get("lob"));
      assertEquals(
          UsRegionsEnum.SE.name(),
          ((UsRegionsEnum[]) categoryProperties.get("usregion"))[0].name());
      assertEquals(
          RegionsEnum.NCSA.name(), ((RegionsEnum[]) categoryProperties.get("region"))[0].name());

      Map<String, Object> allProperties = tableProperties.getAllProperties();
      assertEquals(
          "AllProperties size is 10, ignore property 'scope' and including default properties",
          8,
          allProperties.size());
      assertTrue(
          "There is no property 'scope' applied for this table, as it can`t be defined in such table type",
          !allProperties.containsKey("scope"));

    } else {
      fail();
    }
  }
 private boolean isExecutableTableSyntaxNode(TableSyntaxNode tableSyntaxNode) {
   return XlsNodeTypes.XLS_DT.equals(tableSyntaxNode.getNodeType())
       || XlsNodeTypes.XLS_TBASIC.equals(tableSyntaxNode.getNodeType())
       || XlsNodeTypes.XLS_METHOD.equals(tableSyntaxNode.getNodeType())
       || XlsNodeTypes.XLS_COLUMN_MATCH.equals(tableSyntaxNode.getNodeType())
       || XlsNodeTypes.XLS_SPREADSHEET.equals(tableSyntaxNode.getNodeType());
 }
  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));
    }
  }
  @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();
    }
  }
  @Test
  public void testErrorParsing() {
    String tableName = "Rules void hello1(int hour)";
    TableSyntaxNode resultTsn = findTable(tableName);
    if (resultTsn != null) {
      ITableProperties tableProperties = resultTsn.getTableProperties();
      assertNotNull(tableProperties);

      assertEquals(5, tableProperties.getAllProperties().size());

    } else {
      fail();
    }
  }
 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;
 }
  protected void processError(
      SyntaxNodeException error,
      TableSyntaxNode tableSyntaxNode,
      RulesModuleBindingContext moduleContext) {

    tableSyntaxNode.addError(error);
    BindHelper.processError(error, moduleContext);
  }
  private Map<DimensionPropertiesMethodKey, List<TableSyntaxNode>> groupExecutableMethods(
      TableSyntaxNode[] tableSyntaxNodes) {
    Map<DimensionPropertiesMethodKey, List<TableSyntaxNode>> groupedMethods =
        new HashMap<DimensionPropertiesMethodKey, List<TableSyntaxNode>>();

    for (TableSyntaxNode tsn : tableSyntaxNodes) {
      if (tsn.getMember() instanceof ExecutableRulesMethod) {
        ExecutableRulesMethod executableMethod = (ExecutableRulesMethod) tsn.getMember();
        DimensionPropertiesMethodKey key = new DimensionPropertiesMethodKey(executableMethod);
        if (!groupedMethods.containsKey(key)) {
          groupedMethods.put(key, new ArrayList<TableSyntaxNode>());
        }
        groupedMethods.get(key).add(tsn);
      }
    }
    return groupedMethods;
  }
  public int getNumErrors() {
    int result = 0;

    TableSyntaxNode table = getTableSyntaxNode();
    if (table != null) {
      SyntaxNodeException errors[] = table.getErrors();

      if (errors != null) {
        return errors.length;
      }
    }

    Iterable<? extends ITreeElement<Object>> children = getChildren();
    for (ITreeElement<Object> treeNode : children) {
      if (treeNode instanceof ProjectTreeNode) {
        ProjectTreeNode projectTreeNode = (ProjectTreeNode) treeNode;
        result += projectTreeNode.getNumErrors();
      }
    }
    return result;
  }
 private boolean isActive(TableSyntaxNode executableMethodTable) {
   return Boolean.TRUE.equals(executableMethodTable.getTableProperties().getActive());
 }