diff --git a/src/main/java/com/pump/jira/JiraPump.java b/src/main/java/com/pump/jira/JiraPump.java
index 2f5120970b1d4fe7a676155dc31784aa83feb970..885dfebd8947dcc4bdaab6af7f54301d1616060c 100644
--- a/src/main/java/com/pump/jira/JiraPump.java
+++ b/src/main/java/com/pump/jira/JiraPump.java
@@ -1,15 +1,12 @@
 package com.pump.jira;
 
 import com.atlassian.jira.rest.client.api.JiraRestClient;
-import com.atlassian.jira.rest.client.api.SearchRestClient;
-import com.atlassian.jira.rest.client.api.domain.Issue;
-import com.atlassian.jira.rest.client.api.domain.Project;
-import com.atlassian.jira.rest.client.api.domain.SearchResult;
 import com.atlassian.jira.rest.client.auth.AnonymousAuthenticationHandler;
 import com.atlassian.jira.rest.client.auth.BasicHttpAuthenticationHandler;
 import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
 import com.pump.jira.service.AttachmentService;
 import com.pump.jira.service.IssueService;
+import com.pump.jira.service.LabelService;
 import com.pump.jira.service.ProjectService;
 import com.pump.jira.service.UserService;
 import com.pump.jira.service.VersionService;
@@ -19,15 +16,6 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.net.URI;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.stream.StreamSupport;
 
 @Slf4j
 @Service
@@ -46,131 +34,63 @@ public class JiraPump {
     @Value("${jira.project.key}")
     private String projectKey;
 
-    @Value("${jira.max.issues}")
-    private int maxIssues;
-
-    @Value("${jira.timeout.seconds}")
-    private int timeoutSeconds;
-
     private final UserService userService;
     private final VersionService versionService;
     private final IssueService issueService;
     private final ProjectService projectService;
     private final AttachmentService attachmentService;
+    private final LabelService labelService;
+
 
     // TODO we need to prepare following "objects" (name of SPADe tables)
-    // ToolProjectInstance (Project)
+    // Artifact âś… -> attachmentService.fetchAttachments
     // Configuration
-    // DevelopmentProgram
-    // Identity
-    // IdentityGroup
-    // Iteration
-    // Phase
-    // Project
-    // Role
+    // DevelopmentProgram âś… -> fetchProjectCategory
+    // Identity âś… -> userService.fetchApplicationUsers
+    // IdentityGroup âś… -> userService.fetchGroupBean(restClient)
+    // Iteration âś… -> versionService.fetchIterations
+    // Phase âś… -> versionService.fetchVersion
+    // Project ???
+    // Role âś… -> userService.fetchProjectRoleActors
     // Release
-    // ToolProjectInstance
-    // WorkItemChange
+    // ToolProjectInstance âś… -> projectService.fetchToolProjectInstances
+    // WorkItemChange âś… -> issueService.fetchChanges
     // WorkUnit
-    // WorkUnitCategory
-    // WorkUnitPriority
+    // WorkUnitCategory âś… -> issueService.fetchProjectComponents
+    // WorkUnitPriority âś… -> issueService.fetchWorkUnitPriority
     // WorkUnitRelation
-    // WorkUnitSeverity
-    // WorkUnitStatus
-    // WorkUnitType
-    // any
+    // WorkUnitSeverity ❌ -> issueService.fetchIssues
+    // WorkUnitStatus âś…-> issueService.fetchStatusAndResolution
+    // WorkUnitType âś… -> issueService.fetchAllIssueTypes
+    // any âś… -> labelService.fetchLabels
     public void run() {
         log.info("Starting JiraPump for project {}...", projectKey);
         JiraRestClient restClient = null;
 
         try {
             restClient = createJiraRestClient();
-            attachmentService.fetchAttachments(restClient);
-            userService.fetchApplicationUsers(restClient);
-            versionService.fetchIterations(restClient);
-            projectService.fetchToolProjectInstances(restClient);
-            issueService.fetchIssues(restClient);
-
-//            TODO these methods will be moved into separate services
-//            Project project = fetchProjectDetails(restClient);
-//            fetchProjectVersions(project);
-//            fetchProjectComponents(project);
-//            fetchProjectIssues(restClient);
-//            fetchRecentActivity(restClient);
-//            fetchAssignedIssues(restClient);
-//            fetchCriticalIssues(restClient);
-//            fetchUserInformation(restClient);
-//            fetchIssueTypeStatistics(restClient);
-//            fetchWorkflowInformation(restClient);
-//            fetchProjectRoles(restClient);
-            fetchCustomFieldValues(restClient, "Story Points");
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            log.error("Interrupted while fetching data from Jira", e);
-        } catch (ExecutionException | TimeoutException e) {
-            log.error("Error fetching data from Jira", e);
-        } catch (Exception e) {
+//            attachmentService.fetchAttachments(restClient);
+//            userService.fetchApplicationUsers(restClient);
+//            versionService.fetchIterations(restClient);
+//            projectService.fetchToolProjectInstances(restClient);
+//            issueService.fetchIssues(restClient);
+//            issueService.fetchAllIssueTypes(restClient);
+//            labelService.fetchLabels(restClient);
+//            issueService.fetchProjectComponents(restClient);
+//            userService.fetchProjectRoleActors(restClient);
+//            userService.fetchGroupBean(restClient);
+//            issueService.fetchStatusAndResolution(restClient);
+//            projectService.fetchProjectCategory(restClient);
+//            issueService.fetchWorkUnitPriority(restClient);
+//            versionService.fetchVersion(restClient);
+//            issueService.fetchChanges(restClient);
+        }  catch (Exception e) {
             log.error("Unexpected error while working with Jira", e);
         } finally {
             closeClient(restClient);
         }
     }
 
-
-    private void fetchProjectIssues(JiraRestClient restClient) throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching issues for project: {}", projectKey);
-
-        // Query open issues
-        String jqlOpen = "project = " + projectKey + " AND status = Open ORDER BY created DESC";
-        fetchIssuesByJql(restClient, jqlOpen, "Open issues");
-
-        // Query recently resolved issues
-        String jqlResolved = "project = " + projectKey + " AND status = Resolved ORDER BY resolutiondate DESC";
-        fetchIssuesByJql(restClient, jqlResolved, "Recently resolved issues");
-    }
-
-    private void fetchIssuesByJql(JiraRestClient restClient, String jql, String category)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Executing search: {}", jql);
-
-        SearchRestClient searchClient = restClient.getSearchClient();
-        SearchResult result = searchClient.searchJql(jql, maxIssues, 0, null)
-                                          .get(timeoutSeconds, TimeUnit.SECONDS);
-
-        log.info("Found {} {} (displaying up to {})", result.getTotal(), category, maxIssues);
-
-        List<Issue> issues = StreamSupport.stream(result.getIssues().spliterator(), false)
-                                          .toList();
-
-        for (Issue issue : issues) {
-            log.info("  [{}] {} - {} (Reporter: {}, Status: {})",
-                issue.getKey(),
-                issue.getSummary(),
-                issue.getCreationDate().toString(),
-                issue.getReporter() != null ? issue.getReporter().getDisplayName() : "Unknown",
-                issue.getStatus().getName()
-            );
-        }
-    }
-
-    private void fetchRecentActivity(JiraRestClient restClient) throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching recent activity");
-
-        String jqlRecent = "project = " + projectKey + " ORDER BY updated DESC";
-        SearchResult result = restClient.getSearchClient().searchJql(jqlRecent, 10, 0, null)
-                                        .get(timeoutSeconds, TimeUnit.SECONDS);
-
-        log.info("Recent activity:");
-
-        result.getIssues().forEach(issue ->
-            log.info("  [{}] {} - Updated: {}",
-                issue.getKey(),
-                issue.getSummary(),
-                issue.getUpdateDate().toString()
-            )
-        );
-    }
-
     private JiraRestClient createJiraRestClient() {
         log.info("Establishing connection to Jira at {}", jiraApiUrl);
         AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
@@ -191,53 +111,6 @@ public class JiraPump {
         }
     }
 
-    private Project fetchProjectDetails(JiraRestClient restClient)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching project: {}", projectKey);
-        Project project = restClient.getProjectClient()
-                                    .getProject(projectKey)
-                                    .get(timeoutSeconds, TimeUnit.SECONDS);
-
-        log.info("Project: {} ({})", project.getName(), project.getKey());
-        log.info("Description: {}", project.getDescription());
-        log.info("Lead: {}", project.getLead().getDisplayName());
-        log.info("URI: {}", project.getUri());
-
-        return project;
-    }
-
-    private void fetchProjectVersions(Project project) {
-        log.info("Project versions:");
-        project.getVersions().forEach(version ->
-            log.info("  {} (released: {}, archived: {})",
-                version.getName(),
-                version.isReleased(),
-                version.isArchived()
-            )
-        );
-    }
-
-    private void fetchProjectComponents(Project project) {
-        log.info("Project components:");
-        project.getComponents().forEach(component ->
-            log.info("  {}", component.getName())
-        );
-    }
-
-    private void fetchCriticalIssues(JiraRestClient restClient)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        String jqlCritical = "project = " + projectKey + " AND priority in (Blocker, Critical) ORDER BY created DESC";
-        fetchIssuesByJql(restClient, jqlCritical, "Critical issues");
-    }
-
-    private void fetchAssignedIssues(JiraRestClient restClient)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        if (username != null && !username.isEmpty()) {
-            String jqlAssigned = "project = " + projectKey + " AND assignee = currentUser() ORDER BY updated DESC";
-            fetchIssuesByJql(restClient, jqlAssigned, "Issues assigned to you");
-        }
-    }
-
     private void closeClient(JiraRestClient restClient) {
         if (restClient != null) {
             try {
@@ -248,119 +121,4 @@ public class JiraPump {
             }
         }
     }
-
-    private void fetchUserInformation(JiraRestClient restClient)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching active contributors in project");
-
-        String jqlActive = "project = " + projectKey + " ORDER BY updated DESC";
-        SearchResult result = restClient.getSearchClient().searchJql(jqlActive, 50, 0, null)
-                                        .get(timeoutSeconds, TimeUnit.SECONDS);
-
-        Set<String> usernames = new HashSet<>();
-        result.getIssues().forEach(issue -> {
-            if (issue.getReporter() != null) {
-                usernames.add(issue.getReporter().getName());
-            }
-            if (issue.getAssignee() != null) {
-                usernames.add(issue.getAssignee().getName());
-            }
-        });
-
-        log.info("Found {} active contributors", usernames.size());
-        for (String username : usernames) {
-            try {
-                com.atlassian.jira.rest.client.api.domain.User user =
-                    restClient.getUserClient().getUser(username)
-                              .get(timeoutSeconds, TimeUnit.SECONDS);
-                log.info("  User: {} ({}), Email: {}, Active: {}",
-                    user.getDisplayName(),
-                    user.getName(),
-                    user.getEmailAddress(),
-                    user.isActive());
-            } catch (Exception e) {
-                log.warn("Could not fetch details for user: {}", username);
-            }
-        }
-    }
-
-    private void fetchIssueTypeStatistics(JiraRestClient restClient)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching issue type statistics");
-
-        Project project = restClient.getProjectClient().getProject(projectKey)
-                                    .get(timeoutSeconds, TimeUnit.SECONDS);
-
-        project.getIssueTypes().forEach(issueType -> {
-            try {
-                String jql = "project = " + projectKey + " AND issuetype = \"" + issueType.getName() + "\"";
-                SearchResult result = restClient.getSearchClient().searchJql(jql, 0, 0, null)
-                                                .get(timeoutSeconds, TimeUnit.SECONDS);
-
-                log.info("  {} - {} issues", issueType.getName(), result.getTotal());
-            } catch (Exception e) {
-                log.warn("Error counting issues of type {}: {}", issueType.getName(), e.getMessage());
-            }
-        });
-    }
-
-    private void fetchWorkflowInformation(JiraRestClient restClient)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching workflow status information");
-
-        String jql = "project = " + projectKey + " ORDER BY created DESC";
-        SearchResult result = restClient.getSearchClient().searchJql(jql, 1, 0, null)
-                                        .get(timeoutSeconds, TimeUnit.SECONDS);
-
-        if (result.getTotal() > 0) {
-            Issue sampleIssue = result.getIssues().iterator().next();
-
-            log.info("Status categories in workflow:");
-            Map<String, Integer> statusCounts = new HashMap<>();
-
-            // Now get all issues and count by status
-            String jqlAll = "project = " + projectKey;
-            SearchResult allResult = restClient.getSearchClient().searchJql(jqlAll, maxIssues, 0, null)
-                                               .get(timeoutSeconds, TimeUnit.SECONDS);
-
-            allResult.getIssues().forEach(issue -> {
-                String status = issue.getStatus().getName();
-                statusCounts.put(status, statusCounts.getOrDefault(status, 0) + 1);
-            });
-
-            statusCounts.forEach((status, count) ->
-                log.info("  {} - {} issues", status, count)
-            );
-        }
-    }
-
-    private void fetchProjectRoles(JiraRestClient restClient)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching project roles");
-
-        final String roleEndpoint = jiraApiUrl + "/rest/api/2/project/" + projectKey + "/role";
-
-        log.info("Note: Project role details require custom REST API implementation");
-    }
-
-    private void fetchCustomFieldValues(JiraRestClient restClient, String customFieldName)
-        throws InterruptedException, ExecutionException, TimeoutException {
-        log.info("Fetching values for custom field: {}", customFieldName);
-
-        String jql = "project = " + projectKey;
-        SearchResult result = restClient.getSearchClient().searchJql(jql, maxIssues, 0, null)
-                                        .get(timeoutSeconds, TimeUnit.SECONDS);
-
-        result.getIssues().forEach(issue -> {
-            issue.getFields().forEach(field -> {
-                if (field.getName().equals(customFieldName)) {
-                    log.info("  [{}] {} - {}: {}",
-                        issue.getKey(),
-                        issue.getSummary(),
-                        customFieldName,
-                        field.getValue() != null ? field.getValue().toString() : "null");
-                }
-            });
-        });
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/pump/jira/service/AttachmentService.java b/src/main/java/com/pump/jira/service/AttachmentService.java
index 691bfd92842f90e461771a2d01e4b91becee85cd..39b37058f1318fbbaebadefb8c9fbfc20a48602e 100644
--- a/src/main/java/com/pump/jira/service/AttachmentService.java
+++ b/src/main/java/com/pump/jira/service/AttachmentService.java
@@ -21,10 +21,10 @@ public class AttachmentService {
     @Value("${jira.project.key}")
     private String projectKey;
 
-    @Value("${jira.max.issues:100}")
+    @Value("${jira.max.issues}")
     private int maxIssues;
 
-    @Value("${jira.timeout.seconds:30}")
+    @Value("${jira.timeout.seconds}")
     private int timeoutSeconds;
 
     /// id -> Artifact.externalId -> TODO NOT EXISTING
diff --git a/src/main/java/com/pump/jira/service/IssueService.java b/src/main/java/com/pump/jira/service/IssueService.java
index 7a98daad3364d1ae4d14284548216b58b4b60d4f..3922116fa53aee2fabb41399801ade6d59134094 100644
--- a/src/main/java/com/pump/jira/service/IssueService.java
+++ b/src/main/java/com/pump/jira/service/IssueService.java
@@ -7,6 +7,7 @@ import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.net.URI;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -180,21 +181,465 @@ public class IssueService {
         return dateTime != null ? dateTime.toString("yyyy-MM-dd HH:mm:ss") : "N/A";
     }
 
+
+    /// id -> WorkUnitType.externalId
+    /// name -> WorkUnitType.name
+    /// description + subtask -> WorkUnitType.description
+    public void fetchAllIssueTypes(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching all available issue types");
+
+        try {
+            // Get project to access available issue types
+            Project project = restClient.getProjectClient()
+                                        .getProject(projectKey)
+                                        .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            log.info("Available Issue Types for project {}:", projectKey);
+
+            for (IssueType issueType : project.getIssueTypes()) {
+                log.info("------------------------------------");
+                log.info("  ID: {}", issueType.getId());
+                log.info("  Name: {}", issueType.getName());
+
+                if (issueType.getDescription() != null && !issueType.getDescription().isEmpty()) {
+                    log.info("  Description: {}", issueType.getDescription());
+                } else {
+                    log.info("  Description: None");
+                }
+
+                log.info("  Is Subtask: {}", issueType.isSubtask());
+
+                // Count issues of this type
+                String jql = "project = " + projectKey + " AND issuetype = " + issueType.getId();
+                SearchResult searchResult = restClient.getSearchClient()
+                                                      .searchJql(jql, 1, 0, null)
+                                                      .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                log.info("  Number of issues: {}", searchResult.getTotal());
+            }
+
+            log.info("------------------------------------");
+            log.info("Total issue types: {}", project.getIssueTypes().toString());
+        } catch (Exception e) {
+            log.error("Error fetching issue types: {}", e.getMessage(), e);
+        }
+    }
+
+    /// id -> WorkUnitCategory.externalId
+    /// name -> WorkUnitCategory.name
+    /// description -> WorkUnitCategory.description
+    public void fetchProjectComponents(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching project components for project {}", projectKey);
+
+        try {
+            // Get detailed project information with components
+            Project project = restClient.getProjectClient()
+                                        .getProject(projectKey)
+                                        .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            Iterable<BasicComponent> components = project.getComponents();
+            boolean hasComponents = components.iterator().hasNext();
+
+            if (hasComponents) {
+                log.info("Found components for project {}:", projectKey);
+
+                for (BasicComponent component : components) {
+                    log.info("------------------------------------");
+                    log.info("ID: {}", component.getId());
+                    log.info("Name: {}", component.getName());
+
+                    // Get detailed component information
+                    Component detailedComponent = restClient.getComponentClient()
+                                                            .getComponent(component.getSelf())
+                                                            .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                    if (detailedComponent.getDescription() != null && !detailedComponent.getDescription().isEmpty()) {
+                        log.info("Description: {}", detailedComponent.getDescription());
+                    } else {
+                        log.info("Description: None");
+                    }
+
+                    if (detailedComponent.getLead() != null) {
+                        log.info("Lead: {} ({})",
+                            detailedComponent.getLead().getDisplayName(),
+                            detailedComponent.getLead().getName());
+                    }
+
+                    // Count issues using this component
+                    String jql = "project = " + projectKey + " AND component = \"" + component.getName() + "\"";
+                    SearchResult searchResult = restClient.getSearchClient()
+                                                          .searchJql(jql, 1, 0, null)
+                                                          .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                    log.info("Number of issues: {}", searchResult.getTotal());
+                }
+
+                log.info("------------------------------------");
+                log.info("Total components: {}", countItems(components));
+            } else {
+                log.info("No components found for project {}", projectKey);
+            }
+        } catch (Exception e) {
+            log.error("Error fetching project components: {}", e.getMessage(), e);
+        }
+    }
+
     /**
-     * Formats bytes to a human-readable size
+     * Helper method to count items in an Iterable
      */
-    private String formatBytes(Long bytes) {
-        if (bytes == null) return "Unknown";
+    private int countItems(Iterable<?> iterable) {
+        int count = 0;
+        for (Object item : iterable) {
+            count++;
+        }
+        return count;
+    }
+
+    /// Fetching two types and mapping into same table
+    ///
+    /// 1. Status
+    /// id -> WorkUnitStatus.externalId
+    /// name -> WorkUnitStatus.name
+    /// description -> WorkUnitStatus.description
+    ///
+    /// 2. Resolution
+    /// id -> WorkUnitResolution.externalId
+    /// name -> WorkUnitResolution.name
+    /// description -> WorkUnitResolution.description
+    public void fetchStatusAndResolution(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching statuses and resolutions for project {}", projectKey);
+
+        try {
+            // Collect statuses from project issues
+            log.info("Fetching statuses from project issues...");
+            String jql = "project = " + projectKey;
+            SearchResult searchResult = restClient.getSearchClient()
+                                                  .searchJql(jql, maxIssues, 0, null)
+                                                  .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            // Track unique statuses and resolutions
+            java.util.Map<String, Status> statuses = new java.util.HashMap<>();
+            java.util.Map<String, Resolution> resolutions = new java.util.HashMap<>();
+
+            // Extract status and resolution from each issue
+            for (Issue issue : searchResult.getIssues()) {
+                if (issue.getStatus() != null) {
+                    Status status = issue.getStatus();
+                    statuses.putIfAbsent(status.getId().toString(), status);
+                }
+
+                if (issue.getResolution() != null) {
+                    Resolution resolution = issue.getResolution();
+                    resolutions.putIfAbsent(resolution.getId().toString(), resolution);
+                }
+            }
+
+            // Log statuses information
+            log.info("------------------------------------");
+            log.info("Available Statuses:");
+            for (Status status : statuses.values()) {
+                log.info("------------------------------------");
+                log.info("Status ID: {}", status.getId());
+                log.info("Status Name: {}", status.getName());
+
+                if (status.getDescription() != null) {
+                    log.info("Status Description: {}", status.getDescription());
+                } else {
+                    log.info("Status Description: None");
+                }
+
+                if (status.getIconUrl() != null) {
+                    log.info("Status Icon URL: {}", status.getIconUrl());
+                }
+
+                // Count issues with this status
+                String statusJql = "project = " + projectKey + " AND status = \"" + status.getName() + "\"";
+                SearchResult statusResult = restClient.getSearchClient()
+                                                      .searchJql(statusJql, 1, 0, null)
+                                                      .get(timeoutSeconds, TimeUnit.SECONDS);
+                log.info("Number of issues: {}", statusResult.getTotal());
+            }
+
+            log.info("------------------------------------");
+            log.info("Total statuses: {}", statuses.size());
+
+            // Log resolutions information
+            log.info("------------------------------------");
+            log.info("Available Resolutions:");
+            for (Resolution resolution : resolutions.values()) {
+                log.info("------------------------------------");
+                log.info("Resolution ID: {}", resolution.getId());
+                log.info("Resolution Name: {}", resolution.getName());
+
+                if (resolution.getDescription() != null) {
+                    log.info("Resolution Description: {}", resolution.getDescription());
+                } else {
+                    log.info("Resolution Description: None");
+                }
+
+                // Count issues with this resolution
+                String resolutionJql = "project = " + projectKey + " AND resolution = \"" + resolution.getName() + "\"";
+                SearchResult resolutionResult = restClient.getSearchClient()
+                                                          .searchJql(resolutionJql, 1, 0, null)
+                                                          .get(timeoutSeconds, TimeUnit.SECONDS);
+                log.info("Number of issues: {}", resolutionResult.getTotal());
+            }
 
-        final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
-        int unitIndex = 0;
-        double size = bytes;
+            log.info("------------------------------------");
+            log.info("Total resolutions: {}", resolutions.size());
 
-        while (size > 1024 && unitIndex < units.length - 1) {
-            size /= 1024;
-            unitIndex++;
+        } catch (Exception e) {
+            log.error("Error fetching status and resolution information: {}", e.getMessage(), e);
         }
+    }
 
-        return String.format("%.2f %s", size, units[unitIndex]);
+    /// id -> WorkUnitPriority.externalId
+    /// name -> WorkUnitPriority.name
+    /// description -> WorkUnitPriority.description
+    public void fetchWorkUnitPriority(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching work unit priorities for project {}", projectKey);
+
+        try {
+            // Get all priorities through issues in the project
+            String jql = "project = " + projectKey;
+            SearchResult searchResult = restClient.getSearchClient()
+                                                  .searchJql(jql, maxIssues, 0, null)
+                                                  .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            // Track unique priorities
+            java.util.Map<String, BasicPriority> priorities = new java.util.HashMap<>();
+
+            // Extract priority from each issue
+            for (Issue issue : searchResult.getIssues()) {
+                if (issue.getPriority() != null) {
+                    BasicPriority priority = issue.getPriority();
+                    priorities.putIfAbsent(priority.getId().toString(), priority);
+                }
+            }
+
+            // Log priorities information
+            log.info("------------------------------------");
+            log.info("Available Priorities:");
+
+            if (priorities.isEmpty()) {
+                log.info("No priorities found in project issues");
+            } else {
+                for (BasicPriority priority : priorities.values()) {
+                    log.info("------------------------------------");
+                    log.info("Priority ID: {}", priority.getId());
+                    log.info("Priority Name: {}", priority.getName());
+
+                    // Try to get more information about the priority
+                    try {
+                        URI selfUri = priority.getSelf();
+                        if (selfUri != null) {
+                            log.info("Priority URI: {}", selfUri);
+                        }
+                    } catch (Exception e) {
+                        log.debug("Could not get priority URI: {}", e.getMessage());
+                    }
+
+                    // For BasicPriority, description might not be directly available
+                    // We'll note this limitation
+                    log.info("Priority Description: Not available in BasicPriority");
+
+                    // Count issues with this priority
+                    String priorityJql = "project = " + projectKey + " AND priority = \"" + priority.getName() + "\"";
+                    SearchResult priorityResult = restClient.getSearchClient()
+                                                            .searchJql(priorityJql, 1, 0, null)
+                                                            .get(timeoutSeconds, TimeUnit.SECONDS);
+                    log.info("Number of issues: {}", priorityResult.getTotal());
+                }
+
+                log.info("------------------------------------");
+                log.info("Total priorities: {}", priorities.size());
+            }
+        } catch (Exception e) {
+            log.error("Error fetching priority information: {}", e.getMessage(), e);
+        }
     }
+
+    /// 6 returning types
+    /// 1) ChangItemBean
+    /// all_attributes -> WorkItemChange.description
+    /// 2) Worklog
+    /// timeSpent -> WorkItemChange.description
+    /// startDate -> WorkItemChange.description
+    /// 3) ChangeHistory
+    /// issue -> WorkItemChange.changedItem
+    /// 4) Comment
+    /// issue -> WorkItemChange.changedItem
+    /// 5) Resolution
+    /// name + description -> WorkItemChange.description
+    /// (if has Resolution) -> WorkItemChange.changedItem
+    /// 6) Issue
+    public void fetchChanges(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching issue changes, history, worklogs and comments for project {}", projectKey);
+
+        try {
+            // Get a subset of issues to analyze changes
+            String jql = "project = " + projectKey + " ORDER BY updated DESC";
+            SearchResult searchResult = restClient.getSearchClient()
+                                                  .searchJql(jql, maxIssues, 0, null)
+                                                  .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            log.info("Analyzing changes for {} issues (showing up to {})", searchResult.getTotal(), maxIssues);
+
+            for (Issue issue : searchResult.getIssues()) {
+                log.info("------------------------------------");
+                log.info("Issue: {} - {}", issue.getKey(), issue.getSummary());
+
+                // Fetch complete issue with all fields including changelog
+                Issue fullIssue = restClient.getIssueClient()
+                                            .getIssue(issue.getKey())
+                                            .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                // Log resolution if available
+                if (fullIssue.getResolution() != null) {
+                    Resolution resolution = fullIssue.getResolution();
+                    log.info("Resolution ID: {}", resolution.getId());
+                    log.info("Resolution Name: {}", resolution.getName());
+                    log.info("Resolution Description: {}",
+                        resolution.getDescription() != null ? resolution.getDescription() : "None");
+                } else {
+                    log.info("Resolution: None (issue not resolved)");
+                }
+
+                // Extract Changelog/History using reflection (as it might vary between API versions)
+                try {
+                    Object changelogObj = fullIssue.getClass().getMethod("getChangelog").invoke(fullIssue);
+                    if (changelogObj != null) {
+                        // Get entries/histories collection
+                        Iterable<?> historiesObj = (Iterable<?>) changelogObj.getClass().getMethod("getHistories").invoke(changelogObj);
+
+                        for (Object historyObj : historiesObj) {
+                            String authorName = "Unknown";
+                            String created = "Unknown";
+
+                            try {
+                                // Get author
+                                Object authorObj = historyObj.getClass().getMethod("getAuthor").invoke(historyObj);
+                                if (authorObj != null) {
+                                    authorName = (String) authorObj.getClass().getMethod("getDisplayName").invoke(authorObj);
+                                }
+
+                                // Get creation date
+                                Object createdObj = historyObj.getClass().getMethod("getCreated").invoke(historyObj);
+                                if (createdObj != null) {
+                                    created = createdObj.toString();
+                                }
+                            } catch (Exception e) {
+                                // Skip if methods not available
+                            }
+
+                            log.info("Change History - Author: {}, Created: {}", authorName, created);
+                            log.info("  Issue: {}", issue.getKey());
+
+                            // Get change items
+                            try {
+                                Iterable<?> itemsObj = (Iterable<?>) historyObj.getClass().getMethod("getItems").invoke(historyObj);
+
+                                for (Object itemObj : itemsObj) {
+                                    // Extract change item attributes
+                                    String field = getStringAttribute(itemObj, "getField");
+                                    String fieldType = getStringAttribute(itemObj, "getFieldType");
+                                    String from = getStringAttribute(itemObj, "getFrom");
+                                    String fromString = getStringAttribute(itemObj, "getFromString");
+                                    String to = getStringAttribute(itemObj, "getTo");
+                                    String toString = getStringAttribute(itemObj, "getToString");
+
+                                    log.info("  ChangeItemBean:");
+                                    log.info("    Field: {}", field);
+                                    log.info("    Field Type: {}", fieldType);
+                                    log.info("    From: {} ({})", from, fromString);
+                                    log.info("    To: {} ({})", to, toString);
+                                }
+                            } catch (Exception e) {
+                                log.debug("Could not extract change items: {}", e.getMessage());
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    log.debug("Could not extract changelog: {}", e.getMessage());
+                }
+
+                // Process Worklogs
+                if (fullIssue.getWorklogs() != null && fullIssue.getWorklogs().iterator().hasNext()) {
+                    log.info("Worklogs:");
+                    for (Worklog worklog : fullIssue.getWorklogs()) {
+                        log.info("  Author: {}", worklog.getAuthor().getDisplayName());
+                        log.info("  Time Spent: {} ({}m)", worklog.getMinutesSpent() > 0 ?
+                            formatWorkTime(worklog.getMinutesSpent()) : "Unknown", worklog.getMinutesSpent());
+                        log.info("  Start Date: {}", worklog.getStartDate() != null ?
+                            worklog.getStartDate().toString("yyyy-MM-dd HH:mm:ss") : "Unknown");
+
+                        if (worklog.getComment() != null && !worklog.getComment().isEmpty()) {
+                            String comment = worklog.getComment();
+                            if (comment.length() > 100) {
+                                comment = comment.substring(0, 97) + "...";
+                            }
+                            log.info("  Comment: {}", comment);
+                        }
+                    }
+                }
+
+                // Process Comments
+                if (fullIssue.getComments() != null && fullIssue.getComments().iterator().hasNext()) {
+                    log.info("Comments:");
+                    for (Comment comment : fullIssue.getComments()) {
+                        log.info("  Author: {}", comment.getAuthor().getDisplayName());
+                        log.info("  Created: {}", formatDateTime(comment.getCreationDate()));
+                        log.info("  Updated: {}", formatDateTime(comment.getUpdateDate()));
+                        log.info("  Issue: {}", issue.getKey());
+
+                        String bodyText = comment.getBody();
+                        if (bodyText.length() > 100) {
+                            bodyText = bodyText.substring(0, 97) + "...";
+                        }
+                        log.info("  Body: {}", bodyText);
+                    }
+                }
+            }
+
+            log.info("------------------------------------");
+            log.info("Change fetching completed");
+
+        } catch (Exception e) {
+            log.error("Error fetching changes: {}", e.getMessage(), e);
+        }
+    }
+
+    /**
+     * Helper method to safely extract string attributes from objects using reflection
+     */
+    private String getStringAttribute(Object obj, String methodName) {
+        try {
+            Object result = obj.getClass().getMethod(methodName).invoke(obj);
+            return result != null ? result.toString() : "null";
+        } catch (Exception e) {
+            return "N/A";
+        }
+    }
+
+    /**
+     * Format minutes into human-readable work time (hours and minutes)
+     */
+    private String formatWorkTime(int minutes) {
+        int hours = minutes / 60;
+        int mins = minutes % 60;
+
+        if (hours > 0 && mins > 0) {
+            return hours + "h " + mins + "m";
+        } else if (hours > 0) {
+            return hours + "h";
+        } else {
+            return mins + "m";
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/pump/jira/service/LabelService.java b/src/main/java/com/pump/jira/service/LabelService.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f9823764fb60cb695ab4c4518204ac2551cf5f8
--- /dev/null
+++ b/src/main/java/com/pump/jira/service/LabelService.java
@@ -0,0 +1,70 @@
+package com.pump.jira.service;
+
+import com.atlassian.jira.rest.client.api.JiraRestClient;
+import com.atlassian.jira.rest.client.api.domain.Issue;
+import com.atlassian.jira.rest.client.api.domain.SearchResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Service
+public class LabelService {
+
+    @Value("${jira.project.key}")
+    private String projectKey;
+
+    @Value("${jira.timeout.seconds}")
+    private int timeoutSeconds;
+
+    /**
+     * Fetches all labels used in the project
+     *
+     * @param restClient The Jira REST client
+     */
+    public void fetchLabels(JiraRestClient restClient) {
+        log.info("Fetching labels for project {}", projectKey);
+
+        try {
+            // Search for issues with labels in the project
+            String jql = "project = " + projectKey + " AND labels IS NOT EMPTY ORDER BY updated DESC";
+            SearchResult result = restClient.getSearchClient()
+                                            .searchJql(jql, 100, 0, null)
+                                            .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            Set<String> uniqueLabels = new HashSet<>();
+            Map<String, Integer> labelCounts = new HashMap<>();
+
+            // Collect unique labels and count occurrences
+            for (Issue issue : result.getIssues()) {
+                if (issue.getLabels() != null && !issue.getLabels().isEmpty()) {
+                    for (String label : issue.getLabels()) {
+                        uniqueLabels.add(label);
+                        labelCounts.put(label, labelCounts.getOrDefault(label, 0) + 1);
+                    }
+                }
+            }
+
+            // Display summary of all labels
+            log.info("Found {} unique labels in project {}:", uniqueLabels.size(), projectKey);
+
+            // Sort labels by frequency
+            labelCounts.entrySet().stream()
+                       .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
+                       .forEach(entry -> log.info("  Label: {} (used in {} issues)", entry.getKey(), entry.getValue()));
+
+            // Note about custom field ID for labels
+            log.info("Labels in Jira are stored in system field 'labels'");
+            log.info("Custom field ID: system (not a custom field)");
+
+        } catch (Exception e) {
+            log.error("Error fetching labels: {}", e.getMessage(), e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/pump/jira/service/ProjectService.java b/src/main/java/com/pump/jira/service/ProjectService.java
index 331ec8fe6a79afd62006ec9c803f1872fa59acca..5cd98cb10acde02b2a684313138e575d4b20182a 100644
--- a/src/main/java/com/pump/jira/service/ProjectService.java
+++ b/src/main/java/com/pump/jira/service/ProjectService.java
@@ -2,16 +2,24 @@ package com.pump.jira.service;
 
 import com.atlassian.jira.rest.client.api.JiraRestClient;
 import com.atlassian.jira.rest.client.api.domain.BasicComponent;
+import com.atlassian.jira.rest.client.api.domain.BasicProject;
 import com.atlassian.jira.rest.client.api.domain.IssueType;
 import com.atlassian.jira.rest.client.api.domain.Project;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+
 @Slf4j
 @Service
 public class ProjectService {
@@ -19,7 +27,7 @@ public class ProjectService {
     @Value("${jira.project.key}")
     private String projectKey;
 
-    @Value("${jira.timeout.seconds:30}")
+    @Value("${jira.timeout.seconds}")
     private int timeoutSeconds;
 
     /// id -> ToolProjectInstance.externalId
@@ -127,4 +135,158 @@ public class ProjectService {
             log.error("Error fetching project information: {}", e.getMessage(), e);
         }
     }
+
+    /// TODO - we have no ProjectCategory yet -> library does not support it
+    /// id -> DevelopmentProgram.externalId
+    /// name -> DevelopmentProgram.name
+    /// description -> DevelopmentProgram.description
+    /// min startDate -> DevelopmentProgram.startDate
+    /// where Project.projectCategory = this -> DevelopmentProgram.projects
+    public void fetchProjectCategory(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching project categories and their projects...");
+
+        try {
+            // Get all projects to analyze
+            Iterable<BasicProject> allProjects = restClient.getProjectClient()
+                                                           .getAllProjects()
+                                                           .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            // Maps to track categories and projects
+            Map<String, Map<String, Object>> categoriesMap = new HashMap<>();
+            Map<String, List<Project>> projectsByCategory = new HashMap<>();
+
+            // Process each project to categorize it
+            for (BasicProject basicProject : allProjects) {
+                try {
+                    Project project = restClient.getProjectClient()
+                                                .getProject(basicProject.getKey())
+                                                .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                    // Get category using reflection since direct API may not be available
+                    Object categoryObj = null;
+                    String categoryId = null;
+                    String categoryName = null;
+                    String categoryDescription = null;
+
+                    try {
+                        categoryObj = project.getClass().getMethod("getProjectCategory").invoke(project);
+                        if (categoryObj != null) {
+                            categoryId = categoryObj.getClass().getMethod("getId").invoke(categoryObj).toString();
+                            categoryName = categoryObj.getClass().getMethod("getName").invoke(categoryObj).toString();
+                            try {
+                                Object descObj = categoryObj.getClass().getMethod("getDescription").invoke(categoryObj);
+                                categoryDescription = descObj != null ? descObj.toString() : null;
+                            } catch (Exception e) {
+                                // Description not available
+                            }
+                        }
+                    } catch (Exception e) {
+                        // ProjectCategory not available in this API version
+                    }
+
+                    if (categoryId != null) {
+                        // Create category info map if it doesn't exist
+                        if (!categoriesMap.containsKey(categoryId)) {
+                            Map<String, Object> categoryInfo = new HashMap<>();
+                            categoryInfo.put("id", categoryId);
+                            categoryInfo.put("name", categoryName);
+                            categoryInfo.put("description", categoryDescription);
+                            categoriesMap.put(categoryId, categoryInfo);
+                        }
+
+                        // Add project to category
+                        projectsByCategory.computeIfAbsent(categoryId, k -> new ArrayList<>()).add(project);
+                    }
+                } catch (Exception e) {
+                    log.warn("Could not fetch details for project {}: {}", basicProject.getKey(), e.getMessage());
+                }
+            }
+
+            // Log information about each category and its projects
+            log.info("Found {} project categories", categoriesMap.size());
+
+            for (Map.Entry<String, Map<String, Object>> categoryEntry : categoriesMap.entrySet()) {
+                String categoryId = categoryEntry.getKey();
+                Map<String, Object> category = categoryEntry.getValue();
+
+                log.info("------------------------------------");
+                log.info("Category ID: {}", category.get("id"));
+                log.info("Category Name: {}", category.get("name"));
+
+                if (category.get("description") != null) {
+                    log.info("Category Description: {}", category.get("description"));
+                } else {
+                    log.info("Category Description: None");
+                }
+
+                List<Project> projects = projectsByCategory.get(categoryId);
+                if (projects != null && !projects.isEmpty()) {
+                    // Find earliest start date among projects
+                    Date earliestStartDate = null;
+
+                    log.info("Projects in this category ({}):", projects.size());
+                    for (Project project : projects) {
+                        log.info("  - {} ({})", project.getName(), project.getKey());
+
+                        // Try to get start date using reflection
+                        try {
+                            Object startDateObj = project.getClass().getMethod("getStartDate").invoke(project);
+                            if (startDateObj instanceof Date) {
+                                Date startDate = (Date) startDateObj;
+                                if (earliestStartDate == null || startDate.before(earliestStartDate)) {
+                                    earliestStartDate = startDate;
+                                }
+                            }
+                        } catch (Exception e) {
+                            // Start date not available
+                        }
+                    }
+
+                    if (earliestStartDate != null) {
+                        log.info("Earliest Project Start Date: {}", new SimpleDateFormat("yyyy-MM-dd").format(earliestStartDate));
+                    } else {
+                        log.info("No start dates available for projects in this category");
+                    }
+                } else {
+                    log.info("No projects found in this category");
+                }
+            }
+
+            // Log projects without categories
+            log.info("------------------------------------");
+            log.info("Projects without categories:");
+            int uncategorizedCount = 0;
+
+            for (BasicProject basicProject : allProjects) {
+                try {
+                    Project project = restClient.getProjectClient()
+                                                .getProject(basicProject.getKey())
+                                                .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                    Object categoryObj = null;
+                    try {
+                        categoryObj = project.getClass().getMethod("getProjectCategory").invoke(project);
+                    } catch (Exception e) {
+                        // ProjectCategory not available
+                    }
+
+                    if (categoryObj == null) {
+                        uncategorizedCount++;
+                        log.info("  - {} ({})", project.getName(), project.getKey());
+                    }
+                } catch (Exception e) {
+                    log.warn("Could not fetch details for project {}: {}", basicProject.getKey(), e.getMessage());
+                }
+            }
+
+            if (uncategorizedCount == 0) {
+                log.info("All projects have been assigned to categories");
+            }
+
+        } catch (Exception e) {
+            log.error("Error fetching project categories: {}", e.getMessage(), e);
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/pump/jira/service/UserService.java b/src/main/java/com/pump/jira/service/UserService.java
index 9e87adb34618d171f3d1b5339f944fc156d09049..3db7a7130103de58c430ebd15da6a9ab78b106a2 100644
--- a/src/main/java/com/pump/jira/service/UserService.java
+++ b/src/main/java/com/pump/jira/service/UserService.java
@@ -4,11 +4,15 @@ import com.atlassian.jira.rest.client.api.JiraRestClient;
 import com.atlassian.jira.rest.client.api.domain.BasicUser;
 import com.atlassian.jira.rest.client.api.domain.Issue;
 import com.atlassian.jira.rest.client.api.domain.Project;
+import com.atlassian.jira.rest.client.api.domain.ProjectRole;
+import com.atlassian.jira.rest.client.api.domain.RoleActor;
 import com.atlassian.jira.rest.client.api.domain.SearchResult;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import com.atlassian.jira.rest.client.api.domain.BasicProjectRole;
 
+import java.net.URI;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -30,6 +34,9 @@ public class UserService {
     @Value("${jira.timeout.seconds}")
     private int timeoutSeconds;
 
+    @Value("${jira.url}")
+    private String jiraApiUrl;
+
     /// TODO Most of the time return 401 Unauthorized - need to check permissions
     /// id -> Identity.externalId // TODO NEFUNGUJE PICO
     /// displayName -> Identity.name
@@ -108,6 +115,145 @@ public class UserService {
         }
     }
 
+    /// id -> Role.externalId
+    /// name + Project.projectLead -> Role.name
+    /// descriptor -> Role.description
+    /// TODO WE HAVE NO PERMISSION TO FETCH LAST TWO PROPS
+    public void fetchProjectRoleActors(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching project role actors for project {}", projectKey);
+
+        try {
+            // Get project for basic information and project lead
+            Project project = restClient.getProjectClient()
+                                        .getProject(projectKey)
+                                        .get(timeoutSeconds, TimeUnit.SECONDS);
 
+            // Log project lead information
+            BasicUser projectLead = project.getLead();
+            if (projectLead != null) {
+                log.info("Project lead: {} ({})", projectLead.getDisplayName(), projectLead.getName());
+                if (projectLead.getAccountId() != null) {
+                    log.info("Project lead account ID: {}", projectLead.getAccountId());
+                }
+            } else {
+                log.info("Project has no lead defined");
+            }
 
+            // Get project roles directly from the project
+            log.info("Project roles for project {}:", projectKey);
+            Iterable<BasicProjectRole> projectRoles = project.getProjectRoles();
+
+            Map<String, Set<String>> userRoleMap = new HashMap<>();
+
+            // Process each role
+            // Process each role
+            for (BasicProjectRole role : projectRoles) {
+                log.info("------------------------------------");
+                log.info("Role Name: {}, Role toString: {}", role.getName(), role.toString());
+            }
+
+            log.info("------------------------------------");
+            log.info("Summary of users and their roles:");
+            userRoleMap.forEach((userName, roles) -> {
+                log.info("User: {}, Roles: {}", userName, String.join(", ", roles));
+            });
+
+        } catch (Exception e) {
+            log.error("Error fetching project role actors: {}", e.getMessage(), e);
+            e.printStackTrace();
+        }
+    }
+
+    /// TODO - requires LOG IN - 401 ERROR RN
+    /// self -> IdentityGroup.externalId
+    /// name -> IdentityGroup.name
+    /// GroupMembership.users -> IdentityGroup.members
+    public void fetchGroupBean(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching group information...");
+
+        try {
+            // Get all groups that have access to the project
+            Project project = restClient.getProjectClient()
+                                        .getProject(projectKey)
+                                        .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            // Get project roles to find group-based role actors
+            Iterable<BasicProjectRole> projectRoles = project.getProjectRoles();
+            Set<String> groupNames = new HashSet<>();
+
+            // Process each role to identify groups
+            for (BasicProjectRole basicRole : projectRoles) {
+                try {
+                    ProjectRole role = restClient.getProjectRolesRestClient()
+                                                 .getRole(basicRole.getSelf())
+                                                 .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                    Iterable<RoleActor> actors = role.getActors();
+                    if (actors != null) {
+                        for (RoleActor actor : actors) {
+                            if ("atlassian-group-role-actor".equals(actor.getType())) {
+                                groupNames.add(actor.getName());
+                                log.info("Found group '{}' with role '{}'", actor.getName(), role.getName());
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    log.warn("Could not fetch role details for {}: {}", basicRole.getName(), e.getMessage());
+                }
+            }
+
+            // Log the groups we found
+            if (!groupNames.isEmpty()) {
+                log.info("Found {} groups with access to this project", groupNames.size());
+
+                // For each group, try to get membership details
+                for (String groupName : groupNames) {
+                    try {
+                        log.info("------------------------------------");
+                        log.info("Group Name: {}", groupName);
+                        log.info("Group Self: {}/rest/api/2/group?groupname={}", jiraApiUrl, groupName);
+
+                        // Note: Direct group membership API might require admin permissions
+                        // and might not be available through the standard REST client
+                        log.info("Group Members: To see complete membership, admin privileges may be required");
+
+                        // Try to get users with this group through search
+                        String jql = String.format("project = %s AND memberOf(\"%s\")", projectKey, groupName);
+                        SearchResult searchResult = restClient.getSearchClient()
+                                                              .searchJql(jql)
+                                                              .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                        Set<BasicUser> groupUsers = new HashSet<>();
+                        for (Issue issue : searchResult.getIssues()) {
+                            if (issue.getReporter() != null) {
+                                groupUsers.add(issue.getReporter());
+                            }
+                            if (issue.getAssignee() != null) {
+                                groupUsers.add(issue.getAssignee());
+                            }
+                        }
+
+                        if (!groupUsers.isEmpty()) {
+                            log.info("Users found in group (may be incomplete):");
+                            for (BasicUser user : groupUsers) {
+                                log.info("  - {} ({})", user.getDisplayName(), user.getName());
+                            }
+                        } else {
+                            log.info("No users found in group through JQL search");
+                        }
+
+                    } catch (Exception e) {
+                        log.warn("Error fetching details for group {}: {}", groupName, e.getMessage());
+                    }
+                }
+            } else {
+                log.info("No groups found with access to this project");
+            }
+
+        } catch (Exception e) {
+            log.error("Error fetching group information: {}", e.getMessage(), e);
+        }
+    }
 }
diff --git a/src/main/java/com/pump/jira/service/VersionService.java b/src/main/java/com/pump/jira/service/VersionService.java
index 2a12230ca74fc3180d9204e825361f3e8f01761d..d7bcb472f2534ea6519150bf44446067e192dedc 100644
--- a/src/main/java/com/pump/jira/service/VersionService.java
+++ b/src/main/java/com/pump/jira/service/VersionService.java
@@ -71,4 +71,111 @@ public class VersionService {
 
         }
     }
+
+    /// id -> Phase.externalId
+    /// name -> Phase.name
+    /// description + archived + released+ sequence -> Phase.description
+    /// startDate -> Phase.startDate
+    /// releaseDate -> Phase.endDate
+    /// project -> Phase.project
+    /// min Issue.created -> Phase.created
+    public void fetchVersion(JiraRestClient restClient)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        log.info("Fetching detailed version information for project {}", projectKey);
+
+        try {
+            Project project = restClient.getProjectClient()
+                                        .getProject(projectKey)
+                                        .get(timeoutSeconds, TimeUnit.SECONDS);
+
+            // Convert Iterable to List for easier handling
+            List<Version> versions = new ArrayList<>();
+            project.getVersions().forEach(versions::add);
+
+            if (versions.isEmpty()) {
+                log.info("No versions found for project {}", projectKey);
+                return;
+            }
+
+            log.info("Found {} versions for project {}", versions.size(), projectKey);
+
+            for (Version version : versions) {
+                log.info("------------------------------------");
+                log.info("Version ID: {}", version.getId());
+                log.info("Version Name: {}", version.getName());
+
+                // Description and status flags
+                StringBuilder descriptionWithMeta = new StringBuilder();
+                if (version.getDescription() != null) {
+                    descriptionWithMeta.append(version.getDescription());
+                }
+
+                // Add metadata to description
+                descriptionWithMeta.append(" [Archived: ")
+                                   .append(version.isArchived())
+                                   .append(", Released: ")
+                                   .append(version.isReleased());
+
+                // Try to get sequence number using reflection if available
+                try {
+                    Object sequenceObj = version.getClass().getMethod("getSequence").invoke(version);
+                    if (sequenceObj != null) {
+                        descriptionWithMeta.append(", Sequence: ").append(sequenceObj);
+                    }
+                } catch (Exception e) {
+                    // Sequence not available
+                }
+
+                descriptionWithMeta.append("]");
+                log.info("Full Description: {}", descriptionWithMeta);
+
+                // TODO Start date - some versions may not have a start date
+//                if (version.getStartDate() != null) {
+//                    log.info("Start Date: {}", version.getStartDate());
+//                } else {
+//                    log.info("Start Date: Not set");
+//                }
+
+                // Release date
+                if (version.getReleaseDate() != null) {
+                    log.info("Release Date: {}", version.getReleaseDate());
+                } else {
+                    log.info("Release Date: Not set");
+                }
+
+                // Project information
+                log.info("Project Key: {}", project.getKey());
+                log.info("Project Name: {}", project.getName());
+                log.info("Project ID: {}", project.getId());
+
+                // Find earliest issue creation date for this version
+                String jql = "project = " + projectKey + " AND fixVersion = '" + version.getName() + "' ORDER BY created ASC";
+
+                try {
+                    // Search for issues with this version as a fix version, sorted by creation date
+                    com.atlassian.jira.rest.client.api.domain.SearchResult searchResult =
+                        restClient.getSearchClient()
+                                  .searchJql(jql, 1, 0, null)
+                                  .get(timeoutSeconds, TimeUnit.SECONDS);
+
+                    // If we have any issues
+                    if (searchResult.getTotal() > 0 && searchResult.getIssues().iterator().hasNext()) {
+                        com.atlassian.jira.rest.client.api.domain.Issue earliestIssue =
+                            searchResult.getIssues().iterator().next();
+
+                        log.info("Earliest Issue Creation Date: {}", earliestIssue.getCreationDate());
+                        log.info("Earliest Issue Key: {}", earliestIssue.getKey());
+                        log.info("Total Issues: {}", searchResult.getTotal());
+                    } else {
+                        log.info("No issues found for this version");
+                    }
+                } catch (Exception e) {
+                    log.warn("Error finding issues for version {}: {}", version.getName(), e.getMessage());
+                }
+            }
+        } catch (Exception e) {
+            log.error("Error fetching version information: {}", e.getMessage(), e);
+        }
+    }
+
 }
\ No newline at end of file