package com.aventstack.extentreports.model.context;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.model.NamedAttribute;
import com.aventstack.extentreports.model.Test;

import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
public class NamedAttributeContext<T extends NamedAttribute> implements Serializable {
    private static final long serialVersionUID = -2671203343283101908L;

    private final List<Test> testList = Collections.synchronizedList(new ArrayList<>());
    private T attr;
    private Integer passed = 0;
    private Integer failed = 0;
    private Integer skipped = 0;
    private Integer others = 0;

    public NamedAttributeContext(T attribute, Test test) {
        this.attr = attribute;
        addTest(test);
    }

    public void addTest(Test test) {
        if (test == null)
            throw new IllegalArgumentException("Test cannot be null");
        testList.add(test);
        refresh(test);
    }

    private synchronized void refresh(Test test) {
        if (test.getStatus() == Status.PASS)
            passed++;
        else if (test.getStatus() == Status.FAIL)
            failed++;
        else if (test.getStatus() == Status.SKIP)
            skipped++;
        else
            others++;
    }

    public void refresh() {
        passed = failed = skipped = others = 0;
        testList.forEach(this::refresh);
    }

    public Integer size() {
        return passed + failed + skipped + others;
    }
}

@@ -150,20 +150,68 @@
 va.util.
-List
+HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0Aimpor
@@ -706,123 +706,57 @@
 ate 
-Integer passed = 0;%0A    private Integer failed = 0;%0A    private Integer skipped = 0;%0A    private Integer others = 0
+Map%3CStatus, Integer%3E statusDist = new HashMap%3C%3E()
 ;%0A%0A 
@@ -1121,27 +1121,40 @@
 ) %7B%0A        
-if 
+statusDist.merge
 (test.getSta
@@ -1162,348 +1162,562 @@
 us()
- == Status.PASS)%0A            passed++;%0A        else if (test.getStatus() == Status.FAIL)%0A            failed++
+, 1, Integer::sum);%0A    %7D%0A%0A    public void refresh() %7B%0A        statusDist.clear();%0A        testList.forEach(this::refresh);%0A    %7D%0A%0A    public Integer size() %7B%0A        return statusDist.values().stream().reduce(0, Integer::sum)
 ;%0A    
+%7D%0A%0A
     
-else if (test.getStatus() == 
+public Integer getPassed() %7B%0A        return get(
 Status.
-SKIP)
+PASS);
 %0A    
+%7D%0A%0A
     
-    skipped++;%0A        else%0A            others++;%0A    %7D%0A%0A    public void refresh() %7B%0A        passed = failed = skipped = others = 0;%0A        testList.forEach(this::refresh
+private Integer get(Status s) %7B%0A        return statusDist.get(s) == null ? 0 : statusDist.get(s);%0A    %7D%0A%0A    public Integer getFailed() %7B%0A        return get(Status.FAIL);%0A    %7D%0A%0A    public Integer getSkipped() %7B%0A        return get(Status.SKIP
 );%0A 
@@ -1733,36 +1733,41 @@
  public Integer 
-size
+getOthers
 () %7B%0A        ret
@@ -1774,42 +1774,27 @@
 urn 
-passed + failed + skipped + others
+get(Status.WARNING)
 ;%0A  

Use a status Map to hold status counts for attributes