// Adds a new entry as a raw hexstring representation of the object's raw bytes
        public bool AddEntryAsBinary(string Name, object Value)
        {
            // Verify entry is valid
            if (Value == null)
            {
                return(false);
            }

            // Create an output array
            byte[] Output = new byte[0];
            int    Size   = 0;

            if (Value.GetType().IsArray)
            {
                Type ArrayType = Value.GetType();
                foreach (object Val in (Value as Array))
                {
                    Size += Encoding.GetSizeOfObject(Val);
                }
            }
            else
            {
                Size = Encoding.GetSizeOfObject(Value);
            }
            Output = Encoding.AppendToByteArray(SerializeVarInt(Size), Output);

            // Serialize object
            Output = Encoding.AppendToByteArray(SerializeObjectAsBinary(Value), Output);

            // Add as an entry
            AddEntry(Name, Encoding.ByteArrayToString(Output));
            return(true);
        }
        /* Add the magic identifier to the beginning of the input string */
        protected static string AddMagicIdentifier(string input,
                                                   byte[] magicIdentifier)
        {
            byte[] inputBytes = Encoding.StringToByteArray(input);

            inputBytes = AddMagicIdentifier(inputBytes, magicIdentifier);

            return(Encoding.ByteArrayToString(inputBytes));
        }
        // Decodes an object packed into a byte array
        private T DeserializeObjectFromBinary <T>(byte[] Data)
        {
            // Create an output object
            T Output = default(T);

            // Object is an integer
            if (typeof(T).GetInterfaces().Contains(typeof(IConvertible)))
            {
                // Create a generic method wrapper to access deserialization
                MethodInfo MethodInfo = typeof(Encoding).GetMethod("ByteArrayToInteger", new[] { typeof(byte[]), typeof(int) });
                Type[]     Args       = new Type[] { typeof(T) };
                MethodInfo Method     = MethodInfo.MakeGenericMethod(Args);

                // Deserialize integer
                Output = (T)Method.Invoke(null, new object[] { Data, 0 });
            }

            // Object is a string
            else if (typeof(T) == typeof(string))
            {
                // Deserialize string length
                int Length = DeserializeVarInt <int>(Data, 0, out int Offset);

                // Deserialize string
                Output = (T)Convert.ChangeType(Encoding.ByteArrayToString(Encoding.SplitByteArray(Data, Offset, Length)), typeof(T));
            }

            // Object is an array
            else if (typeof(T).IsArray)
            {
                // Create a generic method wrapper to access deserialization
                MethodInfo MethodInfo = typeof(PortableStorage).GetMethod("DeserializeArrayFromBinary");
                Type[]     Args       = new Type[] { typeof(T) };
                MethodInfo Method     = MethodInfo.MakeGenericMethod(Args);

                // Deserialize integer
                Output = (T)Method.Invoke(null, new object[] { Data });
            }

            // Property is an object
            else
            {
                // Get property list of type
                var Properties = typeof(T).GetProperties();

                // Create a buffer
                byte[] Buffer = Encoding.AppendToByteArray(Data, new byte[0]);

                // Loop through object properties
                foreach (PropertyInfo Property in Properties)
                {
                    // Create a generic method wrapper to access deserialization
                    MethodInfo MethodInfo = typeof(PortableStorage).GetMethod("DeserializeObjectFromBinary");
                    Type[]     Args       = new Type[] { Property.PropertyType };
                    MethodInfo Method     = MethodInfo.MakeGenericMethod(Args);

                    // Set object parameter value
                    var    Param = Method.Invoke(null, new object[] { Buffer });
                    object Temp  = Output;
                    Property.SetValue(Temp, Convert.ChangeType(Param, Property.PropertyType));
                    Output = (T)Convert.ChangeType(Temp, typeof(T));

                    // Resize buffer
                    Buffer = Encoding.SplitByteArray(Buffer, Encoding.GetSizeOfObject(Property.GetValue(Output)), Buffer.Length - Encoding.GetSizeOfObject(Property.GetValue(Output)));
                }
            }

            // Return output
            return(Output);
        }
        // Deserializes an entry from a byte array and adds it to storage
        private byte[] DeserializeEntry(byte[] Buffer)
        {
            // Get entry name length
            int NameLength = Encoding.ByteArrayToInteger <byte>(Buffer, 0, 1);//DeserializeVarInt<int>(Buffer, 0, out int Offset);
            int Offset     = 1;

            if (NameLength < 1 || NameLength > MAX_STRING_LENGTH)
            {
                throw new Exception("Name size exceeds allowed string bounds");
            }

            // Get entry name
            string Name = Encoding.ByteArrayToString(Buffer, Offset, NameLength);

            Offset += NameLength;
            Buffer  = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset);

            // Get object type
            SerializationType Type = GetType(Buffer);

            if ((int)Type < 1 || (int)Type > 14)
            {
                throw new Exception("Invalid serialization type caught: " +
                                    Encoding.ByteArrayToHexString(Encoding.SplitByteArray(Buffer, 1, Buffer.Length - 1)));
            }
            Buffer = Encoding.SplitByteArray(Buffer, 1, Buffer.Length - 1);

            // Create an entry object
            var Output = new object();

            // Object is a string
            if (Type == SerializationType.STRING)
            {
                // Deserialize string length
                int Length = DeserializeVarInt <int>(Buffer, 0, out Offset);

                // Deserialize string
                Output = Encoding.ByteArrayToString(Encoding.SplitByteArray(Buffer, Offset, Length));

                // Resize buffer
                Offset += (Output as string).Length;
                if (Buffer.Length - Offset > 0)
                {
                    Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset);
                }
            }

            // Object is an integer
            else if ((int)Type >= 1 && (int)Type <= 9)
            {
                // Create a generic method wrapper to access deserialization
                MethodInfo MethodInfo = typeof(Encoding).GetMethod("ByteArrayToInteger", new[] { typeof(byte[]), typeof(int) });
                Type[]     Args       = new Type[] { ConvertSerializationType(Type) };
                MethodInfo Method     = MethodInfo.MakeGenericMethod(Args);

                // Deserialize integer
                Output = Method.Invoke(null, new object[] { Buffer, 0 });

                // Resize buffer
                Offset = Encoding.GetSizeOfObject(Output);
                if (Buffer.Length - Offset > 0)
                {
                    Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset);
                }
            }

            // Object is an object
            else if (Type == SerializationType.OBJECT)
            {
                // Create a new storage object
                PortableStorage Storage = new PortableStorage();

                // Deserialize entry
                Buffer = Storage.Deserialize(Buffer, false);
                Output = Storage;
            }

            // Add to entries
            Entries.Add(Name, Output);

            // Return buffer output
            return(Buffer);
        }