// Path: core/ts.core/src/ts/internal/io/tar/TarEntry.java
// public class TarEntry implements Cloneable
// {
// 	private String name;
// 	private long mode, time, size;
// 	private int type;
// 	int filepos;
// 	private String linkName;
// 	
// 	/**
// 	 * Entry type for normal files.
// 	 */
// 	public static final int FILE = '0';
// 
// 	/**
// 	 * Entry type for directories.
// 	 */
// 	public static final int DIRECTORY = '5';
// 
// 	/**
// 	 * Entry type for links.
// 	 */
// 	public static final int LINK = '1';
// 
// 	/**
// 	 * Entry type for symbolic link.
// 	 */
// 	public static final int SYM_LINK = '2';
// 
// 	/**
// 	 * Create a new TarEntry for a file of the given name at the
// 	 * given position in the file.
// 	 *
// 	 * @param name filename
// 	 * @param pos position in the file in bytes
// 	 */
// 	TarEntry(String name, int pos) {
// 		this.name = name;
// 		mode = 0644;
// 		type = FILE;
// 		filepos = pos;
// 		time = System.currentTimeMillis() / 1000;
// 	}
// 
// 	/**
// 	 * Create a new TarEntry for a file of the given name.
// 	 *
// 	 * @param name filename
// 	 */
// 	public TarEntry(String name) {
// 		this(name, -1);
// 	}
// 
// 	/**
// 	 * Returns the type of this file, one of FILE, LINK, SYM_LINK,
// 	 * CHAR_DEVICE, BLOCK_DEVICE, DIRECTORY or FIFO.
// 	 *
// 	 * @return file type
// 	 */
// 	public int getFileType() {
// 		return type;
// 	}
// 
// 	/**
// 	 * Returns the mode of the file in UNIX permissions format.
// 	 *
// 	 * @return file mode
// 	 */
// 	public long getMode() {
// 		return mode;
// 	}
// 
// 	/**
// 	 * Returns the name of the file.
// 	 *
// 	 * @return filename
// 	 */
// 	public String getName() {
// 		return name;
// 	}
// 
// 	/**
// 	 * Returns the size of the file in bytes.
// 	 *
// 	 * @return filesize
// 	 */
// 	public long getSize() {
// 		return size;
// 	}
// 
// 	/**
// 	 * Returns the modification time of the file in seconds since January
// 	 * 1st 1970.
// 	 *
// 	 * @return time
// 	 */
// 	public long getTime() {
// 		return time;
// 	}
// 
// 	/**
// 	 * Sets the type of the file, one of FILE, LINK, SYMLINK, CHAR_DEVICE,
// 	 * BLOCK_DEVICE, or DIRECTORY.
// 	 *
// 	 * @param type
// 	 */
// 	public void setFileType(int type) {
// 		this.type = type;
// 	}
// 
// 	/**
// 	 * Sets the mode of the file in UNIX permissions format.
// 	 *
// 	 * @param mode
// 	 */
// 	public void setMode(long mode) {
// 		this.mode = mode;
// 	}
// 
// 	/**
// 	 * Sets the size of the file in bytes.
// 	 *
// 	 * @param size
// 	 */
// 	public void setSize(long size) {
// 		this.size = size;
// 	}
// 
// 	/**
// 	 * Sets the modification time of the file in seconds since January
// 	 * 1st 1970.
// 	 *
// 	 * @param time
// 	 */
// 	public void setTime(long time) {
// 		this.time = time;
// 	}
// 
// 	public boolean isDirectory() {
// 		return type == DIRECTORY;
// 	}
// 	
// 	public boolean isLink() {
// 		return type == LINK;
// 	}
// 	
// 	public boolean isSymbolicLink() {
// 		return type == SYM_LINK;
// 	}
// 		
// 	public String getLinkName() {
// 		return linkName;
// 	}
// 	
// 	public void setLinkName(String linkName) {
// 		this.linkName = linkName;
// 	}
// }


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.tukaani.xz.XZInputStream;
import ts.internal.io.tar.TarEntry;
import ts.internal.io.tar.TarException;
import ts.internal.io.tar.TarInputStream;

	/**
	 * Extract tar.xz file to destination folder.
	 *
	 * @param file
	 *            zip file to extract
	 * @param destination
	 *            destination folder
	 */
	public static void extractTarXZ(File file, File destination) throws IOException {
		extractTar(file, destination, false);
	}
	
	/**
	 * Extract tar.gz/tar.xz file to destination folder.
	 *
	 * @param file
	 *            zip file to extract
	 * @param destination
	 *            destination folder
	 */
	private static void extractTar(File file, File destination, boolean tarGz) throws IOException {
		TarInputStream in = null;
		OutputStream out = null;
		try {
			// Open the ZIP file
			in = new TarInputStream(tarGz ? new GZIPInputStream(new FileInputStream(file))
					: new XZInputStream(new FileInputStream(file)));

			// Get the first entry
// Path: core/ts.core/src/ts/internal/io/tar/TarEntry.java
// public class TarEntry implements Cloneable
// {
// 	private String name;
// 	private long mode, time, size;
// 	private int type;
// 	int filepos;
// 	private String linkName;
// 	
// 	/**
// 	 * Entry type for normal files.
// 	 */
// 	public static final int FILE = '0';
// 
// 	/**
// 	 * Entry type for directories.
// 	 */
// 	public static final int DIRECTORY = '5';
// 
// 	/**
// 	 * Entry type for links.
// 	 */
// 	public static final int LINK = '1';
// 
// 	/**
// 	 * Entry type for symbolic link.
// 	 */
// 	public static final int SYM_LINK = '2';
// 
// 	/**
// 	 * Create a new TarEntry for a file of the given name at the
// 	 * given position in the file.
// 	 *
// 	 * @param name filename
// 	 * @param pos position in the file in bytes
// 	 */
// 	TarEntry(String name, int pos) {
// 		this.name = name;
// 		mode = 0644;
// 		type = FILE;
// 		filepos = pos;
// 		time = System.currentTimeMillis() / 1000;
// 	}
// 
// 	/**
// 	 * Create a new TarEntry for a file of the given name.
// 	 *
// 	 * @param name filename
// 	 */
// 	public TarEntry(String name) {
// 		this(name, -1);
// 	}
// 
// 	/**
// 	 * Returns the type of this file, one of FILE, LINK, SYM_LINK,
// 	 * CHAR_DEVICE, BLOCK_DEVICE, DIRECTORY or FIFO.
// 	 *
// 	 * @return file type
// 	 */
// 	public int getFileType() {
// 		return type;
// 	}
// 
// 	/**
// 	 * Returns the mode of the file in UNIX permissions format.
// 	 *
// 	 * @return file mode
// 	 */
// 	public long getMode() {
// 		return mode;
// 	}
// 
// 	/**
// 	 * Returns the name of the file.
// 	 *
// 	 * @return filename
// 	 */
// 	public String getName() {
// 		return name;
// 	}
// 
// 	/**
// 	 * Returns the size of the file in bytes.
// 	 *
// 	 * @return filesize
// 	 */
// 	public long getSize() {
// 		return size;
// 	}
// 
// 	/**
// 	 * Returns the modification time of the file in seconds since January
// 	 * 1st 1970.
// 	 *
// 	 * @return time
// 	 */
// 	public long getTime() {
// 		return time;
// 	}
// 
// 	/**
// 	 * Sets the type of the file, one of FILE, LINK, SYMLINK, CHAR_DEVICE,
// 	 * BLOCK_DEVICE, or DIRECTORY.
// 	 *
// 	 * @param type
// 	 */
// 	public void setFileType(int type) {
// 		this.type = type;
// 	}
// 
// 	/**
// 	 * Sets the mode of the file in UNIX permissions format.
// 	 *
// 	 * @param mode
// 	 */
// 	public void setMode(long mode) {
// 		this.mode = mode;
// 	}
// 
// 	/**
// 	 * Sets the size of the file in bytes.
// 	 *
// 	 * @param size
// 	 */
// 	public void setSize(long size) {
// 		this.size = size;
// 	}
// 
// 	/**
// 	 * Sets the modification time of the file in seconds since January
// 	 * 1st 1970.
// 	 *
// 	 * @param time
// 	 */
// 	public void setTime(long time) {
// 		this.time = time;
// 	}
// 
// 	public boolean isDirectory() {
// 		return type == DIRECTORY;
// 	}
// 	
// 	public boolean isLink() {
// 		return type == LINK;
// 	}
// 	
// 	public boolean isSymbolicLink() {
// 		return type == SYM_LINK;
// 	}
// 		
// 	public String getLinkName() {
// 		return linkName;
// 	}
// 	
// 	public void setLinkName(String linkName) {
// 		this.linkName = linkName;
// 	}
// }


// Path: core/ts.core/src/ts/utils/ZipUtils.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.tukaani.xz.XZInputStream;
import ts.internal.io.tar.TarEntry;
import ts.internal.io.tar.TarException;
import ts.internal.io.tar.TarInputStream;


	/**
	 * Extract tar.xz file to destination folder.
	 *
	 * @param file
	 *            zip file to extract
	 * @param destination
	 *            destination folder
	 */
	public static void extractTarXZ(File file, File destination) throws IOException {
		extractTar(file, destination, false);
	}
	
	/**
	 * Extract tar.gz/tar.xz file to destination folder.
	 *
	 * @param file
	 *            zip file to extract
	 * @param destination
	 *            destination folder
	 */
	private static void extractTar(File file, File destination, boolean tarGz) throws IOException {
		TarInputStream in = null;
		OutputStream out = null;
		try {
			// Open the ZIP file
			in = new TarInputStream(tarGz ? new GZIPInputStream(new FileInputStream(file))
					: new XZInputStream(new FileInputStream(file)));

			// Get the first entry
			TarEntry entry = null;