private boolean execEstimateUsingFeatureFrequencies(VectorMap queryParam, StringBuffer respBody, DBAccess dbAccess) {
        try {
            int clntIdx = queryParam.qpIndexOfKeyNoCase("clnt");
            String clientName = (String) queryParam.getVal(clntIdx);

            int ftrsIdx = queryParam.qpIndexOfKeyNoCase("ftrs");
            String ftrNames = null;
            if (ftrsIdx != -1) {
                ftrNames = (String) queryParam.getVal(ftrsIdx);
            }

            int usrIdx = queryParam.qpIndexOfKeyNoCase("usr");
            if (usrIdx == -1) {
                WebServer.win.log.error("-Missing argument: usr");
                return false;
            }
            String user = (String) queryParam.getVal(usrIdx);

            int ftrIdx = queryParam.qpIndexOfKeyNoCase("ftr");
            if (ftrIdx == -1) {
                WebServer.win.log.error("-Missing argument: ftr");
                return false;
            }
            String ftrPattern = (String) queryParam.getVal(ftrIdx);
            String[] ftrs = ftrPattern.split("\\|");

            respBody.append(DBAccess.xmlHeader("/resp_xsl/estimation_profile.xsl"));
            respBody.append("<result>\n");

            String sql = "SELECT " + DBAccess.UPROFILE_TABLE_FIELD_VALUE + " FROM " + DBAccess.UPROFILE_TABLE + " WHERE " + DBAccess.FIELD_PSCLIENT + "='" + clientName + "' AND " + DBAccess.UPROFILE_TABLE_FIELD_USER + "='" + user + "' AND " + DBAccess.UPROFILE_TABLE_FIELD_FEATURE + "=?";
            PreparedStatement selectFtr = dbAccess.getConnection().prepareStatement(sql);

            sql = "SELECT " + DBAccess.FEATURE_STATISTICS_TABLE_FIELD_VALUE + " FROM " + DBAccess.FEATURE_STATISTICS_TABLE + " WHERE " + DBAccess.FIELD_PSCLIENT + "='" + clientName + "' AND " + DBAccess.FEATURE_STATISTICS_TABLE_FIELD_USER + "='" + user + "' AND " + DBAccess.FEATURE_STATISTICS_TABLE_FIELD_FEATURE + "=? AND " + DBAccess.FEATURE_STATISTICS_TABLE_FIELD_TYPE + "=" + DBAccess.STATISTICS_FREQUENCY;
            PreparedStatement selectFtrFreq = dbAccess.getConnection().prepareStatement(sql);

            String sql1 = "SELECT " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_DST + " ftr," + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_WEIGHT + " FROM " + DBAccess.UFTRASSOCIATIONS_TABLE + " WHERE " + DBAccess.FIELD_PSCLIENT + "='" + clientName + "' AND " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_USR + "='' AND " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_SRC + "=? AND " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_TYPE + "=" + DBAccess.RELATION_PHYSICAL;
            String sql2 = "SELECT " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_SRC + " ftr," + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_WEIGHT + " FROM " + DBAccess.UFTRASSOCIATIONS_TABLE + " WHERE " + DBAccess.FIELD_PSCLIENT + "='" + clientName + "' AND " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_USR + "='' AND " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_DST + "=? AND " + DBAccess.UFTRASSOCIATIONS_TABLE_FIELD_TYPE + "=" + DBAccess.RELATION_PHYSICAL;
            sql = "(" + sql1 + ") UNION (" + sql2 + ")";
            PreparedStatement assocs = dbAccess.getConnection().prepareStatement(sql);

            for (int i = 0; i < ftrs.length; i++) {

                assocs.setString(1, ftrs[i]);
                assocs.setString(2, ftrs[i]);
                ResultSet rs = assocs.executeQuery();

                ArrayList<String> coFeatures = new ArrayList<String>(40);
                ArrayList<Float> coFeatureWeights = new ArrayList<Float>(40);
                while (rs.next()) {
                    coFeatures.add(rs.getString(1));
                    coFeatureWeights.add(rs.getFloat(2));
                }
                rs.close();
                int numOfnownCoFtrs = 0;
                float weight = 0.0f;
                float sum = 0.0f;
                int j = 0;

                for (String feature : coFeatures) {
                    selectFtr.setString(1, feature);
                    rs = selectFtr.executeQuery();
                    if (rs.next()) {
                        numOfnownCoFtrs++;
                        float val = rs.getFloat(1);
                        rs.close();
                        selectFtrFreq.setString(1, feature);
                        rs = selectFtrFreq.executeQuery();
                        rs.next();
                        float freq = rs.getFloat(1);

                        weight += val * freq * coFeatureWeights.get(j);
                        sum += freq * coFeatureWeights.get(j);
                    } else {
                        rs.close();
                    }
                    j++;
                }
                if (numOfnownCoFtrs > 0) {
                    String record = "<row><ftr>" + ftrs[i] + "</ftr><val>" + (weight / sum) + "</val><factors>" + (numOfnownCoFtrs * 1.0 / coFeatureWeights.size()) + "</factors></row>";
                    respBody.append(record);
                } else {
                    String record = "<row><ftr>" + ftrs[i] + "</ftr><val>uknown</val><factors>" + (numOfnownCoFtrs * 1.0 / coFeatureWeights.size()) + "</factors></row>";
                    respBody.append(record);
                }
            }
            selectFtr.close();
            selectFtrFreq.close();
            assocs.close();

            respBody.append("</result>");
        } catch (SQLException ex) {
            WebServer.win.log.error(ex.toString());
            ex.printStackTrace();
            return false;
        }
        return true;
    }