SLING-7504 optionally create directories to monitor
diff --git a/src/main/java/org/apache/sling/installer/provider/file/impl/Activator.java b/src/main/java/org/apache/sling/installer/provider/file/impl/Activator.java
index afeeb85..bd11c77 100644
--- a/src/main/java/org/apache/sling/installer/provider/file/impl/Activator.java
+++ b/src/main/java/org/apache/sling/installer/provider/file/impl/Activator.java
@@ -33,9 +33,14 @@
 @Header(name = Constants.BUNDLE_ACTIVATOR, value = "${@class}")
 public class Activator implements BundleActivator {
 
+    /** Comma separated list of directories to monitor */
     public static final String KEY_DIR = "sling.fileinstall.dir";
+    /** The interval in milleseconds between two consecutive polls */
     public static final String KEY_DELAY = "sling.fileinstall.interval";
+    /**  If {@code true} OSGi configurations coming from the file system should be written back to the file system after modification */
     public static final String KEY_WRITEBACK = "sling.fileinstall.writeback";
+    /** If {@code true} the monitored directories are created if not yet existing during start */
+    public static final String KEY_AUTOCREATE_DIR = "sling.fileinstall.dir.autocreate";
 
     /** The services listener will activate the installer. */
     private ServicesListener servicesListener;
@@ -45,17 +50,13 @@
      */
     public void start(final BundleContext context) {
         // read initial scan configurations
-        final List<ScanConfiguration> configs = new ArrayList<ScanConfiguration>();
+        final List<ScanConfiguration> configs = new ArrayList<>();
         final Object dir = getProp(context, KEY_DIR);
         if ( dir != null ) {
             Long delay = null;
-            final Object interval = getProp(context, KEY_DELAY);
+            final String interval = getProp(context, KEY_DELAY);
             if ( interval != null ) {
-                if ( interval instanceof Number ) {
-                    delay = ((Number)interval).longValue();
-                } else {
-                    delay = Long.valueOf(interval.toString());
-                }
+                delay = Long.valueOf(interval.toString());
             }
             final StringTokenizer st = new StringTokenizer(dir.toString(), ",");
             while ( st.hasMoreTokens() ) {
@@ -77,14 +78,12 @@
         this.servicesListener = null;
     }
 
-    public static Object getProp(final BundleContext bundleContext, final String key) {
-        Object o = bundleContext.getProperty(key);
-        if (o == null) {
-            o = System.getProperty(key);
-            if ( o == null ) {
-                o = System.getProperty(key.toUpperCase().replace('.', '_'));
-            }
+    public static String getProp(final BundleContext bundleContext, final String key) {
+        // this already falls back to system properties
+        String value = bundleContext.getProperty(key);
+        if (value == null) {
+            value = System.getProperty(key.toUpperCase().replace('.', '_'));
         }
-        return o;
+        return value;
     }
 }
diff --git a/src/main/java/org/apache/sling/installer/provider/file/impl/FileInstaller.java b/src/main/java/org/apache/sling/installer/provider/file/impl/FileInstaller.java
index 44c02b1..6940dea 100644
--- a/src/main/java/org/apache/sling/installer/provider/file/impl/FileInstaller.java
+++ b/src/main/java/org/apache/sling/installer/provider/file/impl/FileInstaller.java
@@ -26,6 +26,8 @@
 import java.io.OutputStream;
 import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.MessageDigest;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -65,9 +67,11 @@
     private final List<FileMonitor> monitors = new ArrayList<FileMonitor>();
 
     private final boolean writeBack;
+    private final boolean autoCreateDirectories;
 
-    public FileInstaller(final List<ScanConfiguration> configs, final boolean writeBack) {
+    public FileInstaller(final List<ScanConfiguration> configs, final boolean writeBack, boolean autoCreateDirectories) {
         this.writeBack = writeBack;
+        this.autoCreateDirectories = autoCreateDirectories;
         if ( configs != null ) {
             scanConfigurations.addAll(configs);
         }
@@ -84,6 +88,13 @@
                 key = "${sling.home}" + key.substring(settings.getSlingHomePath().length());
             }
             logger.debug("Starting monitor for {}", config.directory);
+            if (autoCreateDirectories) {
+                try {
+                    Files.createDirectory(Paths.get(config.directory));
+                } catch (IOException e) {
+                    logger.warn("Could not create directory to monitor at {}", config.directory, e);
+                }
+            }
             this.monitors.add(new FileMonitor(new File(config.directory),
                     config.scanInterval, new Installer(installer, settings, config.directory, hash(key))));
         }
diff --git a/src/main/java/org/apache/sling/installer/provider/file/impl/ServicesListener.java b/src/main/java/org/apache/sling/installer/provider/file/impl/ServicesListener.java
index 90d016a..5fbb675 100644
--- a/src/main/java/org/apache/sling/installer/provider/file/impl/ServicesListener.java
+++ b/src/main/java/org/apache/sling/installer/provider/file/impl/ServicesListener.java
@@ -64,7 +64,7 @@
     private final FileInstaller installer;
 
     /** Service registration. */
-    private ServiceRegistration registration;
+    private ServiceRegistration<UpdateHandler> registration;
 
     private boolean running = false;
 
@@ -76,7 +76,8 @@
         if ( writeBackObj != null && "false".equalsIgnoreCase(writeBackObj.toString())) {
             writeBack = false;
         }
-        this.installer = new FileInstaller(configs, writeBack);
+        boolean autoCreateDirectories = Boolean.parseBoolean(Activator.getProp(this.bundleContext, Activator.KEY_AUTOCREATE_DIR));
+        this.installer = new FileInstaller(configs, writeBack, autoCreateDirectories);
         this.installerListener = new Listener(INSTALLER_SERVICE_NAME);
         this.settingsListener = new Listener(SETTINGS_SERVICE_NAME);
         this.installerListener.start();
@@ -112,12 +113,12 @@
     private void startScanner(final OsgiInstaller installer, final SlingSettingsService settings) {
         if ( !running ) {
             this.installer.start(installer, settings);
-            final Dictionary<String, Object> props = new Hashtable<String, Object>();
+            final Dictionary<String, Object> props = new Hashtable<>();
             props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling File Installer Controller Service");
             props.put(Constants.SERVICE_VENDOR, VENDOR);
             props.put(UpdateHandler.PROPERTY_SCHEMES, this.installer.getSchemes());
 
-            this.registration = this.bundleContext.registerService(UpdateHandler.class.getName(),
+            this.registration = this.bundleContext.registerService(UpdateHandler.class,
                     this.installer, props);
             running = true;
         }
@@ -138,7 +139,7 @@
 
         private final String serviceName;
 
-        private ServiceReference reference;
+        private ServiceReference<?> reference;
         private Object service;
 
         public Listener(final String serviceName) {