// Path: src/main/java/org/jmeterplugins/repository/exception/DownloadException.java
// public class DownloadException extends RuntimeException {
//     public DownloadException() {
//     }
// 
//     public DownloadException(String message) {
//         super(message);
//     }
// 
//     public DownloadException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: src/main/java/org/jmeterplugins/repository/http/StatsReporter.java
// public class StatsReporter extends Thread {
//     private static final Logger log = LoggerFactory.getLogger(StatsReporter.class);
// 
//     private final JARSource jarSource;
//     private final String[] usageStats;
// 
//     public StatsReporter(JARSource jarSource, String[] usageStats) throws CloneNotSupportedException {
//         this.jarSource = (JARSource) jarSource.clone();
//         this.usageStats = usageStats;
//         setDaemon(true);
//     }
// 
//     @Override
//     public void run() {
//         try {
//             jarSource.reportStats(usageStats);
//             log.debug("Finished send repo stats");
//         } catch (IOException e) {
//             log.warn("Failed to send repo stats", e);
//         }
//     }
// 
//     protected JARSource getJarSource() {
//         return jarSource;
//     }
// }


import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import org.apache.jmeter.assertions.Assertion;
import org.apache.jmeter.config.ConfigElement;
import org.apache.jmeter.control.Controller;
import org.apache.jmeter.engine.JMeterEngine;
import org.apache.jmeter.gui.JMeterGUIComponent;
import org.apache.jmeter.processor.PostProcessor;
import org.apache.jmeter.processor.PreProcessor;
import org.apache.jmeter.samplers.SampleListener;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.timers.Timer;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.reflect.ClassFinder;
import org.jmeterplugins.repository.exception.DownloadException;
import org.jmeterplugins.repository.http.StatsReporter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.file.AccessDeniedException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
            throw new RuntimeException("Result is not array");
        }

        for (Object elm : (JSONArray) json) {
            if (elm instanceof JSONObject) {
                Plugin plugin = Plugin.fromJSON((JSONObject) elm);
                if (plugin.getName().isEmpty()) {
                    log.debug("Skip empty name: " + plugin);
                    continue;
                }

                if (!plugin.isVirtual()) {
                    plugin.detectInstalled(getInstalledPlugins());
                }
                allPlugins.put(plugin, plugin.isInstalled());
            } else {
                log.warn("Invalid array element: " + elm);
            }
        }

        // after all usual plugins detected, detect virtual sets
        for (Plugin plugin : allPlugins.keySet()) {
            if (plugin.isVirtual()) {
                plugin.detectInstalled(getInstalledPlugins());
                allPlugins.put(plugin, plugin.isInstalled());
            }
        }

        if (isSendRepoStats && JMeterUtils.getPropDefault("jpgc.repo.sendstats", "true").equals("true")) {
            try {
// Path: src/main/java/org/jmeterplugins/repository/exception/DownloadException.java
// public class DownloadException extends RuntimeException {
//     public DownloadException() {
//     }
// 
//     public DownloadException(String message) {
//         super(message);
//     }
// 
//     public DownloadException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: src/main/java/org/jmeterplugins/repository/http/StatsReporter.java
// public class StatsReporter extends Thread {
//     private static final Logger log = LoggerFactory.getLogger(StatsReporter.class);
// 
//     private final JARSource jarSource;
//     private final String[] usageStats;
// 
//     public StatsReporter(JARSource jarSource, String[] usageStats) throws CloneNotSupportedException {
//         this.jarSource = (JARSource) jarSource.clone();
//         this.usageStats = usageStats;
//         setDaemon(true);
//     }
// 
//     @Override
//     public void run() {
//         try {
//             jarSource.reportStats(usageStats);
//             log.debug("Finished send repo stats");
//         } catch (IOException e) {
//             log.warn("Failed to send repo stats", e);
//         }
//     }
// 
//     protected JARSource getJarSource() {
//         return jarSource;
//     }
// }


// Path: src/main/java/org/jmeterplugins/repository/PluginManager.java
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import org.apache.jmeter.assertions.Assertion;
import org.apache.jmeter.config.ConfigElement;
import org.apache.jmeter.control.Controller;
import org.apache.jmeter.engine.JMeterEngine;
import org.apache.jmeter.gui.JMeterGUIComponent;
import org.apache.jmeter.processor.PostProcessor;
import org.apache.jmeter.processor.PreProcessor;
import org.apache.jmeter.samplers.SampleListener;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.timers.Timer;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.reflect.ClassFinder;
import org.jmeterplugins.repository.exception.DownloadException;
import org.jmeterplugins.repository.http.StatsReporter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.file.AccessDeniedException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

            throw new RuntimeException("Result is not array");
        }

        for (Object elm : (JSONArray) json) {
            if (elm instanceof JSONObject) {
                Plugin plugin = Plugin.fromJSON((JSONObject) elm);
                if (plugin.getName().isEmpty()) {
                    log.debug("Skip empty name: " + plugin);
                    continue;
                }

                if (!plugin.isVirtual()) {
                    plugin.detectInstalled(getInstalledPlugins());
                }
                allPlugins.put(plugin, plugin.isInstalled());
            } else {
                log.warn("Invalid array element: " + elm);
            }
        }

        // after all usual plugins detected, detect virtual sets
        for (Plugin plugin : allPlugins.keySet()) {
            if (plugin.isVirtual()) {
                plugin.detectInstalled(getInstalledPlugins());
                allPlugins.put(plugin, plugin.isInstalled());
            }
        }

        if (isSendRepoStats && JMeterUtils.getPropDefault("jpgc.repo.sendstats", "true").equals("true")) {
            try {
                StatsReporter reporter = new StatsReporter(jarSource, getUsageStats());