public String createNewTestSession(JSONObject caps, Integer retries) {
    AndroidDevice device = null;
    AndroidApp app = null;
    Exception lastException = null;
    while (retries >= 0) {
      try {
        SelendroidCapabilities desiredCapabilities = getSelendroidCapabilities(caps);
        String desiredAut = desiredCapabilities.getDefaultApp(appsStore.keySet());
        app = getAndroidApp(desiredCapabilities, desiredAut);
        log.info("'" + desiredAut + "' will be used as app under test.");
        device = deviceStore.findAndroidDevice(desiredCapabilities);

        // If we are using an emulator need to start it up
        if (device instanceof AndroidEmulator) {
          startAndroidEmulator(desiredCapabilities, (AndroidEmulator) device);
          // If we are using an android device
        } else {
          device.unlockScreen();
        }

        boolean appInstalledOnDevice = device.isInstalled(app) || app instanceof InstalledAndroidApp;
        if (!appInstalledOnDevice || serverConfiguration.isForceReinstall()) {
          device.install(app);
        } else {
          log.info("the app under test is already installed.");
        }

        if(!serverConfiguration.isNoClearData()) {
          device.clearUserData(app);
        }

        int port = serverConfiguration.isReuseSelendroidServerPort()
            ? serverConfiguration.getSelendroidServerPort()
            : getNextSelendroidServerPort();

        boolean serverInstalled = device.isInstalled("io.selendroid." + app.getBasePackage());
        if (!serverInstalled || serverConfiguration.isForceReinstall()) {
          try {
            device.install(createSelendroidServerApk(app));
          } catch (AndroidSdkException e) {
            throw new SessionNotCreatedException("Could not install selendroid-server on the device", e);
          }
        } else {
          log.info(
              "Not creating and installing selendroid-server because it is already installed for this app under test.");
        }

        // Run any adb commands requested in the capabilities
        List<String> preSessionAdbCommands = desiredCapabilities.getPreSessionAdbCommands();
        runPreSessionCommands(device, preSessionAdbCommands);

        // Push extension dex to device if specified
        String extensionFile = desiredCapabilities.getSelendroidExtensions();
        pushExtensionsToDevice(device, extensionFile);

        pushExtraArgsToDevice(device, desiredCapabilities);

        // Configure logging on the device
        device.setLoggingEnabled(serverConfiguration.isDeviceLog());

        // It's GO TIME!
        // start the selendroid server on the device and make sure it's up
        eventListener.onBeforeDeviceServerStart();
        device.startSelendroid(app, port, desiredCapabilities);
        device.addInstrumentationProcessListener(this);
        waitForServerStart(device);
        eventListener.onAfterDeviceServerStart();

        // arbitrary sleeps? yay...
        // looks like after the server starts responding
        // we need to give it a moment before starting a session?
        try {
          Thread.sleep(500);
        } catch (InterruptedException e1) {
          Thread.currentThread().interrupt();
        }

        // create the new session on the device server
        RemoteWebDriver driver =
          new RemoteWebDriver(new URL("http://localhost:" + device.getSelendroidsPort() + "/wd/hub"), desiredCapabilities);
        String sessionId = driver.getSessionId().toString();
        SelendroidCapabilities requiredCapabilities =
          new SelendroidCapabilities(driver.getCapabilities().asMap());
        ActiveSession session =
          new ActiveSession(sessionId, requiredCapabilities, app, device, port, this);

        this.sessions.put(sessionId, session);

        // We are requesting an "AndroidDriver" so automatically switch to the webview
        if (BrowserType.ANDROID.equals(desiredCapabilities.getAut())) {
          switchToWebView(driver);
        }

        return sessionId;
      } catch (Exception e) {
        lastException = e;
        log.log(Level.SEVERE, "Error occurred while starting Selendroid session", e);
        retries--;

        // Return device to store
        if (device != null) {
          deviceStore.release(device, app);
          device = null;
        }
      }
    }

    if (lastException instanceof RuntimeException) {
      // Don't wrap the exception
      throw (RuntimeException)lastException;
    } else {
      throw new SessionNotCreatedException("Error starting Selendroid session", lastException);
    }
  }
This function will sign an android app and add it to the App Store. The function is made public because it also be
invoked by the Folder Monitor each time a new application dropped into this folder.

@param file
         - The file to be added to the app store
@throws AndroidSdkException
selendroid-standalone/src/main/java/io/selendroid/standalone/server/model/SelendroidStandaloneDriver.java