static public string ToString()
 {
     return(new StringBuilder()
            .AppendLine($"Author: {Author}")
            .AppendLine($"Email: {Email}")
            .AppendLine($"Code Start: {CodeStart.ToShortDateString()}")
            .AppendLine($"Code Time (hours): {Math.Round(CodeHours, 1)}")
            .AppendLine($"Requirements:")
            .AppendLine(Requirments)
            .ToString());
 }
            /// <summary>
            /// Returns a <see cref="System.String" /> that represents this instance.
            /// </summary>
            /// <returns>
            /// A <see cref="System.String" /> that represents this instance.
            /// </returns>
            public override string ToString()
            {
                if (this.pointer == IntPtr.Zero)
                {
                    return(this.pointer.ToString("X16"));
                }

                CodeStart codeStart = new CodeStart(this);

                if (codeStart == CodeStart.Zero)
                {
                    return(this.pointer.ToString("X16"));
                }

                return(this.pointer.ToString("X16") + "(" + codeStart.ToString() + ")");
            }
        /// <summary>
        /// Initializes a new instance of the <see cref="MonoDetour" /> class.
        /// </summary>
        /// <param name="originalClass">The original class.</param>
        /// <param name="replacementClass">The replacement class.</param>
        /// <param name="originalMethodName">Name of the original method.</param>
        /// <param name="replacementMethodName">Name of the replacement method.</param>
        /// <exception cref="System.ArgumentException">
        /// Original method name not defined
        /// or
        /// Replacement method name not defined.
        /// </exception>
        /// <exception cref="System.NullReferenceException">
        /// Replacement method not found
        /// or
        /// Original method not found
        /// or
        /// Original method address not found
        /// or
        /// Replacement method address not found
        /// or
        /// Original call info not found.
        /// </exception>
        public MonoDetour(Type originalClass, Type replacementClass, string originalMethodName, string replacementMethodName = null)
        {
            Log.Debug(this, "MonoDetour", "Construct", originalClass, replacementClass, originalMethodName, replacementMethodName);

            this.IsDetoured            = false;
            this.originalType          = originalClass;
            this.replacementType       = replacementClass;
            this.originalMethodName    = originalMethodName;
            this.replacementMethodName = (replacementMethodName == null) ? originalMethodName : replacementMethodName;

            if (String.IsNullOrEmpty(this.originalMethodName))
            {
                throw new ArgumentException("Original method name not defined");
            }

            if (String.IsNullOrEmpty(this.replacementMethodName))
            {
                throw new ArgumentException("Replacement method name not defined");
            }

            // Get info for the replacement method.
            MethodInfo replacementMethod = replacementClass.GetMethod(
                this.replacementMethodName,
                BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

            if (replacementMethod == null)
            {
                throw new NullReferenceException("Replacement method not found");
            }

            // Find and get info for the original method by comparing all methods with the specified name to the replacement method.
            MethodInfo originalMethod = FindMethod(originalClass, originalMethodName, replacementMethod);

            if (originalMethod == null)
            {
                throw new NullReferenceException("Original method not found");
            }

            this.originalCallSite = originalMethod.MethodHandle.GetFunctionPointer();
            if (this.originalCallSite == CallSite.Zero)
            {
                throw new NullReferenceException("Original method address not found");
            }

            this.replacementCallSite = replacementMethod.MethodHandle.GetFunctionPointer();
            if (this.replacementCallSite == CallSite.Zero)
            {
                throw new NullReferenceException("Replacement method address not found");
            }

            // Save call info to original code.
            this.originalCodeStart = new CodeStart(this.originalCallSite);
            if (this.originalCodeStart == CodeStart.Zero)
            {
                throw new NullReferenceException("Original call info not found");
            }

            if (Log.LogALot)
            {
                Log.DevDebug(this, "MonoDetour", "Constructed", originalClass, replacementClass, originalMethodName, replacementMethodName);
            }
        }
 /// <summary>
 /// Patches the call site with whatever instructions are in code start.
 /// </summary>
 /// <param name="callSite">The call site.</param>
 /// <param name="codeStart">The call info.</param>
 private void PatchCallSiteWithCodeStart(IntPtr callSite, CodeStart codeStart)
 {
     codeStart.PatchCallSite(callSite);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="MonoDetour" /> class.
        /// </summary>
        /// <param name="originalClass">The original class.</param>
        /// <param name="replacementClass">The replacement class.</param>
        /// <param name="originalMethodName">Name of the original method.</param>
        /// <param name="replacementMethodName">Name of the replacement method.</param>
        /// <exception cref="System.ArgumentException">
        /// Original method name not defined
        /// or
        /// Replacement method name not defined.
        /// </exception>
        /// <exception cref="System.NullReferenceException">
        /// Replacement method not found
        /// or
        /// Original method not found
        /// or
        /// Original method address not found
        /// or
        /// Replacement method address not found
        /// or
        /// Original call info not found.
        /// </exception>
        public MonoDetour(Type originalClass, Type replacementClass, string originalMethodName, string replacementMethodName = null)
        {
            Log.Debug(this, "MonoDetour", "Construct", originalClass, replacementClass, originalMethodName, replacementMethodName);

            this.IsDetoured = false;
            this.originalType = originalClass;
            this.replacementType = replacementClass;
            this.originalMethodName = originalMethodName;
            this.replacementMethodName = (replacementMethodName == null) ? originalMethodName : replacementMethodName;

            if (String.IsNullOrEmpty(this.originalMethodName))
            {
                throw new ArgumentException("Original method name not defined");
            }

            if (String.IsNullOrEmpty(this.replacementMethodName))
            {
                throw new ArgumentException("Replacement method name not defined");
            }

            // Get info for the replacement method.
            MethodInfo replacementMethod = replacementClass.GetMethod(
                                            this.replacementMethodName,
                                            BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            if (replacementMethod == null)
            {
                throw new NullReferenceException("Replacement method not found");
            }

            // Find and get info for the original method by comparing all methods with the specified name to the replacement method.
            MethodInfo originalMethod = FindMethod(originalClass, originalMethodName, replacementMethod);

            if (originalMethod == null)
            {
                throw new NullReferenceException("Original method not found");
            }

            this.originalCallSite = originalMethod.MethodHandle.GetFunctionPointer();
            if (this.originalCallSite == CallSite.Zero)
            {
                throw new NullReferenceException("Original method address not found");
            }

            this.replacementCallSite = replacementMethod.MethodHandle.GetFunctionPointer();
            if (this.replacementCallSite == CallSite.Zero)
            {
                throw new NullReferenceException("Replacement method address not found");
            }

            // Save call info to original code.
            this.originalCodeStart = new CodeStart(this.originalCallSite);
            if (this.originalCodeStart == CodeStart.Zero)
            {
                throw new NullReferenceException("Original call info not found");
            }

            if (Log.LogALot)
            {
                Log.DevDebug(this, "MonoDetour", "Constructed", originalClass, replacementClass, originalMethodName, replacementMethodName);
            }
        }
            /// <summary>
            /// Returns a <see cref="System.String" /> that represents this instance.
            /// </summary>
            /// <returns>
            /// A <see cref="System.String" /> that represents this instance.
            /// </returns>
            public override string ToString()
            {
                if (this.pointer == IntPtr.Zero)
                {
                    return this.pointer.ToString("X16");
                }

                CodeStart codeStart = new CodeStart(this);
                if (codeStart == CodeStart.Zero)
                {
                    return this.pointer.ToString("X16");
                }

                return this.pointer.ToString("X16") + "(" + codeStart.ToString() + ")";
            }
 /// <summary>
 /// Patches the call site with whatever instructions are in code start.
 /// </summary>
 /// <param name="callSite">The call site.</param>
 /// <param name="codeStart">The call info.</param>
 private void PatchCallSiteWithCodeStart(IntPtr callSite, CodeStart codeStart)
 {
     codeStart.PatchCallSite(callSite);
 }