/** Constructor for module with dependent modules */
 public XlsModuleOpenClass(
     String name,
     XlsMetaInfo metaInfo,
     OpenL openl,
     IDataBase dbase,
     Set<CompiledDependency> usingModules,
     ClassLoader classLoader,
     boolean useDescisionTableDispatcher,
     boolean dispatchingValidationEnabled) {
   super(name, openl);
   this.dataBase = dbase;
   this.metaInfo = metaInfo;
   this.useDescisionTableDispatcher = useDescisionTableDispatcher;
   this.dispatchingValidationEnabled = dispatchingValidationEnabled;
   this.classLoader = classLoader;
   if (usingModules != null) {
     setDependencies(usingModules);
     initDependencies();
   }
   initImports(metaInfo.getXlsModuleNode());
 }
  /**
   * 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);
      }
    }
  }