function [attAffinity] = CalcAttributesAffinity_S5(data, attData, last_known_node, addMissingAtt, threshold, reqNodesToKeep)
    n = size(attData,1);
    numAtt = size(attData,2);
    
    if addMissingAtt > 0 && last_known_node < n
        attData = AddMissingNodesAttrFromNeighborsNeighbors(data, attData, last_known_node, addMissingAtt);
    end
    
    percentSparse = 0.25; %%0.33;
    
    count = sum(attData,2);
    nnz_n = nnz(count);
    nnz_p = 100*nnz_n/n;
    LogMsg(sprintf('attAffinity count  (%d, %.3f) - nnz=%d, %7.5f%%',numAtt,threshold,nnz_n, nnz_p));
%    fprintf('calculating attribtes affinity matrix - common start\n');
    % sigal - 12.6.13
    % calculate attribute affinity only for the nodesToKeep
    nodesWithAtt = (count > 0)';
    if nargin < 6
        reqNodesToKeep = (count > -1)'; % i.e. all
        percentSparse  = 0.75; %%nnz_n/n;
    end
    %sigal - 27.10.13
    if nnz_p > 0.75
        percentSparse  = 0.75;
    end
    nodesToKeep = reqNodesToKeep & nodesWithAtt;
    numNodesToKeep = full(sum(nodesToKeep));
    [rows,idxNodesToKeep] = find(nodesToKeep);
    LogMsg(sprintf('nodesToKeep (req, nnz, final) %d %d %d',full(sum(reqNodesToKeep)), full(sum(nodesWithAtt)), numNodesToKeep));
    % full calculation  %common = sparse(attData*attData');
    
%     %Sigal - 16.6.13 - use full C implementation
%     common = sparse(n,n);
%     common(nodesToKeep,nodesToKeep) = attData(nodesToKeep,:)*attData(nodesToKeep,:)';
%     [r,c] = find(common);
%     %nnz_n=numNodesToKeep*numNodesToKeep/2; 
%     nnz_n=size(r,1);%x=nnz(attAffinity);
%     perc_nnz = nnz_n/(n*n);
%     LogMsg(sprintf('attAffinity count  (%d, %.3f) - nnz=%d, %7.5f%%',numAtt,threshold,nnz_n,100*perc_nnz));
%     % Sigal 22.3.13 - TODO use sparse if x < 40%
%     if perc_nnz>0.4
%         LogMsg(sprintf('*** WARNING: attAffinity - use sparse for more than 40%% full matrix (n=%d,p=%.3f)',n,perc_nnz));
%     end
    
%     attAffinity = sparse(n,n);
%     for i=1:nnz_n
%         val = common(r(i),c(i));
%         total = count(r(i))+count(c(i))-val;
% %         if (c(i)<31 && r(i)<31) 
% %             fprintf('(i,j)=(%d,%d): common=%f, total=%f\n',full(r(i))-1,full(c(i))-1,full(val),full(total));
% %         end
%         if total > 0 && val/total > threshold
%            attAffinity(r(i),c(i)) = val/total;
%         end
%     end
% 
%     nnz_n = nnz(attAffinity);
%     LogMsg(sprintf('attAffinity totalM (%d, %.3f) - nnz=%d, %7.5f%%',numAtt,threshold,nnz_n,100*nnz_n/(n*n)));

%Sigal - 16.6.13 - use full C implementation
%     attAffinity = AttributesSimilarity(common,count,threshold);
%     clear('common');
    clear('count');
    attAffinity = AttributesSimilarity5(logical(attData'),idxNodesToKeep',threshold, percentSparse);
    nnz_n = nnz(attAffinity);
    LogMsg(sprintf('attAffinity totalC (%d, %.3f) - nnz=%d, %7.5f%%',numAtt,threshold,nnz_n,100*nnz_n/(n*n)));

%     %debuging
%     debugMex = 1;
%     if debugMex
% %         attAffinity2 = AttributesSimilarity5a(attData,idxNodesToKeep',threshold);
%         attAffinity2 = AttributesSimilarity5(logical(attData'),idxNodesToKeep',threshold);
%         aff3 = attAffinity - attAffinity2;
%         nnz_a3 = nnz(aff3);
%         fprintf('diff affinity nnz_a3 %d \n',nnz_a3);
% 
%         clear('attAffinity2');
%         clear('aff3');
%     end
    
    
%     diff = attAffinityC-attAffinity;
%     nnz_n = nnz(diff);
%     LogMsg(sprintf('attAffinity diff  (%d, %.3f) - nnz=%d, %7.5f%%',numAtt,threshold,nnz_n,100*nnz_n/(n*n)));
    
end %function
