/**
   * Compiles the given rule strings into a single rulebase
   *
   * @param rules
   * @return
   * @throws Exception
   */
  public static RuleBase compile(List<String> rules) throws Exception {
    Properties properties = new Properties();
    properties.setProperty("drools.dialect.java.compiler", "JANINO");
    properties.setProperty("drools.dialect.default", "java");
    properties.setProperty("drools.dialect.java.compiler.lnglevel", "1.5");

    // properties.setProperty("drools.dump.dir", "/tmp");
    // log.debug("drools.dump.dir value is set to " + dumpDir);

    PackageBuilderConfiguration conf = new PackageBuilderConfiguration(properties);
    PackageBuilder builder = new PackageBuilder(conf);
    RuleBase ruleBase = RuleBaseFactory.newRuleBase();

    for (String rule : rules) {
      StringReader drl = new StringReader(rule);
      builder.addPackageFromDrl(drl);
      PackageBuilderErrors errors = builder.getErrors();
      for (DroolsError error : errors.getErrors()) {
        log.warn(error);
      }
    }
    ruleBase.addPackage(builder.getPackage());
    return ruleBase;
  }
  public void execute() throws MojoExecutionException {
    // find all the rules items and load them into a package
    try {

      // Need to load the build classpath
      @SuppressWarnings("unchecked")
      List<Dependency> dependencies = project.getDependencies();
      List<URL> url = new ArrayList<URL>();
      url.add(outputDirectory.toURI().toURL());
      for (Dependency d : dependencies) {
        String scope = d.getScope();
        if (!Artifact.SCOPE_TEST.equals(scope)) {
          Artifact artifact =
              getArtifact(
                  d.getGroupId(),
                  d.getArtifactId(),
                  d.getVersion(),
                  d.getType(),
                  d.getClassifier());
          url.add(artifact.getFile().toURI().toURL());
        }
      }

      URL[] classpath = url.toArray(new URL[url.size()]);

      URLClassLoader uc =
          new URLClassLoader(classpath, this.getClass().getClassLoader()) {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
              getLog().debug("Loading Class for compile [" + name + "]");
              Class<?> c = super.loadClass(name);
              getLog().debug("Loading Class for compile [" + name + "] found [" + c + "]");
              return c;
            }

            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {
              getLog().debug("Finding Class for compile [" + name + "]");
              Class<?> c = super.findClass(name);
              getLog().debug("Finding Class for compile [" + name + "] found [" + c + "]");
              return c;
            }
          };
      URLClassLoader uc2 =
          new URLClassLoader(classpath, this.getClass().getClassLoader()) {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
              getLog().debug("Loading Class for runtime [" + name + "]");
              Class<?> c = super.loadClass(name);
              getLog().debug("Loading Class for runtime [" + name + "] found [" + c + "]");
              return c;
            }

            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {
              getLog().debug("Finding Class for runtime [" + name + "]");
              Class<?> c = super.findClass(name);
              getLog().debug("Finding Class for runtime [" + name + "] found [" + c + "]");
              return c;
            }
          };
      getLog().info("Package Class loader is using classpath " + Arrays.toString(uc.getURLs()));

      listClassloader("  ", uc);

      PackageBuilderConfiguration packageBuilderConfiguration = new PackageBuilderConfiguration(uc);
      PackageBuilder pb = new PackageBuilder(packageBuilderConfiguration);

      DirectoryScanner ds = new DirectoryScanner();
      ds.setIncludes(includes);
      ds.setExcludes(excludes);
      ds.setBasedir(rulesdir);
      ds.setCaseSensitive(true);
      ds.scan();

      String[] files = ds.getIncludedFiles();
      for (String file : files) {
        File f = new File(rulesdir, file);
        Reader reader = new FileReader(f);
        try {
          if (file.endsWith(".drl")) {
            getLog().info("Adding Rules " + f);
            pb.addPackageFromDrl(reader);
          } else if (file.endsWith(".xml")) {
            getLog().info("Adding Package definition " + f);
            pb.addPackageFromXml(reader);
          } else if (file.endsWith(".rf")) {
            getLog().info("Adding Rule Flow " + f);
            pb.addRuleFlow(reader);
          } else {
            getLog().info("Ignored Resource " + f);
          }

        } finally {
          reader.close();
        }
      }

      pb.compileAll();
      PackageBuilderErrors errors = pb.getErrors();
      if (errors.size() > 0) {
        for (KnowledgeBuilderError kberr : errors) {
          getLog().error(kberr.toString());
        }
        throw new MojoExecutionException("Package is not valid");
      }
      org.drools.rule.Package p = pb.getPackage();
      if (!p.isValid()) {
        getLog().error("Package is not valid ");
        throw new MojoExecutionException("Package is not valid");
      }

      File outputFile = getOutputFile();
      getLog().info("Saving compiled package to  " + outputFile.getPath());
      outputFile.getParentFile().mkdirs();
      FileOutputStream fout = new FileOutputStream(outputFile);
      DroolsStreamUtils.streamOut(fout, p);
      fout.close();

      getLog().info("Testing Compiled package " + outputFile.getPath());

      File inputFile = getOutputFile();
      FileInputStream fin = new FileInputStream(inputFile);

      RuleBaseConfiguration config = new RuleBaseConfiguration(uc2);
      RuleBase ruleBase = RuleBaseFactory.newRuleBase(config);
      Object o = DroolsStreamUtils.streamIn(fin, uc);

      ruleBase.addPackage((Package) o);
      KnowledgeBase kb = new KnowledgeBaseImpl(ruleBase);

      @SuppressWarnings("unused")
      StatelessKnowledgeSession session = kb.newStatelessKnowledgeSession();

      getLog().info("Testing passed ");

    } catch (Exception e) {
      getLog().error(e);
      throw new MojoExecutionException(e.getMessage());
    }
  }