function [Mclasses, Minstances, level_ndx, instance_ndx] = LM2ADEsegments(annotation, img)

annotation = LMsortlayers(annotation, img);
[S_instances] = LMobjectmask(annotation, size(img));
classesndx = [annotation.object.namendx];

Nobjects = length(annotation.object);

% For each object or part, integrate all its part-masks into the whole
objectlevel = zeros(1,Nobjects);
for j = 1:Nobjects
    [~, ~, ~, recursiveparents] = findparts(annotation, j);
    objectlevel(j) = length(recursiveparents);
end
Nlevels = max(objectlevel)+1;

% Sort parts by level and start grouping the smaller parts and move towards
% objects
[~,p] = sort(objectlevel, 'descend');
for j = p
    [~, ~, recursiveparts] = findparts(annotation, j);

    if ~isempty(recursiveparts)
        recursiveparts = id2ndx(annotation, recursiveparts);
        mask_parts = S_instances(:,:,j)+uint8(sum(S_instances(:,:,recursiveparts),3));
        S_instances(:,:,j) = uint8(mask_parts > 0.01);
    end
end

% Loop over depth (with the background objects first). 
% Put each object on its appropriate level. An object will
% occlude anything that it is not part of. 
for j = 2:Nobjects
    [~, ~, recursiveparts, recursiveparents] = findparts(annotation, j);
    if isempty(recursiveparents)
        % only whole objects will be used to occlude other objects and parts. 
        % The parts are already taken into account inside the objects. 
        % Whole object can occlude parts.
        occlusion = 1-S_instances(:,:,j);
        %recursiveparents = id2ndx(annotation, recursiveparents);
        
        % Objects can not occlude its own parts
        recursiveparts = id2ndx(annotation, recursiveparts);
        k = setdiff(1:j-1, recursiveparts);
        if ~isempty(k)
            S_instances(:,:,k) = S_instances(:,:,k).*repmat(occlusion, [1 1 length(k)]);
        end
    end
end


% Assign whole-object labels taking into account occlusions!
Mclasses = zeros([size(img,1) size(img,2) Nlevels]);
Minstances = zeros([size(img,1) size(img,2) Nlevels]);
for level = 0:Nlevels-1
    instances = find(objectlevel == level);
    nn=0;
    for k = instances
        nn = nn+1;
        mask = S_instances(:,:,k)==0; % this will fix parts occluding to each other within the same object.
        Mclasses(:,:,level+1) = Mclasses(:,:,level+1).*mask + classesndx(k)*double(S_instances(:,:,k));
        Minstances(:,:,level+1) = Minstances(:,:,level+1).*mask + nn*double(S_instances(:,:,k));
        
        % for each object in annotation, store the level and instance index
        % assigned in the segmentation:
        level_ndx(k) = level;
        instance_ndx(k) = nn;
    end
end

return


figure
for level = 0:Nlevels-1
    R = 10*uint8(fix(Mclasses(:,:,level+1)/256));
    G = uint8(rem(Mclasses(:,:,level+1), 256));
    B = uint8(Minstances(:,:,level+1)/max(max(Minstances(:,:,level+1)))*255);
    MclassesImg = cat(3,cat(3,R,G),B);
    subplot(2,2,level+1)
    imshow(MclassesImg);
end   

