@Override
    public void run() {
        try {
            PUserDBAccess pdbAccess = new PUserDBAccess(dbAccess);
            Statement stmt;
            stmt = dbAccess.getConnection().createStatement();

            PUser collaborativeProfile = pdbAccess.getUserProfile(user, null, clientName, true);

            Map<String, Float> ftrFreqa = collaborativeProfile.getFtrReqs();
            Map<String, Float> ftrVals = collaborativeProfile.getProfile();
            HashMap<String, Float> ftrSum = new HashMap<String, Float>();

            Map<Set<String>, Float> assocFreqa = collaborativeProfile.getFtrAssocs();
            Map<Set<String>, Float> assocSum = new HashMap<Set<String>, Float>();

            for (String ftr : ftrVals.keySet()) {
                ftrSum.put(ftr, Float.valueOf(1));
            }

            for (Set<String> ftrSet : assocFreqa.keySet()) {
                assocSum.put(ftrSet, Float.valueOf(1));
            }

            //System.out.println( assocFreqa.size() + " " + assocSum.size() );

            String sql = "SELECT * FROM " + DBAccess.UASSOCIATIONS_TABLE + " WHERE " + DBAccess.FIELD_PSCLIENT + "='" + clientName + "' AND " + DBAccess.UASSOCIATIONS_TABLE_FIELD_SRC + "='" + user + "' AND " + DBAccess.UASSOCIATIONS_TABLE_FIELD_TYPE + "=" + DBAccess.RELATION_BINARY_SIMILARITY;
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                String otherUser = rs.getString(DBAccess.UASSOCIATIONS_TABLE_FIELD_DST);
                float dist = rs.getFloat(DBAccess.UASSOCIATIONS_TABLE_FIELD_WEIGHT);
                PUser otherUserProfile = pdbAccess.getUserProfile(otherUser, null, clientName, true);
                updateCollaborativeProfile(otherUserProfile, dist, assocFreqa, ftrFreqa, ftrVals, ftrSum, assocSum);
            }
            rs.close();

            sql = "SELECT * FROM " + DBAccess.UASSOCIATIONS_TABLE + " WHERE " + DBAccess.FIELD_PSCLIENT + "='" + clientName + "' AND " + DBAccess.UASSOCIATIONS_TABLE_FIELD_DST + "='" + user + "' AND " + DBAccess.UASSOCIATIONS_TABLE_FIELD_TYPE + "=" + DBAccess.RELATION_BINARY_SIMILARITY;
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                String otherUser = rs.getString(DBAccess.UASSOCIATIONS_TABLE_FIELD_SRC);
                float dist = rs.getFloat(DBAccess.UASSOCIATIONS_TABLE_FIELD_WEIGHT);
                PUser otherUserProfile = pdbAccess.getUserProfile(otherUser, null, clientName, true);
                updateCollaborativeProfile(otherUserProfile, dist, assocFreqa, ftrFreqa, ftrVals, ftrSum, assocSum);
            }
            rs.close();

            //if (ftrVals.size() != ftrFreqa.size()) {
            //    System.out.println(" sizes " + ftrVals.size() + " " + ftrFreqa.size());
            //    System.exit(- 1);
            //}

            sql = "INSERT DELAYED INTO " + DBAccess.CFPROFILE_TABLE + " VALUES (?,?,?,?,'" + clientName + "')";
            PreparedStatement cfFtrStmt = dbAccess.getConnection().prepareStatement(sql);
            cfFtrStmt.setString(1, this.user);
            Set<Entry<String, Float>> entries = ftrVals.entrySet();
            for (Iterator<Entry<String, Float>> it = entries.iterator(); it.hasNext();) {
                Map.Entry<String, Float> entry = it.next();
                String feature = entry.getKey();
                float val = entry.getValue() / ftrSum.get(feature);
                cfFtrStmt.setString(2, feature);
                cfFtrStmt.setString(3, val + "");
                cfFtrStmt.setFloat(4, val);
                cfFtrStmt.addBatch();
                //System.out.println( cfFtrStmt.toString() );
            }
            cfFtrStmt.executeBatch();
            cfFtrStmt.close();

            sql = "INSERT DELAYED INTO " + DBAccess.CFFEATURE_STATISTICS_TABLE + " VALUES (?,?," + DBAccess.STATISTICS_FREQUENCY + ",?,'" + clientName + "')";
            PreparedStatement cfFtrfrStmt = dbAccess.getConnection().prepareStatement(sql);
            cfFtrfrStmt.setString(1, this.user);
            entries = ftrFreqa.entrySet();
            for (Iterator<Entry<String, Float>> it = entries.iterator(); it.hasNext();) {
                Map.Entry<String, Float> entry = it.next();
                String feature = entry.getKey();
                float val = entry.getValue() / ftrSum.get(feature);
                cfFtrfrStmt.setString(2, feature);
                cfFtrfrStmt.setFloat(3, val);
                cfFtrfrStmt.addBatch();
            }
            cfFtrfrStmt.executeBatch();
            cfFtrfrStmt.close();

            sql = "INSERT DELAYED INTO " + DBAccess.CFFTRASSOCIATIONS_TABLE + " VALUES (?,?,?," + DBAccess.RELATION_SIMILARITY + ",?,'" + clientName + "')";
            PreparedStatement cfAssocFtrStmt = dbAccess.getConnection().prepareStatement(sql);
            cfAssocFtrStmt.setString(4, this.user);
            Set<Entry<Set<String>, Float>> asentries = assocFreqa.entrySet();
            //System.out.println( assocFreqa.size() + " " + assocSum.size() );
            for (Iterator<Entry<Set<String>, Float>> it = asentries.iterator(); it.hasNext();) {
                Map.Entry<Set<String>, Float> entry = it.next();
                Set<String> features = entry.getKey();
                float val = entry.getValue() / assocSum.get(features);
                Iterator<String> ftrI = features.iterator();
                cfAssocFtrStmt.setString(1, ftrI.next());
                cfAssocFtrStmt.setString(2, ftrI.next());
                cfAssocFtrStmt.setFloat(3, val);
                cfAssocFtrStmt.addBatch();
            }
            cfAssocFtrStmt.executeBatch();
            cfAssocFtrStmt.close();
            stmt.close();

        } catch (SQLException ex) {
            WebServer.win.log.error(ex.toString());
            System.exit(0);
        }
        WebServer.win.log.echo("Processing for " + user + " Collaborative profile completed");
    }