Inheritance: ICloneable
        private void button2_Click(object sender, EventArgs e)
        {
            byte[] original = null, modified = null;

            try
            {
                BinaryReader br = new BinaryReader(File.OpenRead(textBox1.Text));
                original = br.ReadBytes((int)br.BaseStream.Length);
                br.Close();
            }
            catch (Exception)
            {
                MessageBox.Show("Error opening file\n" + textBox1.Text);
                return;
            }

            try
            {
                BinaryReader br = new BinaryReader(File.Open(textBox2.Text, FileMode.Open));
                modified = br.ReadBytes((int)br.BaseStream.Length);
                br.Close();
            }
            catch (Exception)
            {
                MessageBox.Show("Error opening file\n" + textBox2.Text);
                return;
            }

            UPSfile upsFile = new UPSfile(original, modified);
            upsFile.WriteToFile(textBox3.Text);
            MessageBox.Show("Patch has been created.");

            this.Close();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            if (!File.Exists(textBox1.Text))
            {
                MessageBox.Show("Patch doesn't exist.");
                return;
            }
            UPSfile UPSFile = new UPSfile(textBox1.Text);
            int[,] details = UPSFile.GetData();
            UPSFile = null;

            List<string> lines = new List<string>(details.Length + 1);
            lines.Add(textBox2.Lines[0]);
            string offsets = "Offsets ";
            string lenghts = "Lenghts";
            lines.Add(offsets);
            int longestOffsetLenght = offsets.Length;
            for (int i = 0; i < details.Length / 2; i++)
            {
                string line = Convert.ToString(details[i, 0], 16);
                if (line.Length + 1 > longestOffsetLenght)
                    longestOffsetLenght = line.Length + 1;
                lines.Add(line);
            }

            for (int i = 1; i < lines.Count; i++)
                lines[i] += "\t";
            lines[1] += lenghts;
            for (int i = 2; i < lines.Count; i++)
            {
                lines[i] += Convert.ToString(details[i - 2, 1], 16);
                lines[i] = lines[i].ToUpper();
            }

            textBox2.Lines = lines.ToArray();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            UPSfile upsFile = new UPSfile(textBox3.Text);
            byte[] file = null;

            try
            {
                BinaryReader br = new BinaryReader(File.Open(textBox1.Text, FileMode.OpenOrCreate));
                file = br.ReadBytes((int)br.BaseStream.Length);
                br.Close();
            }
            catch (Exception)
            {
                MessageBox.Show("Error opening file\n" + textBox1.Text);
                return;
            }

            if (!upsFile.ValidPatch)
            {
                MessageBox.Show("The patch is corrupt.");
                return;
            }

            bool validToApply = upsFile.ValidToApply(file);

            if (radioButton1.Checked)
            {
                if (!validToApply)
                {
                    MessageBox.Show("The patch doesn't match the file.\nPatching canceled.");
                    return;
                }
            }
            else if (radioButton2.Checked)
            {
                if (!validToApply)
                {
                    if (MessageBox.Show("The patch doesn't match the file.\nPatch anyway?", "Patch?", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                        return;
                }
            }
            else if (radioButton3.Checked)
            {
                if (!validToApply)
                    MessageBox.Show("The patch doesn't match the file.\nPatching anyway.");
            }
            else if (!radioButton4.Checked)
            {
                throw new Exception("What do you want me to do!?!?!?");
            }

            if (checkBox1.Checked)
            {
                string filePath = Path.ChangeExtension(textBox1.Text, ".bak");
                if (File.Exists(filePath))
                {
                    string fileName = Path.GetFileNameWithoutExtension(textBox1.Text);
                    int i = 1;
                    while (File.Exists(Path.GetDirectoryName(textBox1.Text) + fileName + i + ".bak"))
                    {
                        i++;
                    }
                    filePath = Path.GetDirectoryName(textBox1.Text) + fileName + i + ".bak";
                }

                File.Copy(textBox1.Text, filePath, false);
            }

            byte[] newFile = upsFile.Apply(file);

            try
            {
                BinaryWriter bw = new BinaryWriter(File.Open(textBox1.Text, FileMode.Truncate));
                bw.Write(newFile);
                bw.Close();
            }
            catch (Exception)
            {
                MessageBox.Show("Error opening file\n" + textBox1.Text);
                return;
            }

            MessageBox.Show("Patching has been done.");
            this.Close();
        }
        public static UPSfile operator +(UPSfile a, UPSfile b)
        {
            byte[] emptyFile = new byte[Math.Max(a.newFileSize, b.newFileSize)];
            byte[] OrigEmptyFile = emptyFile.Clone() as byte[];
            emptyFile = b.Apply(a.Apply(emptyFile));

            UPSfile result = new UPSfile(OrigEmptyFile, emptyFile);
            result.patchCRC32 = result.CalculatePatchCRC32();
            result.originalFileCRC32 = a.originalFileCRC32;
            result.newFileCRC32 = 0;

            return result;
        }