/**
   * Generates interface class using methods and fields of given IOpenClass instance.
   *
   * @throws Exception if an error has occurred
   */
  public static Class<?> generateInterface(
      String className,
      IOpenClass openClass,
      ClassLoader classLoader,
      String[] includes,
      String[] excludes)
      throws Exception {

    if (openClass == null) {
      return generateInterface(className, EMPTY_RULES, classLoader);
    }

    List<RuleInfo> rules = new ArrayList<RuleInfo>();

    final Collection<IOpenMethod> methods = openClass.getMethods();
    for (IOpenMethod method : methods) {

      if (!isIgnoredMember(method)) {
        RuleInfo ruleInfo = getRuleInfoForMethod(method);
        boolean isMember = isMember(ruleInfo, includes, excludes);
        if (isMember) {
          rules.add(ruleInfo);
        }
      }
    }

    final Collection<IOpenField> fields = openClass.getFields().values();
    for (IOpenField field : fields) {

      if (!isIgnoredMember(field)) {

        if (field.isReadable()) {
          RuleInfo ruleInfo = getRuleInfoForField(field);
          boolean isMember = isMember(ruleInfo, includes, excludes);
          if (isMember) {
            rules.add(ruleInfo);
          }
        }
      }
    }

    return generateInterface(className, rules.toArray(new RuleInfo[rules.size()]), classLoader);
  }
  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);
            }
          }
        }
      }
    }
  }