diff --git a/IPASorter/FileClass.cs b/IPASorter/FileClass.cs
deleted file mode 100644
index 6e3b624..0000000
--- a/IPASorter/FileClass.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace IPASorter
-{
- public class IPAFile
- {
- public string path { get; set; }
- public string md5sum { get; set; }
- public string fileName { get; set; }
- public string CFBundleIdentifier { get; set; }
- public string CFBundleVersion { get; set; }
- public string MinimumOSVersion { get; set; }
- public string CFBundleDisplayName { get; set; }
- }
-
- public class AppList
- {
- public IPAFile[] apps { get; set; }
- }
-}
diff --git a/IPASorter/IPASorter.csproj b/IPASorter/IPASorter.csproj
index 5733140..c73e0d1 100644
--- a/IPASorter/IPASorter.csproj
+++ b/IPASorter/IPASorter.csproj
@@ -5,10 +5,4 @@
netcoreapp3.1
-
-
- PlistCS.dll
-
-
-
diff --git a/IPASorter/Plist.cs b/IPASorter/Plist.cs
new file mode 100644
index 0000000..f52c364
--- /dev/null
+++ b/IPASorter/Plist.cs
@@ -0,0 +1,961 @@
+//
+// PlistCS Property List (plist) serialization and parsing library.
+//
+// https://github.com/animetrics/PlistCS
+//
+// Copyright (c) 2011 Animetrics Inc. (marc@animetrics.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace PlistCS
+{
+ public static class Plist
+ {
+ private static List offsetTable = new List();
+ private static List objectTable = new List();
+ private static int refCount;
+ private static int objRefSize;
+ private static int offsetByteSize;
+ private static long offsetTableOffset;
+
+ #region Public Functions
+
+ public static object readPlist(string path)
+ {
+ using (FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read))
+ {
+ return readPlist(f, plistType.Auto);
+ }
+ }
+
+ public static object readPlistSource(string source)
+ {
+ return readPlist(System.Text.Encoding.UTF8.GetBytes(source));
+ }
+
+ public static object readPlist(byte[] data)
+ {
+ return readPlist(new MemoryStream(data), plistType.Auto);
+ }
+
+ public static plistType getPlistType(Stream stream)
+ {
+ byte[] magicHeader = new byte[8];
+ stream.Read(magicHeader, 0, 8);
+
+ if (BitConverter.ToInt64(magicHeader, 0) == 3472403351741427810)
+ {
+ return plistType.Binary;
+ }
+ else
+ {
+ return plistType.Xml;
+ }
+ }
+
+ public static object readPlist(Stream stream, plistType type)
+ {
+ if (type == plistType.Auto)
+ {
+ type = getPlistType(stream);
+ stream.Seek(0, SeekOrigin.Begin);
+ }
+
+ if (type == plistType.Binary)
+ {
+ using (BinaryReader reader = new BinaryReader(stream))
+ {
+ byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
+ return readBinary(data);
+ }
+ }
+ else
+ {
+ XmlDocument xml = new XmlDocument();
+ xml.XmlResolver = null;
+ xml.Load(stream);
+ return readXml(xml);
+ }
+ }
+
+ public static void writeXml(object value, string path)
+ {
+ using (StreamWriter writer = new StreamWriter(path))
+ {
+ writer.Write(writeXml(value));
+ }
+ }
+
+ public static void writeXml(object value, Stream stream)
+ {
+ using (StreamWriter writer = new StreamWriter(stream))
+ {
+ writer.Write(writeXml(value));
+ }
+ }
+
+ public static string writeXml(object value)
+ {
+ using (MemoryStream ms = new MemoryStream())
+ {
+ XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
+ xmlWriterSettings.Encoding = new System.Text.UTF8Encoding(false);
+ xmlWriterSettings.ConformanceLevel = ConformanceLevel.Document;
+ xmlWriterSettings.Indent = true;
+
+ using (XmlWriter xmlWriter = XmlWriter.Create(ms, xmlWriterSettings))
+ {
+ xmlWriter.WriteStartDocument();
+ //xmlWriter.WriteComment("DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
+ xmlWriter.WriteDocType("plist", "-//Apple Computer//DTD PLIST 1.0//EN", "http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);
+ xmlWriter.WriteStartElement("plist");
+ xmlWriter.WriteAttributeString("version", "1.0");
+ compose(value, xmlWriter);
+ xmlWriter.WriteEndElement();
+ xmlWriter.WriteEndDocument();
+ xmlWriter.Flush();
+ xmlWriter.Close();
+ return System.Text.Encoding.UTF8.GetString(ms.ToArray());
+ }
+ }
+ }
+
+ public static void writeBinary(object value, string path)
+ {
+ using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create)))
+ {
+ writer.Write(writeBinary(value));
+ }
+ }
+
+ public static void writeBinary(object value, Stream stream)
+ {
+ using (BinaryWriter writer = new BinaryWriter(stream))
+ {
+ writer.Write(writeBinary(value));
+ }
+ }
+
+ public static byte[] writeBinary(object value)
+ {
+ offsetTable.Clear();
+ objectTable.Clear();
+ refCount = 0;
+ objRefSize = 0;
+ offsetByteSize = 0;
+ offsetTableOffset = 0;
+
+ //Do not count the root node, subtract by 1
+ int totalRefs = countObject(value) - 1;
+
+ refCount = totalRefs;
+
+ objRefSize = RegulateNullBytes(BitConverter.GetBytes(refCount)).Length;
+
+ composeBinary(value);
+
+ writeBinaryString("bplist00", false);
+
+ offsetTableOffset = (long)objectTable.Count;
+
+ offsetTable.Add(objectTable.Count - 8);
+
+ offsetByteSize = RegulateNullBytes(BitConverter.GetBytes(offsetTable[offsetTable.Count - 1])).Length;
+
+ List offsetBytes = new List();
+
+ offsetTable.Reverse();
+
+ for (int i = 0; i < offsetTable.Count; i++)
+ {
+ offsetTable[i] = objectTable.Count - offsetTable[i];
+ byte[] buffer = RegulateNullBytes(BitConverter.GetBytes(offsetTable[i]), offsetByteSize);
+ Array.Reverse(buffer);
+ offsetBytes.AddRange(buffer);
+ }
+
+ objectTable.AddRange(offsetBytes);
+
+ objectTable.AddRange(new byte[6]);
+ objectTable.Add(Convert.ToByte(offsetByteSize));
+ objectTable.Add(Convert.ToByte(objRefSize));
+
+ var a = BitConverter.GetBytes((long)totalRefs + 1);
+ Array.Reverse(a);
+ objectTable.AddRange(a);
+
+ objectTable.AddRange(BitConverter.GetBytes((long)0));
+ a = BitConverter.GetBytes(offsetTableOffset);
+ Array.Reverse(a);
+ objectTable.AddRange(a);
+
+ return objectTable.ToArray();
+ }
+
+ #endregion
+
+ #region Private Functions
+
+ private static object readXml(XmlDocument xml)
+ {
+ XmlNode rootNode = xml.DocumentElement.ChildNodes[0];
+ return parse(rootNode);
+ }
+
+ private static object readBinary(byte[] data)
+ {
+ offsetTable.Clear();
+ List offsetTableBytes = new List();
+ objectTable.Clear();
+ refCount = 0;
+ objRefSize = 0;
+ offsetByteSize = 0;
+ offsetTableOffset = 0;
+
+ List bList = new List(data);
+
+ List trailer = bList.GetRange(bList.Count - 32, 32);
+
+ parseTrailer(trailer);
+
+ objectTable = bList.GetRange(0, (int)offsetTableOffset);
+
+ offsetTableBytes = bList.GetRange((int)offsetTableOffset, bList.Count - (int)offsetTableOffset - 32);
+
+ parseOffsetTable(offsetTableBytes);
+
+ return parseBinary(0);
+ }
+
+ private static Dictionary parseDictionary(XmlNode node)
+ {
+ XmlNodeList children = node.ChildNodes;
+ if (children.Count % 2 != 0)
+ {
+ throw new DataMisalignedException("Dictionary elements must have an even number of child nodes");
+ }
+
+ Dictionary dict = new Dictionary();
+
+ for (int i = 0; i < children.Count; i += 2)
+ {
+ XmlNode keynode = children[i];
+ XmlNode valnode = children[i + 1];
+
+ if (keynode.Name != "key")
+ {
+ throw new ApplicationException("expected a key node");
+ }
+
+ object result = parse(valnode);
+
+ if (result != null)
+ {
+ dict.Add(keynode.InnerText, result);
+ }
+ }
+
+ return dict;
+ }
+
+ private static List