@Override
  public void handleAction(ActionParameters params) throws ActionException {
    if (params.getUser().isGuest()) {
      throw new ActionDeniedException("Session expired");
    }
    final long id = ConversionHelper.getLong(params.getHttpParam(PARAM_ID), -1);
    if (id == -1) {
      throw new ActionParamsException(
          "Parameter missing or non-numeric: " + PARAM_ID + "=" + params.getHttpParam(PARAM_ID));
    }

    final Analysis analysis = analysisDataService.getAnalysisById(id);
    if (analysis == null) {
      throw new ActionParamsException("Analysis id didn't match any analysis: " + id);
    }
    if (!params.getUser().getUuid().equals(analysis.getUuid())) {
      throw new ActionDeniedException("Analysis belongs to another user");
    }

    try {
      analysisDataService.deleteAnalysis(analysis);
      // write static response to notify success {"result" : "success"}
      ResponseHelper.writeResponse(params, JSONHelper.createJSONObject("result", "success"));
    } catch (ServiceException ex) {
      throw new ActionException("Error deleting analysis", ex);
    }
  }
  /**
   * Handles action_route CreateAnalysisLayer
   *
   * @param params Ajax request parameters
   *     **********************************************************************
   */
  public void handleAction(ActionParameters params) throws ActionException {

    if (params.getUser().isGuest()) {
      throw new ActionDeniedException("Session expired");
    }

    final String analyse = params.getRequiredParam(PARAM_ANALYSE, ERROR_ANALYSE_PARAMETER_MISSING);
    JSONObject analyseJson = JSONHelper.createJSONObject(analyse);
    if (analyseJson == null) {
      // json corrupted/parsing failed
      throw new ActionParamsException(ERROR_ANALYSE_PARAMETER_MISSING);
    }

    // filter conf data
    final String filter1 = params.getHttpParam(PARAM_FILTER1);
    final String filter2 = params.getHttpParam(PARAM_FILTER2);

    // Get baseProxyUrl
    final String baseUrl = getBaseProxyUrl(params);

    // User
    String uuid = params.getUser().getUuid();
    // note! analysisLayer is replaced in aggregate handling!!
    AnalysisLayer analysisLayer = getAnalysisLayer(analyseJson, filter1, filter2, baseUrl, uuid);
    Analysis analysis = null;

    if (analysisLayer.getMethod().equals(AnalysisParser.LAYER_UNION)) {
      // no WPS for merge analysis
      analysis = analysisDataService.mergeAnalysisData(analysisLayer, analyse, params.getUser());
    } else {
      // Generate WPS XML
      String featureSet = executeWPSprocess(analysisLayer);
      if (analysisLayer.getMethod().equals(AnalysisParser.UNION)
          || analysisLayer.getMethod().equals(AnalysisParser.INTERSECT)
          || analysisLayer.getMethod().equals(AnalysisParser.SPATIAL_JOIN)) {
        // Harmonize namespaces and element names
        featureSet = analysisParser.harmonizeElementNames(featureSet, analysisLayer);
      }

      // Add data to analysis db  - we must create still an union in aggregate case
      if (analysisLayer.getMethod().equals(AnalysisParser.AGGREGATE)) {
        // No store to analysis db for aggregate - set results in to the
        // response
        // Save analysis results - use union of input data
        analysisLayer.setWpsLayerId(-1);
        final String aggregateResult =
            this.localiseAggregateResult(
                analysisParser.parseAggregateResults(featureSet, analysisLayer), analyseJson);
        log.debug("\nAggregate results:\n", aggregateResult, "\n");
        /*
        Aggregate results:
         {"fi_url_1":{"Count":4},"tmp_id":{"Sum":45301,"Median":12232,"Count":4,"Standar
        d deviation":3186.3551571505645,"Maximum":14592,"Average":11325.25,"Minimum":624
        5},"fi_url_3":{"Count":4},"postinumero":{"Count":4},"fi_url_2":{"Count":4},"fi_s
        posti_1":{"Count":4},"kuntakoodi":{"Count":4},"fi_osoite":{"Count":4},"fi_nimi":
        {"Count":4},"kto_tarkennus":{"Count":4}}
                         */
        analysisLayer.setResult(aggregateResult);

        // Get geometry for aggretage features
        try {
          // Just return result as JSON and don't save analysis to DB
          if (!params.getHttpParam(PARAM_SAVE_BLN, true)) {
            // NOTE!! Replacing the analysisLayer!
            // Get response as geojson when no db store
            analysisLayer =
                getAggregateLayer(analyse, filter1, filter2, baseUrl, analysisLayer, JSONFORMAT);
            featureSet = wpsService.requestFeatureSet(analysisLayer);
            // Just return result as JSON and don't save analysis to DB
            // Get geometry as geojson for hilighting features of aggregate result
            JSONObject geojson = JSONHelper.createJSONObject(featureSet);
            JSONObject jsaggregate = JSONHelper.createJSONObject(aggregateResult);
            JSONObject results = new JSONObject();
            JSONHelper.putValue(results, JSON_KEY_GEOJSON, geojson);
            JSONHelper.putValue(results, JSON_KEY_AGGREGATE_RESULT, jsaggregate);
            ResponseHelper.writeResponse(params, results);
            return;
          }
          // NOTE!! Replacing the analysisLayer!  - response is gml
          analysisLayer =
              getAggregateLayer(analyse, filter1, filter2, baseUrl, analysisLayer, null);
          featureSet = wpsService.requestFeatureSet(analysisLayer);
          // Harmonize namespaces and element names
          featureSet = analysisParser.harmonizeElementNames(featureSet, analysisLayer);
          featureSet =
              analysisParser.mergeAggregateResults2FeatureSet(
                  featureSet,
                  analysisLayer,
                  this.getRowOrder(analyseJson),
                  this.getColumnOrder(analyseJson));
          // Redefine column types
          analysisLayer.setFieldtypeMap(
              this.getAggregateFieldTypes(this.getColumnOrder(analyseJson)));
        } catch (ServiceException e) {
          throw new ActionException(ERROR_UNABLE_TO_GET_FEATURES_FOR_UNION, e);
        }
      }
      // Add extra TypeNames (depends on wps method)
      analysisParser.fixTypeNames(analysisLayer);

      // Fix geometry property name for WFST (could be any, depends on Wps method )
      fixGeometryPropertyName(analysisLayer);

      analysis =
          analysisDataService.storeAnalysisData(
              featureSet, analysisLayer, analyse, params.getUser());
    }

    if (analysis == null) {
      this.MyError(ERROR_UNABLE_TO_STORE_ANALYSIS_DATA, params, null);
      return;
    }

    analysisLayer.setWpsLayerId(analysis.getId()); // aka. analysis_id
    // Analysis field mapping
    analysisLayer.setLocaleFields(analysis);
    analysisLayer.setNativeFields(analysis);

    // copy permissions from source layer to new analysis
    final Resource sourceResource =
        getSourcePermission(analysisParser.getSourceLayerId(analyseJson), params.getUser());
    if (sourceResource != null) {
      final Resource analysisResource = new Resource();
      analysisResource.setType(AnalysisLayer.TYPE);
      analysisResource.setMapping("analysis", Long.toString(analysis.getId()));
      for (Permission p : sourceResource.getPermissions()) {
        // check if user has role matching permission?
        if (p.isOfType(Permissions.PERMISSION_TYPE_PUBLISH)
            || p.isOfType(Permissions.PERMISSION_TYPE_VIEW_PUBLISHED)) {
          analysisResource.addPermission(p.clonePermission());
        }
      }
      log.debug(
          "Trying to save permissions for analysis",
          analysisResource,
          analysisResource.getPermissions());
      permissionsService.saveResourcePermissions(analysisResource);
    } else {
      log.warn("Couldn't get source permissions for analysis, result will have none");
    }

    // Get analysisLayer JSON for response to front
    final JSONObject analysisLayerJSON = AnalysisHelper.getlayerJSON(analysis);

    // Additional param for new layer creation when merging layers:
    // - Notify client to remove merged layers since they are removed from backend
    JSONArray mlayers = new JSONArray();
    if (analysisLayer.getMergeAnalysisLayers() != null) {
      for (String lay : analysisLayer.getMergeAnalysisLayers()) {
        mlayers.put(lay);
      }
    }
    JSONHelper.putValue(analysisLayerJSON, "mergeLayers", mlayers);

    Set<String> permissionsList = permissionsService.getPublishPermissions(AnalysisLayer.TYPE);
    Set<String> downloadPermissionsList =
        permissionsService.getDownloadPermissions(AnalysisLayer.TYPE);
    Set<String> editAccessList = null;
    String permissionKey = "analysis+" + analysis.getId();
    JSONObject permissions =
        OskariLayerWorker.getPermissions(
            params.getUser(),
            permissionKey,
            permissionsList,
            downloadPermissionsList,
            editAccessList);
    JSONHelper.putValue(analysisLayerJSON, "permissions", permissions);

    ResponseHelper.writeResponse(params, analysisLayerJSON);
  }