diff --git a/src/SixLabors.Core/Helpers/DebugGuard.cs b/src/SixLabors.Core/Helpers/DebugGuard.cs
new file mode 100644
index 000000000..f20a763aa
--- /dev/null
+++ b/src/SixLabors.Core/Helpers/DebugGuard.cs
@@ -0,0 +1,201 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Diagnostics;
+
+namespace SixLabors
+{
+ ///
+ /// Provides methods to protect against invalid parameters for a DEBUG build.
+ ///
+ [DebuggerStepThrough]
+ internal static class DebugGuard
+ {
+ ///
+ /// Verifies, that the method parameter with specified object value is not null
+ /// and throws an exception if it is found to be so.
+ ///
+ /// The target object, which cannot be null.
+ /// The name of the parameter that is to be checked.
+ /// is null
+ [Conditional("DEBUG")]
+ public static void NotNull(object target, string parameterName)
+ {
+ if (target == null)
+ {
+ throw new ArgumentNullException(parameterName);
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is less than a maximum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The maximum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is greater than the maximum value.
+ ///
+ [Conditional("DEBUG")]
+ public static void MustBeLessThan(TValue value, TValue max, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(max) >= 0)
+ {
+ throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than {max}.");
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is less than or equal to a maximum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The maximum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is greater than the maximum value.
+ ///
+ [Conditional("DEBUG")]
+ public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(max) > 0)
+ {
+ throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than or equal to {max}.");
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is greater than a minimum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The minimum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is less than the minimum value.
+ ///
+ [Conditional("DEBUG")]
+ public static void MustBeGreaterThan(TValue value, TValue min, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(min) <= 0)
+ {
+ throw new ArgumentOutOfRangeException(
+ parameterName,
+ $"Value must be greater than {min}.");
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is greater than or equal to a minimum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The minimum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is less than the minimum value.
+ ///
+ [Conditional("DEBUG")]
+ public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(min) < 0)
+ {
+ throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min}.");
+ }
+ }
+
+ ///
+ /// Verifies, that the method parameter with specified target value is true
+ /// and throws an exception if it is found to be so.
+ ///
+ ///
+ /// The target value, which cannot be false.
+ ///
+ ///
+ /// The name of the parameter that is to be checked.
+ ///
+ ///
+ /// The error message, if any to add to the exception.
+ ///
+ ///
+ /// is false
+ ///
+ [Conditional("DEBUG")]
+ public static void IsTrue(bool target, string parameterName, string message)
+ {
+ if (!target)
+ {
+ throw new ArgumentException(message, parameterName);
+ }
+ }
+
+ ///
+ /// Verifies, that the method parameter with specified target value is false
+ /// and throws an exception if it is found to be so.
+ ///
+ /// The target value, which cannot be true.
+ /// The name of the parameter that is to be checked.
+ /// The error message, if any to add to the exception.
+ ///
+ /// is true
+ ///
+ [Conditional("DEBUG")]
+ public static void IsFalse(bool target, string parameterName, string message)
+ {
+ if (target)
+ {
+ throw new ArgumentException(message, parameterName);
+ }
+ }
+
+ ///
+ /// Verifies, that the target span is of same size than the 'other' span.
+ ///
+ /// The element type of the spans
+ /// The target span.
+ /// The 'other' span to compare 'target' to.
+ /// The name of the parameter that is to be checked.
+ ///
+ /// is true
+ ///
+ [Conditional("DEBUG")]
+ public static void MustBeSameSized(Span target, Span other, string parameterName)
+ where T : struct
+ {
+ if (target.Length != other.Length)
+ {
+ throw new ArgumentException("Span-s must be the same size!", parameterName);
+ }
+ }
+
+ ///
+ /// Verifies, that the `target` span has the length of 'minSpan', or longer.
+ ///
+ /// The element type of the spans
+ /// The target span.
+ /// The 'minSpan' span to compare 'target' to.
+ /// The name of the parameter that is to be checked.
+ ///
+ /// is true
+ ///
+ [Conditional("DEBUG")]
+ public static void MustBeSizedAtLeast(Span target, Span minSpan, string parameterName)
+ where T : struct
+ {
+ if (target.Length < minSpan.Length)
+ {
+ throw new ArgumentException($"Span-s must be at least of length {minSpan.Length}!", parameterName);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SixLabors.Core/Helpers/Guard.cs b/src/SixLabors.Core/Helpers/Guard.cs
new file mode 100644
index 000000000..990187772
--- /dev/null
+++ b/src/SixLabors.Core/Helpers/Guard.cs
@@ -0,0 +1,250 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+
+namespace SixLabors
+{
+ ///
+ /// Provides methods to protect against invalid parameters.
+ ///
+ [DebuggerStepThrough]
+ internal static class Guard
+ {
+ ///
+ /// Verifies, that the method parameter with specified object value is not null
+ /// and throws an exception if it is found to be so.
+ ///
+ /// The target object, which cannot be null.
+ /// The name of the parameter that is to be checked.
+ /// The error message, if any to add to the exception.
+ /// is null
+ public static void NotNull(object target, string parameterName, string message = "")
+ {
+ if (target == null)
+ {
+ if (!string.IsNullOrWhiteSpace(message))
+ {
+ throw new ArgumentNullException(parameterName, message);
+ }
+
+ throw new ArgumentNullException(parameterName);
+ }
+ }
+
+ ///
+ /// Verifies, that the string method parameter with specified object value and message
+ /// is not null, not empty and does not contain only blanks and throws an exception
+ /// if the object is null.
+ ///
+ /// The target string, which should be checked against being null or empty.
+ /// Name of the parameter.
+ /// The error message, if any to add to the exception.
+ /// is null.
+ /// is empty or contains only blanks.
+ public static void NotNullOrEmpty(string target, string parameterName, string message = "")
+ {
+ NotNull(target, parameterName, message);
+
+ if (string.IsNullOrWhiteSpace(target))
+ {
+ if (!string.IsNullOrWhiteSpace(message))
+ {
+ throw new ArgumentException(message, parameterName);
+ }
+
+ throw new ArgumentException("Value cannot be null or empty and cannot contain only blanks.", parameterName);
+ }
+ }
+
+ ///
+ /// Verifies, that the enumeration is not null and not empty.
+ ///
+ /// The type of objects in the
+ /// The target enumeration, which should be checked against being null or empty.
+ /// Name of the parameter.
+ /// The error message, if any to add to the exception.
+ /// is null.
+ /// is empty.
+ public static void NotNullOrEmpty(IEnumerable target, string parameterName, string message = "")
+ {
+ NotNull(target, parameterName, message);
+
+ if (!target.Any())
+ {
+ if (!string.IsNullOrWhiteSpace(message))
+ {
+ throw new ArgumentException(message, parameterName);
+ }
+
+ throw new ArgumentException("Value cannot be empty.", parameterName);
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is less than a maximum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The maximum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is greater than the maximum value.
+ ///
+ public static void MustBeLessThan(TValue value, TValue max, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(max) >= 0)
+ {
+ throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than {max}.");
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is less than or equal to a maximum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The maximum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is greater than the maximum value.
+ ///
+ public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(max) > 0)
+ {
+ throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than or equal to {max}.");
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is greater than a minimum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The minimum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is less than the minimum value.
+ ///
+ public static void MustBeGreaterThan(TValue value, TValue min, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(min) <= 0)
+ {
+ throw new ArgumentOutOfRangeException(
+ parameterName,
+ $"Value must be greater than {min}.");
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is greater than or equal to a minimum value
+ /// and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The minimum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is less than the minimum value.
+ ///
+ public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(min) < 0)
+ {
+ throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min}.");
+ }
+ }
+
+ ///
+ /// Verifies that the specified value is greater than or equal to a minimum value and less than
+ /// or equal to a maximum value and throws an exception if it is not.
+ ///
+ /// The target value, which should be validated.
+ /// The minimum value.
+ /// The maximum value.
+ /// The name of the parameter that is to be checked.
+ /// The type of the value.
+ ///
+ /// is less than the minimum value of greater than the maximum value.
+ ///
+ public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName)
+ where TValue : IComparable
+ {
+ if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0)
+ {
+ throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min} and less than or equal to {max}.");
+ }
+ }
+
+ ///
+ /// Verifies, that the method parameter with specified target value is true
+ /// and throws an exception if it is found to be so.
+ ///
+ ///
+ /// The target value, which cannot be false.
+ ///
+ ///
+ /// The name of the parameter that is to be checked.
+ ///
+ ///
+ /// The error message, if any to add to the exception.
+ ///
+ ///
+ /// is false
+ ///
+ public static void IsTrue(bool target, string parameterName, string message)
+ {
+ if (!target)
+ {
+ throw new ArgumentException(message, parameterName);
+ }
+ }
+
+ ///
+ /// Verifies, that the method parameter with specified target value is false
+ /// and throws an exception if it is found to be so.
+ ///
+ /// The target value, which cannot be true.
+ /// The name of the parameter that is to be checked.
+ /// The error message, if any to add to the exception.
+ ///
+ /// is true
+ ///
+ public static void IsFalse(bool target, string parameterName, string message)
+ {
+ if (target)
+ {
+ throw new ArgumentException(message, parameterName);
+ }
+ }
+
+ ///
+ /// Verifies, that the `target` span has the length of 'minSpan', or longer.
+ ///
+ /// The element type of the spans
+ /// The target span.
+ /// The minimum length.
+ /// The name of the parameter that is to be checked.
+ ///
+ /// is true
+ ///
+ public static void MustBeSizedAtLeast(Span target, int minLength, string parameterName)
+ {
+ if (target.Length < minLength)
+ {
+ throw new ArgumentException($"Span-s must be at least of length {minLength}!", parameterName);
+ }
+ }
+ }
+}
diff --git a/src/SixLabors.Core/Properties/AssemblyInfo.cs b/src/SixLabors.Core/Properties/AssemblyInfo.cs
index b24029bb0..559a161d5 100644
--- a/src/SixLabors.Core/Properties/AssemblyInfo.cs
+++ b/src/SixLabors.Core/Properties/AssemblyInfo.cs
@@ -34,3 +34,9 @@ using System.Runtime.CompilerServices;
// Ensure the internals can be tested.
[assembly: InternalsVisibleTo("SixLabors.Core.Tests")]
+
+// Ensure the internals are visible to the other projects.
+[assembly: InternalsVisibleTo("SixLabors.Exif")]
+[assembly: InternalsVisibleTo("SixLabors.Fonts")]
+[assembly: InternalsVisibleTo("SixLabors.ImageSharp")]
+[assembly: InternalsVisibleTo("SixLabors.Shapes")]
diff --git a/src/SixLabors.Core/SixLabors.Core.csproj b/src/SixLabors.Core/SixLabors.Core.csproj
index c479c3cc1..57422a9c1 100644
--- a/src/SixLabors.Core/SixLabors.Core.csproj
+++ b/src/SixLabors.Core/SixLabors.Core.csproj
@@ -44,6 +44,7 @@
All
+
\ No newline at end of file