docs: private void mergePackage( InternalKnowledgePackage pkg,
                                 InternalKnowledgePackage newPkg ) {
          // Merge imports
          final Map<String, ImportDeclaration> imports = pkg.getImports();
          imports.putAll(newPkg.getImports());
  
          // Merge static imports
          for (String staticImport : newPkg.getStaticImports()) {
              pkg.addStaticImport(staticImport);
          }
  
          String lastIdent = null;
          String lastType = null;
          try {
              // merge globals
              if (newPkg.getGlobals() != null && newPkg.getGlobals() != Collections.EMPTY_MAP) {
                  Map<String, String> globals = pkg.getGlobals();
                  // Add globals
                  for (final Map.Entry<String, String> entry : newPkg.getGlobals().entrySet()) {
                      final String identifier = entry.getKey();
                      final String type = entry.getValue();
                      lastIdent = identifier;
                      lastType = type;
                      if (globals.containsKey( identifier ) && !globals.get( identifier ).equals( type )) {
                          throw new RuntimeException(pkg.getName() + " cannot be integrated");
                      } else {
                          pkg.addGlobal( identifier,
                                         this.rootClassLoader.loadClass( type ) );
                          // this isn't a package merge, it's adding to the rulebase, but I've put it here for convienience
                          addGlobal(identifier,
                                    this.rootClassLoader.loadClass(type));
                      }
                  }
              }
          } catch (ClassNotFoundException e) {
              throw new RuntimeException( "Unable to resolve class '" + lastType +
                                          "' for global '" + lastIdent + "'" );
          }
  
          // merge entry point declarations
          if (newPkg.getEntryPointIds() != null) {
              for (String ep : newPkg.getEntryPointIds()) {
                  pkg.addEntryPointId( ep );
  
              }
          }
  
          // merge the type declarations
          if (newPkg.getTypeDeclarations() != null) {
              // add type declarations
              for (TypeDeclaration type : newPkg.getTypeDeclarations().values()) {
                  // @TODO should we allow overrides? only if the class is not in use.
                  if (!pkg.getTypeDeclarations().containsKey( type.getTypeName() )) {
                      // add to package list of type declarations
                      pkg.addTypeDeclaration( type );
                  }
              }
          }
  
          // merge window declarations
          if ( newPkg.getWindowDeclarations() != null ) {
              // add window declarations
              for ( WindowDeclaration window : newPkg.getWindowDeclarations().values() ) {
                  if ( !pkg.getWindowDeclarations().containsKey( window.getName() ) ||
                       pkg.getWindowDeclarations().get( window.getName() ).equals( window ) ) {
                      pkg.addWindowDeclaration( window );
                  } else {
                      throw new RuntimeException( "Unable to merge two conflicting window declarations for window named: "+window.getName() );
                  }
              }
          }
  
          //Merge rules into the RuleBase package
          //as this is needed for individual rule removal later on
          List<RuleImpl> rulesToBeRemoved = new ArrayList<RuleImpl>();
          for (Rule newRule : newPkg.getRules()) {
              // remove the rule if it already exists
              RuleImpl oldRule = pkg.getRule(newRule.getName());
              if (oldRule != null) {
                  rulesToBeRemoved.add(oldRule);
              }
          }
          if (!rulesToBeRemoved.isEmpty()) {
              removeRules( rulesToBeRemoved );
          }
  
          for (Rule newRule : newPkg.getRules()) {
              pkg.addRule((RuleImpl)newRule);
          }
  
          //Merge The Rule Flows
          if (newPkg.getRuleFlows() != null) {
              for (Process flow : newPkg.getRuleFlows().values()) {
                  pkg.addProcess(flow);
              }
          }
  
          if ( ! newPkg.getResourceTypePackages().isEmpty() ) {
              KieWeavers weavers = ServiceRegistry.getInstance().get(KieWeavers.class);
              for ( ResourceTypePackage rtkKpg : newPkg.getResourceTypePackages().values() ) {
                  weavers.merge( this, pkg, rtkKpg );
              }
          }
      }