diff --git a/README.md b/README.md
index 4601d3b..f9571ca 100644
--- a/README.md
+++ b/README.md
@@ -40,9 +40,9 @@ JRE/JDK 8u60 or higher.
 ### Table of supported GoldLeaf versions
 | GoldLeaf version | NS-USBloader version |
 | ---------------- | -------------------- |
-| v0.5             | v0.4 - v0.5.2        |
+| v0.5             | v0.4 - v0.5.2, v0.8  |
 | v0.6.1           | v0.6                 |
-| v0.7             | v0.7                 |
+| v0.7             | v0.7 - v0.8          |
 
 ### Usage
 ##### Linux:
diff --git a/src/main/java/nsusbloader/AppPreferences.java b/src/main/java/nsusbloader/AppPreferences.java
index 0e28a13..fc001f4 100644
--- a/src/main/java/nsusbloader/AppPreferences.java
+++ b/src/main/java/nsusbloader/AppPreferences.java
@@ -26,7 +26,8 @@ public class AppPreferences {
             String HostExtra,
             boolean autoCheck4Updates,
             boolean tinfoilXciSupport,
-            boolean nspFileFilterForGl
+            boolean nspFileFilterForGl,
+            String useOldGlVersion
             ){
         setProtocol(Protocol);
         setRecent(PreviouslyOpened);
@@ -43,6 +44,7 @@ public class AppPreferences {
         setAutoCheckUpdates(autoCheck4Updates);
         setTfXCI(tinfoilXciSupport);
         setNspFileFilterGL(nspFileFilterForGl);
+        setUseOldGlVersion(useOldGlVersion);
     }
     public String getTheme(){
         String theme = preferences.get("THEME", "/res/app_dark.css");           // Don't let user to change settings manually
@@ -114,4 +116,7 @@ public class AppPreferences {
 
     public boolean getNspFileFilterGL(){return preferences.getBoolean("GL_NSP_FILTER", false); }
     public void setNspFileFilterGL(boolean prop){preferences.putBoolean("GL_NSP_FILTER", prop);}
+
+    public String getUseOldGlVersion(){ return preferences.get("OldGlVersion", ""); }
+    public void setUseOldGlVersion(String version){ preferences.put("OldGlVersion", version);}
 }
diff --git a/src/main/java/nsusbloader/Controllers/NSLMainController.java b/src/main/java/nsusbloader/Controllers/NSLMainController.java
index e1506a3..144719a 100644
--- a/src/main/java/nsusbloader/Controllers/NSLMainController.java
+++ b/src/main/java/nsusbloader/Controllers/NSLMainController.java
@@ -164,7 +164,7 @@ public class NSLMainController implements Initializable {
             if (FrontTabController.getSelectedProtocol().equals("GoldLeaf") ||
                     ( FrontTabController.getSelectedProtocol().equals("TinFoil") && FrontTabController.getSelectedNetUsb().equals("USB") )
             ){
-                usbNetCommunications = new UsbCommunications(nspToUpload, FrontTabController.getSelectedProtocol(), SettingsTabController.getNSPFileFilterForGL());
+                usbNetCommunications = new UsbCommunications(nspToUpload, FrontTabController.getSelectedProtocol()+SettingsTabController.getGlOldVer(), SettingsTabController.getNSPFileFilterForGL());
                 workThread = new Thread(usbNetCommunications);
                 workThread.setDaemon(true);
                 workThread.start();
@@ -323,7 +323,8 @@ public class NSLMainController implements Initializable {
                 SettingsTabController.getHostExtra(),
                 SettingsTabController.getAutoCheckForUpdates(),
                 SettingsTabController.getTfXCISupport(),
-                SettingsTabController.getNSPFileFilterForGL()
+                SettingsTabController.getNSPFileFilterForGL(),
+                SettingsTabController.getGlOldVer()
         );
     }
 }
diff --git a/src/main/java/nsusbloader/Controllers/SettingsController.java b/src/main/java/nsusbloader/Controllers/SettingsController.java
index 087136c..c8950e9 100644
--- a/src/main/java/nsusbloader/Controllers/SettingsController.java
+++ b/src/main/java/nsusbloader/Controllers/SettingsController.java
@@ -61,8 +61,16 @@ public class SettingsController implements Initializable {
     @FXML
     private ChoiceBox<String> langCB;
 
+    @FXML
+    private CheckBox glOldVerCheck;
+
+    @FXML
+    private ChoiceBox<String> glOldVerChoice;
+
     private HostServices hs;
 
+    private static final String[] oldGlSupportedVersions = {"v0.5"};
+
     @Override
     public void initialize(URL url, ResourceBundle resourceBundle) {
         nspFilesFilterForGLCB.setSelected(AppPreferences.getInstance().getNspFileFilterGL());
@@ -240,7 +248,20 @@ public class SettingsController implements Initializable {
                     ResourceBundle.getBundle("locale", new Locale(langCB.getSelectionModel().getSelectedItem()))
                             .getString("windowBodyRestartToApplyLang"));
         });
-
+        // Set supported old versions
+        glOldVerChoice.getItems().addAll(oldGlSupportedVersions);
+        String oldVer = AppPreferences.getInstance().getUseOldGlVersion();  // Overhead; Too much validation of consistency
+        if (Arrays.asList(oldGlSupportedVersions).contains(oldVer)) {
+            glOldVerChoice.getSelectionModel().select(oldVer);
+            glOldVerChoice.setDisable(false);
+            glOldVerCheck.setSelected(true);
+        }
+        else {
+            glOldVerChoice.getSelectionModel().select(0);
+            glOldVerChoice.setDisable(true);
+            glOldVerCheck.setSelected(false);
+        }
+        glOldVerCheck.setOnAction(e-> glOldVerChoice.setDisable(! glOldVerCheck.isSelected()) );
     }
     public boolean getNSPFileFilterForGL(){return nspFilesFilterForGLCB.isSelected(); }
     public boolean getExpertModeSelected(){ return expertModeCb.isSelected(); }
@@ -262,4 +283,11 @@ public class SettingsController implements Initializable {
         newVersionLink.setVisible(true);
         newVersionLink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer);
     }
+
+    public String getGlOldVer() {
+        if (glOldVerCheck.isSelected())
+            return glOldVerChoice.getValue();
+        else
+            return "";
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/nsusbloader/USB/GoldLeaf.java b/src/main/java/nsusbloader/USB/GoldLeaf.java
index 21cdff1..d395c41 100644
--- a/src/main/java/nsusbloader/USB/GoldLeaf.java
+++ b/src/main/java/nsusbloader/USB/GoldLeaf.java
@@ -576,7 +576,7 @@ class GoldLeaf implements ITransferModule {
             }
         }
         else if (filePath.startsWith("SPEC:/")){
-            System.out.println(filePath);
+            //System.out.println(filePath);
             filePath = filePath.replaceFirst("SPEC:/","");
             if (selectedFile.getName().equals(filePath)){
                 command.add(GL_OBJ_TYPE_FILE);
diff --git a/src/main/java/nsusbloader/USB/GoldLeaf_05.java b/src/main/java/nsusbloader/USB/GoldLeaf_05.java
new file mode 100644
index 0000000..3592051
--- /dev/null
+++ b/src/main/java/nsusbloader/USB/GoldLeaf_05.java
@@ -0,0 +1,352 @@
+package nsusbloader.USB;
+
+import javafx.concurrent.Task;
+import nsusbloader.ModelControllers.LogPrinter;
+import nsusbloader.NSLDataTypes.EFileStatus;
+import nsusbloader.NSLDataTypes.EMsgType;
+import nsusbloader.USB.PFS.PFSProvider;
+import org.usb4java.DeviceHandle;
+import org.usb4java.LibUsb;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+
+/**
+ * GoldLeaf processing
+ * */
+public class GoldLeaf_05 implements ITransferModule{
+    //                            CMD                                G     L     U     C
+    private static final byte[] CMD_GLUC =               new byte[]{0x47, 0x4c, 0x55, 0x43};
+    private static final byte[] CMD_ConnectionRequest =  new byte[]{0x00, 0x00, 0x00, 0x00};    // Write-only command
+    private static final byte[] CMD_NSPName =            new byte[]{0x02, 0x00, 0x00, 0x00};    // Write-only command
+    private static final byte[] CMD_NSPData =            new byte[]{0x04, 0x00, 0x00, 0x00};    // Write-only command
+
+    private static final byte[] CMD_ConnectionResponse = new byte[]{0x01, 0x00, 0x00, 0x00};
+    private static final byte[] CMD_Start =              new byte[]{0x03, 0x00, 0x00, 0x00};
+    private static final byte[] CMD_NSPContent =         new byte[]{0x05, 0x00, 0x00, 0x00};
+    private static final byte[] CMD_NSPTicket =          new byte[]{0x06, 0x00, 0x00, 0x00};
+    private static final byte[] CMD_Finish =             new byte[]{0x07, 0x00, 0x00, 0x00};
+
+    private DeviceHandle handlerNS;
+    private Task<Void> task;
+    private LogPrinter logPrinter;
+    private EFileStatus status = EFileStatus.FAILED;
+    private RandomAccessFile raf;   // NSP File
+
+    GoldLeaf_05(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Task<Void> task, LogPrinter logPrinter){
+        logPrinter.print("============= GoldLeaf v0.5 =============\n" +
+            "        Only one file per time could be sent. In case you selected more the first one would be picked.", EMsgType.INFO);
+        if (nspMap.isEmpty()){
+            logPrinter.print("For using this GoldLeaf version you have to add file to the table and select it for upload", EMsgType.INFO);
+            return;
+        }
+        File nspFile = (File) nspMap.values().toArray()[0];
+        logPrinter.print("File for upload: "+nspFile.getAbsolutePath(), EMsgType.INFO);
+
+        if (!nspFile.getName().toLowerCase().endsWith(".nsp")) {
+            logPrinter.print("GL This file doesn't look like NSP", EMsgType.FAIL);
+            return;
+        }
+        PFSProvider pfsElement;
+        try{
+            pfsElement = new PFSProvider(nspFile, logPrinter);
+        }
+        catch (Exception e){
+            logPrinter.print("GL File provided has incorrect structure and won't be uploaded\n\t"+e.getMessage(), EMsgType.FAIL);
+            status = EFileStatus.INCORRECT_FILE_FAILED;
+            return;
+        }
+        logPrinter.print("GL File structure validated and it will be uploaded", EMsgType.PASS);
+
+        this.handlerNS = handler;
+        this.task = task;
+        this.logPrinter = logPrinter;
+        try{
+            this.raf = new RandomAccessFile(nspFile, "r");
+        }
+        catch (FileNotFoundException fnfe){
+            logPrinter.print("GL File not found\n\t"+fnfe.getMessage(), EMsgType.FAIL);
+            return;
+        }
+
+        // Go parse commands
+        byte[] readByte;
+
+        // Go connect to GoldLeaf
+        if (writeUsb(CMD_GLUC)) {
+            logPrinter.print("GL Initiating GoldLeaf connection [1/2]", EMsgType.FAIL);
+            return;
+        }
+        logPrinter.print("GL Initiating GoldLeaf connection: [1/2]", EMsgType.PASS);
+        if (writeUsb(CMD_ConnectionRequest)){
+            logPrinter.print("GL Initiating GoldLeaf connection: [2/2]", EMsgType.FAIL);
+            return;
+        }
+        logPrinter.print("GL Initiating GoldLeaf connection: [2/2]", EMsgType.PASS);
+
+        while (true) {
+            readByte = readUsb();
+            if (readByte == null)
+                return;
+
+            if (Arrays.equals(readByte, CMD_GLUC)) {
+                if ((readByte = readUsb()) == null)
+                    return;
+
+                if (Arrays.equals(readByte, CMD_ConnectionResponse)) {
+                    if (handleConnectionResponse(pfsElement))
+                        return;
+                    else
+                        continue;
+                }
+                if (Arrays.equals(readByte, CMD_Start)) {
+                    if (handleStart(pfsElement))
+                        return;
+                    else
+                        continue;
+                }
+                if (Arrays.equals(readByte, CMD_NSPContent)) {
+                    if (handleNSPContent(pfsElement, true))
+                        return;
+                    else
+                        continue;
+                }
+                if (Arrays.equals(readByte, CMD_NSPTicket)) {
+                    if (handleNSPContent(pfsElement, false))
+                        return;
+                    else
+                        continue;
+                }
+                if (Arrays.equals(readByte, CMD_Finish)) {
+                    logPrinter.print("GL Closing GoldLeaf connection: Transfer successful.", EMsgType.PASS);
+                    status = EFileStatus.UPLOADED;
+                    break;
+                }
+            }
+        }
+        try {
+            raf.close();
+        }
+        catch (IOException ioe){
+            logPrinter.print("GL Failed to close file.", EMsgType.INFO);
+        }
+    }
+    /**
+     * ConnectionResponse command handler
+     * @return true if failed
+     *         false if no issues
+     * */
+    private boolean handleConnectionResponse(PFSProvider pfsElement){
+        logPrinter.print("GL 'ConnectionResponse' command:", EMsgType.INFO);
+        if (writeUsb(CMD_GLUC)) {
+            logPrinter.print("  [1/4]", EMsgType.FAIL);
+            return true;
+        }
+        logPrinter.print("  [1/4]", EMsgType.PASS);
+        if (writeUsb(CMD_NSPName)) {
+            logPrinter.print("  [2/4]", EMsgType.FAIL);
+            return true;
+        }
+        logPrinter.print("  [2/4]", EMsgType.PASS);
+
+        if (writeUsb(pfsElement.getBytesNspFileNameLength())) {
+            logPrinter.print("  [3/4]", EMsgType.FAIL);
+            return true;
+        }
+        logPrinter.print("  [3/4]", EMsgType.PASS);
+
+        if (writeUsb(pfsElement.getBytesNspFileName())) {
+            logPrinter.print("  [4/4]", EMsgType.FAIL);
+            return true;
+        }
+        logPrinter.print("  [4/4]", EMsgType.PASS);
+
+        return false;
+    }
+    /**
+     * Start command handler
+     * @return true if failed
+     *         false if no issues
+     * */
+    private boolean handleStart(PFSProvider pfsElement){
+        logPrinter.print("GL Handle 'Start' command:", EMsgType.INFO);
+        if (writeUsb(CMD_GLUC)) {
+            logPrinter.print("  [Prefix]", EMsgType.FAIL);
+            return true;
+        }
+        logPrinter.print("  [Prefix]", EMsgType.PASS);
+
+        if (writeUsb(CMD_NSPData)) {
+            logPrinter.print("  [Command]", EMsgType.FAIL);
+            return true;
+        }
+        logPrinter.print("  [Command]", EMsgType.PASS);
+
+        if (writeUsb(pfsElement.getBytesCountOfNca())) {
+            logPrinter.print("  [Sub-files count]", EMsgType.FAIL);
+            return true;
+        }
+        logPrinter.print("  [Sub-files count]", EMsgType.PASS);
+
+        int ncaCount = pfsElement.getIntCountOfNca();
+        logPrinter.print("  [Information for "+ncaCount+" sub-files]", EMsgType.INFO);
+        for (int i = 0; i < ncaCount; i++){
+            logPrinter.print("File #"+i, EMsgType.INFO);
+            if (writeUsb(pfsElement.getNca(i).getNcaFileNameLength())) {
+                logPrinter.print("  [1/4] Name length", EMsgType.FAIL);
+                return true;
+            }
+            logPrinter.print("  [1/4] Name length", EMsgType.PASS);
+
+            if (writeUsb(pfsElement.getNca(i).getNcaFileName())) {
+                logPrinter.print("  [2/4] Name", EMsgType.FAIL);
+                return true;
+            }
+            logPrinter.print("  [2/4] Name", EMsgType.PASS);
+            if (writeUsb(ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(pfsElement.getBodySize()+pfsElement.getNca(i).getNcaOffset()).array())) {   // offset. real.
+                logPrinter.print("  [3/4] Offset", EMsgType.FAIL);
+                return true;
+            }
+            logPrinter.print("  [3/4] Offset", EMsgType.PASS);
+            if (writeUsb(ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(pfsElement.getNca(i).getNcaSize()).array())) {  // size
+                logPrinter.print("  [4/4] Size", EMsgType.FAIL);
+                return true;
+            }
+            logPrinter.print("  [4/4] Size", EMsgType.PASS);
+        }
+        return false;
+    }
+    /**
+     * NSPContent command handler
+     * @param isItRawRequest true: just ask NS what's needed
+     *                       false: send ticket
+     * @return true if failed
+     *         false if no issues
+     * */
+    private boolean handleNSPContent(PFSProvider pfsElement, boolean isItRawRequest){
+        int requestedNcaID;
+
+        if (isItRawRequest) {
+            logPrinter.print("GL Handle 'Content' command", EMsgType.INFO);
+            byte[] readByte = readUsb();
+            if (readByte == null || readByte.length != 4) {
+                logPrinter.print("  [Read requested ID]", EMsgType.FAIL);
+                return true;
+            }
+            requestedNcaID = ByteBuffer.wrap(readByte).order(ByteOrder.LITTLE_ENDIAN).getInt();
+            logPrinter.print("  [Read requested ID = "+requestedNcaID+" ]", EMsgType.PASS);
+        }
+        else {
+            requestedNcaID = pfsElement.getNcaTicketID();
+            logPrinter.print("GL Handle 'Ticket' command (ID = "+requestedNcaID+" )", EMsgType.INFO);
+        }
+
+        long realNcaOffset = pfsElement.getNca(requestedNcaID).getNcaOffset()+pfsElement.getBodySize();
+        long realNcaSize = pfsElement.getNca(requestedNcaID).getNcaSize();
+
+        long readFrom = 0;
+
+        int readPice = 8388608; // 8mb
+        byte[] readBuf;
+
+        try{
+            raf.seek(realNcaOffset);
+
+            while (readFrom < realNcaSize){
+                if (realNcaSize - readFrom < readPice)
+                    readPice = Math.toIntExact(realNcaSize - readFrom);    // it's safe, I guarantee
+                readBuf = new byte[readPice];
+                if (raf.read(readBuf) != readPice)
+                    return true;
+                //System.out.println("S: "+readFrom+" T: "+realNcaSize+" P: "+readPice);    //  DEBUG
+                if (writeUsb(readBuf))
+                    return true;
+                //-----------------------------------------/
+                logPrinter.updateProgress((readFrom+readPice)/(realNcaSize/100.0) / 100.0);
+                //-----------------------------------------/
+                readFrom += readPice;
+            }
+            //-----------------------------------------/
+            logPrinter.updateProgress(1.0);
+            //-----------------------------------------/
+        }
+        catch (IOException ioe){
+            logPrinter.print("GL Failed to read NCA ID "+requestedNcaID+". IO Exception:\n  "+ioe.getMessage(), EMsgType.FAIL);
+            ioe.printStackTrace();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public EFileStatus getStatus() { return status; }
+
+    /**
+     * Sending any byte array to USB device
+     * @return 'false' if no issues
+     *          'true' if errors happened
+     * */
+    private boolean writeUsb(byte[] message){
+        ByteBuffer writeBuffer = ByteBuffer.allocateDirect(message.length);   //writeBuffer.order() equals BIG_ENDIAN;
+        writeBuffer.put(message);                                             // Don't do writeBuffer.rewind();
+        IntBuffer writeBufTransferred = IntBuffer.allocate(1);
+        int result;
+
+        while (! task.isCancelled()) {
+            result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 1000);  // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01
+
+            switch (result){
+                case LibUsb.SUCCESS:
+                    if (writeBufTransferred.get() == message.length)
+                        return false;
+                    else {
+                        logPrinter.print("GL Data transfer issue [write]\n  Requested: "+message.length+"\n  Transferred: "+writeBufTransferred.get(), EMsgType.FAIL);
+                        return true;
+                    }
+                case LibUsb.ERROR_TIMEOUT:
+                    continue;
+                default:
+                    logPrinter.print("GL Data transfer issue [write]\n  Returned: "+ UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
+                    logPrinter.print("GL Execution stopped", EMsgType.FAIL);
+                    return true;
+            }
+        }
+        logPrinter.print("GL Execution interrupted", EMsgType.INFO);
+        return true;
+    }
+    /**
+     * Reading what USB device responded.
+     * @return byte array if data read successful
+     *         'null' if read failed
+     * */
+    private byte[] readUsb(){
+        ByteBuffer readBuffer = ByteBuffer.allocateDirect(512);
+        // We can limit it to 32 bytes, but there is a non-zero chance to got OVERFLOW from libusb.
+        IntBuffer readBufTransferred = IntBuffer.allocate(1);
+
+        int result;
+        while (! task.isCancelled()) {
+            result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000);  // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
+
+            switch (result) {
+                case LibUsb.SUCCESS:
+                    int trans = readBufTransferred.get();
+                    byte[] receivedBytes = new byte[trans];
+                    readBuffer.get(receivedBytes);
+                    return receivedBytes;
+                case LibUsb.ERROR_TIMEOUT:
+                    continue;
+                default:
+                    logPrinter.print("GL Data transfer issue [read]\n  Returned: " + UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
+                    logPrinter.print("GL Execution stopped", EMsgType.FAIL);
+                    return null;
+            }
+        }
+        logPrinter.print("GL Execution interrupted", EMsgType.INFO);
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/nsusbloader/USB/PFS/NCAFile.java b/src/main/java/nsusbloader/USB/PFS/NCAFile.java
new file mode 100644
index 0000000..368c79d
--- /dev/null
+++ b/src/main/java/nsusbloader/USB/PFS/NCAFile.java
@@ -0,0 +1,25 @@
+package nsusbloader.USB.PFS;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Data class to hold NCA, tik, xml etc. meta-information
+ * */
+public class NCAFile {
+    //private int ncaNumber;
+    private byte[] ncaFileName;
+    private long ncaOffset;
+    private long ncaSize;
+
+    //public void setNcaNumber(int ncaNumber){ this.ncaNumber = ncaNumber; }
+    void setNcaFileName(byte[] ncaFileName) { this.ncaFileName = ncaFileName; }
+    void setNcaOffset(long ncaOffset) { this.ncaOffset = ncaOffset; }
+    void setNcaSize(long ncaSize) { this.ncaSize = ncaSize; }
+
+    //public int getNcaNumber() {return this.ncaNumber; }
+    public byte[] getNcaFileName() { return ncaFileName; }
+    public byte[] getNcaFileNameLength() { return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(ncaFileName.length).array(); }
+    public long getNcaOffset() { return ncaOffset; }
+    public long getNcaSize() { return ncaSize; }
+}
diff --git a/src/main/java/nsusbloader/USB/PFS/PFSProvider.java b/src/main/java/nsusbloader/USB/PFS/PFSProvider.java
new file mode 100644
index 0000000..1ca2791
--- /dev/null
+++ b/src/main/java/nsusbloader/USB/PFS/PFSProvider.java
@@ -0,0 +1,183 @@
+package nsusbloader.USB.PFS;
+
+import nsusbloader.ModelControllers.LogPrinter;
+import nsusbloader.NSLDataTypes.EMsgType;
+import nsusbloader.ServiceWindow;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * Used in GoldLeaf USB protocol
+ * */
+public class PFSProvider {
+    private static final byte[] PFS0 = new byte[]{0x50, 0x46, 0x53, 0x30};  // PFS0
+
+    private String nspFileName;
+    private NCAFile[] ncaFiles;
+    private long bodySize;
+    private int ticketID = -1;
+
+    public PFSProvider(File nspFile, LogPrinter logPrinter) throws Exception{
+
+        RandomAccessFile randAccessFile = new RandomAccessFile(nspFile, "r");
+        nspFileName = nspFile.getName();
+
+        int filesCount;
+        int header;
+
+        logPrinter.print("PFS Start NSP file analyze for ["+nspFileName+"]", EMsgType.INFO);
+
+        byte[] fileStartingBytes = new byte[12];
+        // Read PFS0, files count, header, padding (4 zero bytes)
+        if (randAccessFile.read(fileStartingBytes) == 12)
+            logPrinter.print("PFS Read file starting bytes.", EMsgType.PASS);
+        else {
+            logPrinter.print("PFS Read file starting bytes.", EMsgType.FAIL);
+            randAccessFile.close();
+            throw new Exception("Unable to read file starting bytes");
+        }
+        // Check PFS0
+        if (Arrays.equals(PFS0, Arrays.copyOfRange(fileStartingBytes, 0, 4)))
+            logPrinter.print("PFS Read 'PFS0'.", EMsgType.PASS);
+        else
+            logPrinter.print("PFS Read 'PFS0': this file looks wired.", EMsgType.WARNING);
+        // Get files count
+        filesCount = ByteBuffer.wrap(Arrays.copyOfRange(fileStartingBytes, 4, 8)).order(ByteOrder.LITTLE_ENDIAN).getInt();
+        if (filesCount > 0 ) {
+            logPrinter.print("PFS Read files count [" + filesCount + "]", EMsgType.PASS);
+        }
+        else {
+            logPrinter.print("PFS Read files count", EMsgType.FAIL);
+            randAccessFile.close();
+            throw new Exception("Unable to read file count");
+        }
+        // Get header
+        header = ByteBuffer.wrap(Arrays.copyOfRange(fileStartingBytes, 8, 12)).order(ByteOrder.LITTLE_ENDIAN).getInt();
+        if (header > 0 )
+            logPrinter.print("PFS Read header ["+header+"]", EMsgType.PASS);
+        else {
+            logPrinter.print("PFS Read header ", EMsgType.FAIL);
+            randAccessFile.close();
+            throw new Exception("Unable to read header");
+        }
+        //*********************************************************************************************
+        // Create NCA set
+        this.ncaFiles = new NCAFile[filesCount];
+        // Collect files from NSP
+        byte[] ncaInfoArr = new byte[24];   // should be unsigned long, but.. java.. u know my pain man
+
+        HashMap<Integer, Long> ncaNameOffsets = new LinkedHashMap<>();
+
+        int offset;
+        long nca_offset;
+        long nca_size;
+        long nca_name_offset;
+
+        for (int i=0; i<filesCount; i++){
+            if (randAccessFile.read(ncaInfoArr) == 24) {
+                logPrinter.print("PFS Read NCA inside NSP: " + i, EMsgType.PASS);
+            }
+            else {
+                logPrinter.print("PFS Read NCA inside NSP: "+i, EMsgType.FAIL);
+                randAccessFile.close();
+                throw new Exception("Unable to read NCA inside NSP");
+            }
+            offset =  ByteBuffer.wrap(Arrays.copyOfRange(ncaInfoArr, 0, 4)).order(ByteOrder.LITTLE_ENDIAN).getInt();
+            nca_offset = ByteBuffer.wrap(Arrays.copyOfRange(ncaInfoArr, 4, 12)).order(ByteOrder.LITTLE_ENDIAN).getLong();
+            nca_size = ByteBuffer.wrap(Arrays.copyOfRange(ncaInfoArr, 12, 20)).order(ByteOrder.LITTLE_ENDIAN).getLong();
+            nca_name_offset = ByteBuffer.wrap(Arrays.copyOfRange(ncaInfoArr, 20, 24)).order(ByteOrder.LITTLE_ENDIAN).getInt(); // yes, cast from int to long.
+
+            logPrinter.print("  Padding check", offset == 0?EMsgType.PASS:EMsgType.WARNING);
+            logPrinter.print("  NCA offset check: "+nca_offset, nca_offset >= 0?EMsgType.PASS:EMsgType.WARNING);
+            logPrinter.print("  NCA size check: "+nca_size, nca_size >= 0?EMsgType.PASS: EMsgType.WARNING);
+            logPrinter.print("  NCA name offset check: "+nca_name_offset, nca_name_offset >= 0?EMsgType.PASS:EMsgType.WARNING);
+
+            NCAFile ncaFile = new NCAFile();
+            ncaFile.setNcaOffset(nca_offset);
+            ncaFile.setNcaSize(nca_size);
+            this.ncaFiles[i] = ncaFile;
+
+            ncaNameOffsets.put(i, nca_name_offset);
+        }
+        // Final offset
+        byte[] bufForInt = new byte[4];
+        if ((randAccessFile.read(bufForInt) == 4) && (Arrays.equals(bufForInt, new byte[4])))
+            logPrinter.print("PFS Final padding check", EMsgType.PASS);
+        else
+            logPrinter.print("PFS Final padding check", EMsgType.WARNING);
+
+        // Calculate position including header for body size offset
+        bodySize = randAccessFile.getFilePointer()+header;
+        //*********************************************************************************************
+        // Collect file names from NCAs
+        logPrinter.print("PFS Collecting file names", EMsgType.INFO);
+        List<Byte> ncaFN;                 // Temporary
+        byte[] b = new byte[1];                 // Temporary
+        for (int i=0; i<filesCount; i++){
+            ncaFN = new ArrayList<>();
+            randAccessFile.seek(filesCount*24+16+ncaNameOffsets.get(i));          // Files cont * 24(bit for each meta-data) + 4 bytes goes after all of them  + 12 bit what were in the beginning
+            while ((randAccessFile.read(b)) != -1){
+                if (b[0] == 0x00)
+                    break;
+                else
+                    ncaFN.add(b[0]);
+            }
+            byte[] exchangeTempArray = new byte[ncaFN.size()];
+            for (int j=0; j < ncaFN.size(); j++)
+                exchangeTempArray[j] = ncaFN.get(j);
+            // Find and store ticket (.tik)
+            if (new String(exchangeTempArray, StandardCharsets.UTF_8).toLowerCase().endsWith(".tik"))
+                this.ticketID = i;
+            this.ncaFiles[i].setNcaFileName(Arrays.copyOf(exchangeTempArray, exchangeTempArray.length));
+        }
+        randAccessFile.close();
+        logPrinter.print("PFS Finished NSP file analyze for ["+nspFileName+"]", EMsgType.PASS);
+    }
+    /**
+     * Return file name as byte array
+     * */
+    public byte[] getBytesNspFileName(){
+        return nspFileName.getBytes(StandardCharsets.UTF_8);
+    }
+    /**
+     * Return file name length as byte array
+     * */
+    public byte[] getBytesNspFileNameLength(){
+        return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(getBytesNspFileName().length).array();
+    }
+    /**
+     * Return NCA count inside of file as byte array
+     * */
+    public byte[] getBytesCountOfNca(){
+        return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(ncaFiles.length).array();
+    }
+    /**
+     * Return NCA count inside of file as int
+     * */
+    public int getIntCountOfNca(){
+        return ncaFiles.length;
+    }
+    /**
+     * Return requested-by-number NCA file inside of file
+     * */
+    public NCAFile getNca(int ncaNumber){
+        return ncaFiles[ncaNumber];
+    }
+    /**
+     * Return bodySize
+     * */
+    public long getBodySize(){
+        return bodySize;
+    }
+    /**
+     * Return special NCA file: ticket
+     * (sugar)
+     * */
+    public int getNcaTicketID(){
+        return ticketID;
+    }
+}
diff --git a/src/main/java/nsusbloader/USB/UsbCommunications.java b/src/main/java/nsusbloader/USB/UsbCommunications.java
index 97df6a6..4206d13 100644
--- a/src/main/java/nsusbloader/USB/UsbCommunications.java
+++ b/src/main/java/nsusbloader/USB/UsbCommunications.java
@@ -54,8 +54,10 @@ public class UsbCommunications extends Task<Void> {
 
         if (protocol.equals("TinFoil"))
             module = new TinFoil(handler, nspMap, this, logPrinter);
-        else
+        else if (protocol.equals("GoldLeaf"))
             module = new GoldLeaf(handler, nspMap, this, logPrinter, nspFilterForGl);
+        else
+            module = new GoldLeaf_05(handler, nspMap, this, logPrinter);
 
         usbConnect.close();
 
diff --git a/src/main/resources/SettingsTab.fxml b/src/main/resources/SettingsTab.fxml
index 7e3532f..4664798 100644
--- a/src/main/resources/SettingsTab.fxml
+++ b/src/main/resources/SettingsTab.fxml
@@ -94,6 +94,12 @@
                   </HBox>
                   <CheckBox fx:id="tfXciSpprtCb" mnemonicParsing="false" text="%tab2_Cb_AllowXci" />
                   <Label disable="true" text="%tab2_Lbl_AllowXciDesc" wrapText="true" />
+         <HBox alignment="CENTER_LEFT" spacing="5.0">
+            <children>
+               <CheckBox fx:id="glOldVerCheck" mnemonicParsing="false" text="%tab2_Cb_UseOldGlVersion" />
+               <ChoiceBox fx:id="glOldVerChoice" prefWidth="75.0" />
+            </children>
+         </HBox>
                </children>
                <padding>
                   <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
diff --git a/src/main/resources/locale.properties b/src/main/resources/locale.properties
index 74de375..438b73d 100644
--- a/src/main/resources/locale.properties
+++ b/src/main/resources/locale.properties
@@ -43,3 +43,4 @@ tab2_Lbl_AllowXciDesc=Used by some third-party applications that support XCI and
 tab2_Lbl_Language=Language
 windowBodyRestartToApplyLang=Please restart application to apply changes.
 tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
+tab2_Cb_UseOldGlVersion=Use old GoldLeaf version
diff --git a/src/main/resources/locale_rus.properties b/src/main/resources/locale_rus.properties
index 1751e5b..6e7abc0 100644
--- a/src/main/resources/locale_rus.properties
+++ b/src/main/resources/locale_rus.properties
@@ -43,4 +43,5 @@ tab2_Lbl_AllowXciDesc=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u04
 tab2_Lbl_Language=\u042F\u0437\u044B\u043A
 windowBodyRestartToApplyLang=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0447\u0442\u043E\u0431\u044B \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
 tab2_Cb_GLshowNspOnly=\u041E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C \u0438\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0444\u0430\u0439\u043B\u044B *.nsp \u0432 GoldLeaf.
+tab2_Cb_UseOldGlVersion=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0430\u0440\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E GoldLeaf
 
diff --git a/src/main/resources/locale_ukr.properties b/src/main/resources/locale_ukr.properties
index 3cf30d5..9d3d6f4 100644
--- a/src/main/resources/locale_ukr.properties
+++ b/src/main/resources/locale_ukr.properties
@@ -42,4 +42,5 @@ tab2_Cb_AllowXci=\u0414\u043E\u0437\u0432\u043E\u043B\u0438\u0442\u0438 \u0432\u
 tab2_Lbl_AllowXciDesc=\u0412\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0454\u0442\u044C\u0441\u044F \u0434\u0435\u044F\u043A\u0438\u043C\u0438 \u0441\u0442\u043E\u0440\u043E\u043D\u043D\u0456\u043C\u0438 \u0434\u043E\u0434\u0430\u0442\u043A\u0430\u043C\u0438, \u044F\u043A\u0456 \u043F\u0456\u0434\u0442\u0440\u0438\u043C\u0443\u044E\u0442\u044C XCI \u0456 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u044E\u0442\u044C \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0456 TinFoil. \u042F\u043A\u0449\u043E \u043D\u0435 \u0432\u043F\u0435\u0432\u043D\u0435\u043D\u0456 \u2014\u00A0\u043D\u0435 \u0437\u043C\u0456\u043D\u044E\u0439\u0442\u0435.
 tab2_Lbl_Language=\u041C\u043E\u0432\u0430
 windowBodyRestartToApplyLang=\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0456\u0442\u044C \u0434\u043E\u0434\u0430\u0442\u043E\u043A \u0449\u043E\u0431 \u0437\u043C\u0456\u043D\u0438 \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
-tab2_Cb_GLshowNspOnly=\u0412\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u0432\u0438\u043A\u043B\u044E\u0447\u043D\u043E *.nsp \u0444\u0430\u0439\u043B\u0438 \u0443 GoldLeaf.
\ No newline at end of file
+tab2_Cb_GLshowNspOnly=\u0412\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u0432\u0438\u043A\u043B\u044E\u0447\u043D\u043E *.nsp \u0444\u0430\u0439\u043B\u0438 \u0443 GoldLeaf.
+tab2_Cb_UseOldGlVersion=\u0412\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u0440\u0443 \u0432\u0435\u0440\u0441\u0456\u044E GoldLeaf
\ No newline at end of file