@Override
  public void init(
      ForegroundModuleDescriptor moduleDescriptor,
      SectionInterface sectionInterface,
      DataSource dataSource)
      throws Exception {

    this.sectionInterface = sectionInterface;
    this.systemInterface = sectionInterface.getSystemInterface();
    this.moduleDescriptor = moduleDescriptor;

    ModuleUtils.setModuleSettings(
        this,
        StaticContentModule.class,
        moduleDescriptor.getMutableSettingHandler(),
        sectionInterface.getSystemInterface());

    loadGlobalContentLinks();

    checkInstanceHandlerRegistration(registerInInstanceHandler);
  }
  @Override
  public List<SettingDescriptor> getSettings() {

    try {
      return ModuleUtils.getAnnotatedSettingDescriptors(
          this, Object.class, sectionInterface.getSystemInterface());
    } catch (IllegalArgumentException e) {

      throw new RuntimeException(e);

    } catch (IllegalAccessException e) {

      throw new RuntimeException(e);

    } catch (InstantiationException e) {

      throw new RuntimeException(e);

    } catch (SQLException e) {

      throw new RuntimeException(e);
    }
  }
  @Override
  public SimpleForegroundModuleResponse processRequest(
      HttpServletRequest req, HttpServletResponse res, User user, URIParser uriParser)
      throws AccessDeniedException, URINotFoundException {

    // TODO add support to separate numeric foreground module aliases from moduleID's (fv prefix?)
    // TODO add support to separate background module hashcodes from moduleID's (bv prefix?)

    Integer sectionID;

    if (uriParser.size() >= 3 && uriParser.get(1).equals("global")) {

      if (!enableGlobalContentLinks) {

        throw new AccessDeniedException("Global content links are disabled");
      }

      Properties globalContentLinks = this.globalContentLinks;

      if (globalContentLinks == null) {

        throw new URINotFoundException(uriParser);
      }

      if (!globalContentLinks.isEmpty()) {

        String filePath = getFilePath(uriParser, 1);

        for (Entry<Object, Object> linkEntry : globalContentLinks.entrySet()) {

          if (filePath.startsWith(linkEntry.getKey().toString())) {

            URL linkedURL = this.getClass().getResource(linkEntry.getValue() + filePath);

            if (linkedURL != null) {

              try {
                InputStream fileStream = linkedURL.openStream();

                if (fileStream != null) {

                  this.sendFile(
                      req,
                      res,
                      uriParser,
                      linkedURL,
                      fileStream,
                      user,
                      linkEntry.getValue().toString(),
                      filePath,
                      null,
                      null);

                  return null;
                }
              } catch (IOException e) {
                log.error(
                    "Unable to load file from url "
                        + linkedURL
                        + " belonging to global content links",
                    e);
              }
            }
          }
        }
      }

    } else if (uriParser.size() >= 5
        && (uriParser.get(1).equals("f") || uriParser.get(1).equals("b"))
        && !uriParser.getFormattedURI().contains("..")
        && (sectionID = NumberUtils.toInt(uriParser.get(2))) != null) {

      // Get the requested section
      SectionInterface sectionInterface = systemInterface.getSectionInterface(sectionID);

      if (sectionInterface == null) {

        // The requested section is not started or does not exist
        throw new AccessDeniedException(
            "The requested section ID was not found in cache (URI: "
                + uriParser.getFormattedURI()
                + ")");

      } else if (!AccessUtils.checkAccess(user, sectionInterface.getSectionDescriptor())) {

        // The user does not have access to the requested section
        throw new AccessDeniedException(
            "User does not have access to section "
                + sectionInterface.getSectionDescriptor()
                + " (URI: "
                + uriParser.getFormattedURI()
                + ")");
      }

      // Check that the user has access to all parent section
      SectionInterface parentSection = sectionInterface.getParentSectionInterface();

      while (parentSection != null) {

        if (!AccessUtils.checkAccess(user, parentSection.getSectionDescriptor())) {

          // User does not have access to a parent section
          throw new AccessDeniedException(
              "User does not have access to section "
                  + sectionInterface.getSectionDescriptor()
                  + " (URI: "
                  + uriParser.getFormattedURI()
                  + ")");
        }

        parentSection = parentSection.getParentSectionInterface();
      }

      boolean foreground = uriParser.get(1).equals("f");

      String moduletype;

      if (foreground) {

        moduletype = "foreground module";

      } else {

        moduletype = "background module";
      }

      Integer moduleID = NumberUtils.toInt(uriParser.get(3));

      // Get the requested module
      Entry<? extends VisibleModuleDescriptor, ? extends Module<?>> moduleEntry = null;

      if (moduleID != null) {

        if (foreground) {

          moduleEntry = sectionInterface.getForegroundModuleCache().getEntry(moduleID);

        } else {

          moduleEntry = sectionInterface.getBackgroundModuleCache().getEntry(moduleID);
        }
      }

      if (moduleEntry == null) {

        if (foreground) {

          String alias = uriParser.get(3);

          moduleEntry = sectionInterface.getForegroundModuleCache().getEntry(alias);

        } else if (moduleID != null) {

          moduleEntry = sectionInterface.getBackgroundModuleCache().getEntryByHashCode(moduleID);
        }
      }

      if (moduleEntry != null) {

        VisibleModuleDescriptor moduleDescriptor = moduleEntry.getKey();

        // Check if the user has access to this module
        if (AccessUtils.checkAccess(user, moduleDescriptor)) {

          // Check that the module has a static content directory set
          if (!StringUtils.isEmpty(moduleDescriptor.getStaticContentPackage())) {

            // Check that the requested file exists in the specified classpath directory

            String filePath = getFilePath(uriParser, 3);

            URL url =
                moduleEntry
                    .getValue()
                    .getClass()
                    .getResource(moduleDescriptor.getStaticContentPackage() + filePath);

            InputStream fileStream = null;

            if (url != null) {

              try {
                fileStream = url.openStream();
              } catch (IOException e) {
              }
            }

            if (fileStream != null) {

              log.debug(
                  "Sending file "
                      + moduleDescriptor.getStaticContentPackage()
                      + filePath
                      + " from "
                      + moduletype
                      + " "
                      + moduleDescriptor
                      + " reqested using URI "
                      + uriParser.getFormattedURI()
                      + " to user "
                      + user);

              this.sendFile(
                  req,
                  res,
                  uriParser,
                  url,
                  fileStream,
                  user,
                  moduleDescriptor.getStaticContentPackage(),
                  filePath,
                  moduleDescriptor,
                  moduletype);

              return null;

            } else if ((fileStream =
                    moduleEntry
                        .getValue()
                        .getClass()
                        .getResourceAsStream(
                            moduleDescriptor.getStaticContentPackage()
                                + "/StaticContentLinks.properties"))
                != null) {

              Properties links = new Properties();

              try {
                links.load(fileStream);

              } catch (IOException e) {
                log.error(
                    "Unable to load static content links belonging to "
                        + moduletype
                        + " "
                        + moduleDescriptor,
                    e);
              } finally {
                StreamUtils.closeStream(fileStream);
              }

              if (!links.isEmpty()) {

                for (Entry<Object, Object> linkEntry : links.entrySet()) {

                  if (filePath.startsWith(linkEntry.getKey().toString())) {

                    URL linkedURL =
                        moduleEntry
                            .getValue()
                            .getClass()
                            .getResource(linkEntry.getValue() + filePath);

                    if (linkedURL != null) {

                      try {
                        fileStream = linkedURL.openStream();

                        if (fileStream != null) {

                          this.sendFile(
                              req,
                              res,
                              uriParser,
                              linkedURL,
                              fileStream,
                              user,
                              linkEntry.getValue().toString(),
                              filePath,
                              moduleDescriptor,
                              moduletype);

                          return null;
                        }

                      } catch (IOException e) {
                        log.error(
                            "Unable to load file from url "
                                + linkedURL
                                + " belonging to "
                                + moduletype
                                + " "
                                + moduleDescriptor,
                            e);
                      }
                    }
                  }
                }
              }

            } else {
              log.info(
                  "File "
                      + uriParser.getFormattedURI()
                      + " requested from "
                      + moduletype
                      + " "
                      + moduleDescriptor
                      + " by user "
                      + user
                      + " not found");
            }

          } else {
            log.info(
                "User "
                    + user
                    + " requested static content from "
                    + moduletype
                    + " "
                    + moduleDescriptor
                    + " which has no static content package set, using URI "
                    + uriParser.getFormattedURI());
          }
        } else {
          throw new AccessDeniedException(
              "User does not have access to "
                  + moduletype
                  + " "
                  + moduleEntry.getKey()
                  + " (URI: "
                  + uriParser.getFormattedURI()
                  + ")");
        }
      } else {
        log.info(
            "Invalid sectionID or moduleID in URI "
                + uriParser.getFormattedURI()
                + " requested by user "
                + user);
      }
    } else {
      log.info("Invalid URI " + uriParser.getFormattedURI() + " requested by user " + user);
    }

    throw new URINotFoundException(uriParser);
  }