gt: 		File f = new File(dir + File.separator + fName);
context: /*
   * Universal Media Server, for streaming any media to DLNA
   * compatible renderers based on the http://www.ps3mediaserver.org.
   * Copyright (C) 2012 UMS developers.
   *
   * This program is a free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; version 2
   * of the License only.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   */
  
  package net.pms.configuration;
  
  import com.sun.jna.Platform;
  import java.io.BufferedOutputStream;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.net.URL;
  import java.net.URLConnection;
  import java.util.ArrayList;
  import java.util.Map;
  import java.util.Scanner;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipInputStream;
  import javax.swing.JLabel;
  import net.pms.Messages;
  import net.pms.PMS;
  import net.pms.external.ExternalFactory;
  import org.apache.commons.configuration.ConfigurationException;
  import org.apache.commons.io.FileUtils;
  import org.apache.commons.lang3.StringUtils;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class DownloadPlugins {
  	private final static String PLUGIN_LIST_URL = "https://www.universalmediaserver.com/plugins/list.php";
  	private final static String PLUGIN_TEST_FILE = "plugin_inst.tst";
  
  	private static final Logger LOGGER = LoggerFactory.getLogger(DownloadPlugins.class);
  	private static final PmsConfiguration configuration = PMS.getConfiguration();
  
  	private String id;
  	private String name;
  	private String rating;
  	private String desc;
  	private String url;
  	private String author;
  	private String version;
  	private ArrayList<URL> jars;
  	private JLabel updateLabel;
  	private String[] props;
  	private boolean test;
  	private boolean old;
  
  	public static ArrayList<DownloadPlugins> downloadList() {
  		ArrayList<DownloadPlugins> res = new ArrayList<>();
  
  		if (!configuration.getExternalNetwork()) {
  			// Do not try to get the plugin list if there is no
  			// external network.
  			return res;
  		}
  
  		try {
  			URL u = new URL(PLUGIN_LIST_URL);
  			URLConnection connection = u.openConnection();
  			connection.setConnectTimeout(5000);
  			connection.setReadTimeout(5000);
  			BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  			parse_list(res, in, false);
  			File test = new File(configuration.getPluginDirectory() + File.separator + PLUGIN_TEST_FILE);
  			if (test.exists()) {
  				in = new BufferedReader(new InputStreamReader(new FileInputStream(test)));
  				parse_list(res, in, true);
  			}
  		} catch (IOException e) {
  		}
  		return res;
  	}
  
  	private static int getInt(String val) {
  		try {
  			return Integer.parseInt(val);
  		} catch (Exception e) {
  			return 0;
  		}
  	}
  
  	private static void parse_list(ArrayList<DownloadPlugins> res, BufferedReader in, boolean test) throws IOException {
  		String str;
  		DownloadPlugins plugin = new DownloadPlugins(test);
  		while ((str = in.readLine()) != null) {
  			str = str.trim();
  			if (StringUtils.isEmpty(str)) {
  				if (plugin.isOk() || plugin.isTest()) {
  					if (test) {
  						plugin.setRating("TEST");
  					}
  					res.add(plugin);
  				} else {
  					LOGGER.trace("An invalid plugin was ignored (1)");
  				}
  				plugin = new DownloadPlugins(test);
  				continue;
  			}
  			String[] keyval = str.split("=", 2);
  			if (keyval.length < 2) {
  				continue;
  			}
  			if (keyval[0].equalsIgnoreCase("id")) {
  				plugin.id = keyval[1];
  			}
  			if (keyval[0].equalsIgnoreCase("name")) {
  				plugin.name = keyval[1];
  			}
  			if (keyval[0].equalsIgnoreCase("rating")) {
  				// Rating is temporarily switched off
  				// plugin.rating = keyval[1];
  			}
  			if (keyval[0].equalsIgnoreCase("desc")) {
  				plugin.desc = keyval[1];
  			}
  			if (keyval[0].equalsIgnoreCase("url")) {
  				plugin.url = keyval[1];
  			}
  			if (keyval[0].equalsIgnoreCase("author")) {
  				plugin.author = keyval[1];
  			}
  			if (keyval[0].equalsIgnoreCase("version")) {
  				plugin.version = keyval[1];
  			}
  			if (keyval[0].equalsIgnoreCase("type")) {
  				// Deprecated
  			}
  			if (keyval[0].equalsIgnoreCase("require")) {
  				plugin.old = false;
  				String[] minVer = keyval[1].split("\\.");
  				String[] myVer = PMS.getVersion().split("\\.");
  				int max = Math.max(myVer.length, minVer.length);
  				for (int i = 0; i < max; i++) {
  					int my,min;
  					// If the versions are of different length
  					// say that the part of "wrong" length is 0
  					my = getInt(((i > myVer.length) ? "0" : myVer[i]));
  					min = getInt(((i > minVer.length) ? "0" : minVer[i]));
  					if (min == my) {
  						// This is equal take the next part of the
  						// version string
  						continue;
  					}
  					if (min > my) {
  						// Old otherwise it is new
  						plugin.old = true;
  					}
  					// anyway stop here
  					break;
  				}
  			}
  			if (keyval[0].equalsIgnoreCase("prop")) {
  				plugin.props = keyval[1].split(",");
  			}
  		}
  		if (plugin.isOk() || plugin.isTest()) { // Add the last one
  			if (test) {
  				plugin.setRating("TEST");
  			}
  			res.add(plugin);
  		} else {
  			LOGGER.trace("An invalid plugin was ignored (2)");
  		}
  		in.close();
  	}
  
  	public DownloadPlugins() {
  		this(false);
  	}
  
  	public DownloadPlugins(boolean test) {
  		rating = "--";
  		jars = null;
  		old = false;
  		this.test = test;
  	}
  
  	public String getName() {
  		return name;
  	}
  
  	public String getRating() {
  		return rating;
  	}
  
  	public String getAuthor() {
  		return author;
  	}
  
  	public String getDescription() {
  		return desc;
  	}
  
  	public String getVersion() {
  		return version;
  	}
  
  	public void setRating(String str) {
  		rating = str;
  	}
  
  	public boolean isOk() {
  		// We must have a name and ID
  		return (!StringUtils.isEmpty(name)) && (!StringUtils.isEmpty(id));
  	}
  
  	public boolean isTest() {
  		return test;
  	}
  
  	public boolean isOld() {
  		return old;
  	}
  
  	private String splitString(String string) {
  		StringBuilder buf = new StringBuilder();
  		String tempString = string;
  
  		if (string != null) {
  			while (tempString.length() > 60) {
  				String block = tempString.substring(0, 60);
  				int index = block.lastIndexOf(' ');
  				if (index < 0) {
  					index = tempString.indexOf(' ');
  				}
  				if (index >= 0) {
  					buf.append(tempString.substring(0, index)).append("<BR>");
  				}
  				tempString = tempString.substring(index + 1);
  			}
  		} else {
  			tempString = " ";
  		}
  		buf.append(tempString);
  		return buf.toString();
  	}
  
  	private String header(String hdr) {
  		return "<br><b>" + hdr + ":  </b>";
  	}
  
  	public String htmlString() {
  		String res = "<html>";
  		res += "<b>Name:  </b>" + getName();
  		if (!StringUtils.isEmpty(getRating())) {
  			res += header("Rating") + getRating();
  		}
  		if (!StringUtils.isEmpty(getAuthor())) {
  			res += header("Author") + getAuthor();
  		}
  		if (!StringUtils.isEmpty(getDescription())) {
  			res += header("Description") + splitString(getDescription());
  		}
  		return res;
  	}
  
  	private String extractFileName(String str, String name) {
  		if (!StringUtils.isEmpty(name)) {
  			return name;
  		}
  		int pos = str.lastIndexOf('/');
  		if (pos == -1) {
  			return name;
  		}
  		return str.substring(pos + 1);
  	}
  
  	private void ensureCreated(String p) {
  		File f = new File(p);
  		f.mkdirs();
  	}
  
  	private void unzip(File f, String dir) {
  		// Zip file with loads of goodies
  		// Unzip it
  		ZipInputStream zis;
  		try {
  			zis = new ZipInputStream(new FileInputStream(f));
  			ZipEntry entry;
  			while ((entry = zis.getNextEntry()) != null) {
  				File dst = new File(dir + File.separator + entry.getName());
  				if (entry.isDirectory()) {
  					dst.mkdirs();
  					continue;
  				}
  				int count;
  				byte data[] = new byte[4096];
  				FileOutputStream fos = new FileOutputStream(dst);
  				try (BufferedOutputStream dest = new BufferedOutputStream(fos, 4096)) {
  					while ((count = zis.read(data, 0, 4096)) != -1) {
  						dest.write(data, 0, count);
  					}
  					dest.flush();
  				}
  				if (dst.getAbsolutePath().endsWith(".jar")) {
  					jars.add(dst.toURI().toURL());
  				}
  			}
  			zis.close();
  		} catch (Exception e) {
  			LOGGER.info("unzip error " + e);
  		}
  		f.delete();
  	}
  
  	private boolean downloadFile(String url, String dir, String name) throws Exception {
  		URL u = new URL(url);
  		ensureCreated(dir);
  		String fName = extractFileName(url, name);
  
  		LOGGER.debug("fetch file " + url);
  		if (updateLabel != null) {
  			updateLabel.setText(Messages.getString("NetworkTab.47") + ": " + fName);
  		}
  
  