Ver código fonte

Refactor to simplify

Tig 1 ano atrás
pai
commit
dabb106c0e

+ 194 - 150
Terminal.Gui/Drawing/Aligner.cs

@@ -12,6 +12,11 @@ public class Aligner : INotifyPropertyChanged
     /// <summary>
     ///     Gets or sets how the <see cref="Aligner"/> aligns items within a container.
     /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         <see cref="AlignmentMode"/> provides additional options for aligning items in a container.
+    ///     </para>
+    /// </remarks>
     public Alignment Alignment
     {
         get => _alignment;
@@ -22,40 +27,33 @@ public class Aligner : INotifyPropertyChanged
         }
     }
 
-    private int _containerSize;
+    private AlignmentModes _alignmentMode = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems;
 
     /// <summary>
-    ///     The size of the container.
+    ///     Gets or sets the modes controlling <see cref="Alignment"/>.
     /// </summary>
-    public int ContainerSize
+    public AlignmentModes AlignmentMode
     {
-        get => _containerSize;
+        get => _alignmentMode;
         set
         {
-            _containerSize = value;
-            PropertyChanged?.Invoke (this, new (nameof (ContainerSize)));
+            _alignmentMode = value;
+            PropertyChanged?.Invoke (this, new (nameof (AlignmentMode)));
         }
     }
 
-    private bool _spaceBetweenItems;
+    private int _containerSize;
 
     /// <summary>
-    ///     Gets or sets whether <see cref="Aligner"/> adds at least one space between items. Default is
-    ///     <see langword="false"/>.
+    ///     The size of the container.
     /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         If the total size of the items is greater than the container size, the space between items will be ignored
-    ///         starting from the right or bottom.
-    ///     </para>
-    /// </remarks>
-    public bool SpaceBetweenItems
+    public int ContainerSize
     {
-        get => _spaceBetweenItems;
+        get => _containerSize;
         set
         {
-            _spaceBetweenItems = value;
-            PropertyChanged?.Invoke (this, new (nameof (SpaceBetweenItems)));
+            _containerSize = value;
+            PropertyChanged?.Invoke (this, new (nameof (ContainerSize)));
         }
     }
 
@@ -64,43 +62,34 @@ public class Aligner : INotifyPropertyChanged
 
     /// <summary>
     ///     Takes a list of item sizes and returns a list of the positions of those items when aligned within <see name="ContainerSize"/>
-    ///     using the <see cref="Alignment"/> and <see cref="SpaceBetweenItems"/> settings.
+    ///     using the <see cref="Alignment"/> and <see cref="AlignmentMode"/> settings.
     /// </summary>
     /// <param name="sizes">The sizes of the items to align.</param>
     /// <returns>The locations of the items, from left/top to right/bottom.</returns>
-    public int [] Align (int [] sizes) { return Align (Alignment, SpaceBetweenItems, ContainerSize, sizes); }
+    public int [] Align (int [] sizes) { return Align (Alignment, AlignmentMode, ContainerSize, sizes); }
 
     /// <summary>
     ///     Takes a list of item sizes and returns a list of the  positions of those items when aligned within <paramref name="containerSize"/>
     ///     using specified parameters.
     /// </summary>
-    /// <param name="sizes">The sizes of the items to align.</param>
     /// <param name="alignment">Specifies how the items will be aligned.</param>
-    /// <param name="spaceBetweenItems">
-    ///     <para>
-    ///         Indicates whether at least one space should be added between items.
-    ///     </para>
-    ///     <para>
-    ///         If the total size of the items is greater than the container size, the space between items will be ignored
-    ///         starting from the right or bottom.
-    ///     </para>
-    /// </param>
+    /// <param name="alignmentMode"></param>
     /// <param name="containerSize">The size of the container.</param>
+    /// <param name="sizes">The sizes of the items to align.</param>
     /// <returns>The positions of the items, from left/top to right/bottom.</returns>
-    public static int [] Align (Alignment alignment, bool spaceBetweenItems, int containerSize, int [] sizes)
+    public static int [] Align (in Alignment alignment, in AlignmentModes alignmentMode, int containerSize, int [] sizes)
     {
         if (sizes.Length == 0)
         {
             return new int [] { };
         }
 
-        int maxSpaceBetweenItems = spaceBetweenItems ? 1 : 0;
+        int maxSpaceBetweenItems = alignmentMode.HasFlag (AlignmentModes.AddSpaceBetweenItems) ? 1 : 0;
 
         var positions = new int [sizes.Length]; // positions of the items. the return value.
         int totalItemsSize = sizes.Sum ();
         int totalGaps = sizes.Length - 1; // total gaps between items
         int totalItemsAndSpaces = totalItemsSize + totalGaps * maxSpaceBetweenItems; // total size of items and spaces if we had enough room
-
         int spaces = totalGaps * maxSpaceBetweenItems; // We'll decrement this below to place one space between each item until we run out
 
         if (totalItemsSize >= containerSize)
@@ -112,167 +101,222 @@ public class Aligner : INotifyPropertyChanged
             spaces = containerSize - totalItemsSize;
         }
 
+        var currentPosition = 0;
+
         switch (alignment)
         {
             case Alignment.Start:
-                var currentPosition = 0;
-
-                for (var i = 0; i < sizes.Length; i++)
+                switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
                 {
-                    CheckSizeCannotBeNegative (i, sizes);
+                    case AlignmentModes.StartToEnd:
+                        Start (sizes, positions, ref spaces, maxSpaceBetweenItems);
 
-                    if (i == 0)
-                    {
-                        positions [0] = 0; // first item position
+                        break;
 
-                        continue;
-                    }
+                    case AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast:
+                        IgnoreLast (sizes, containerSize, positions, maxSpaceBetweenItems, totalItemsSize, spaces, currentPosition);
 
-                    int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+                        break;
+
+                    case AlignmentModes.EndToStart:
+                    case AlignmentModes.EndToStart | AlignmentModes.IgnoreFirstOrLast:
+                        throw new NotImplementedException ("EndToStart is not implemented.");
 
-                    // subsequent items are placed one space after the previous item
-                    positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
+                        break;
                 }
 
                 break;
 
             case Alignment.End:
-                currentPosition = containerSize - totalItemsSize - spaces;
-
-                for (var i = 0; i < sizes.Length; i++)
+                switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
                 {
-                    CheckSizeCannotBeNegative (i, sizes);
-                    int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+                    case AlignmentModes.StartToEnd:
+                        End (containerSize, sizes, totalItemsSize, spaces, maxSpaceBetweenItems, positions);
+
+                        break;
+
+                    case AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast:
+                        IgnoreFirst (sizes, containerSize, positions, maxSpaceBetweenItems, totalItemsSize, spaces, currentPosition);
+
+                        break;
+
+                    case AlignmentModes.EndToStart:
+                    case AlignmentModes.EndToStart | AlignmentModes.IgnoreFirstOrLast:
+                        throw new NotImplementedException ("EndToStart is not implemented.");
+
+                        break;
 
-                    positions [i] = currentPosition;
-                    currentPosition += sizes [i] + spaceBefore;
                 }
 
                 break;
 
             case Alignment.Center:
-                if (sizes.Length > 1)
-                {
-                    // remaining space to be distributed before first and after the items
-                    int remainingSpace = Math.Max (0, containerSize - totalItemsSize - spaces);
+                Center (containerSize, sizes, totalItemsSize, spaces, positions, maxSpaceBetweenItems);
 
-                    for (var i = 0; i < sizes.Length; i++)
-                    {
-                        CheckSizeCannotBeNegative (i, sizes);
+                break;
 
-                        if (i == 0)
-                        {
-                            positions [i] = remainingSpace / 2; // first item position
+            case Alignment.Fill:
+                Fill (containerSize, sizes, totalItemsSize, positions);
 
-                            continue;
-                        }
+                break;
 
-                        int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+            default:
+                throw new ArgumentOutOfRangeException (nameof (alignment), alignment, null);
+        }
 
-                        // subsequent items are placed one space after the previous item
-                        positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
-                    }
-                }
-                else if (sizes.Length == 1)
-                {
-                    CheckSizeCannotBeNegative (0, sizes);
-                    positions [0] = (containerSize - sizes [0]) / 2; // single item is centered
-                }
+        return positions;
+    }
 
-                break;
+    private static void Start (int [] sizes, int [] positions, ref int spaces, int maxSpaceBetweenItems)
+    {
+        for (var i = 0; i < sizes.Length; i++)
+        {
+            CheckSizeCannotBeNegative (i, sizes);
 
-            case Alignment.Fill:
-                int spaceBetween = sizes.Length > 1 ? (containerSize - totalItemsSize) / (sizes.Length - 1) : 0;
-                int remainder = sizes.Length > 1 ? (containerSize - totalItemsSize) % (sizes.Length - 1) : 0;
-                currentPosition = 0;
+            if (i == 0)
+            {
+                positions [0] = 0; // first item position
 
-                for (var i = 0; i < sizes.Length; i++)
-                {
-                    CheckSizeCannotBeNegative (i, sizes);
-                    positions [i] = currentPosition;
-                    int extraSpace = i < remainder ? 1 : 0;
-                    currentPosition += sizes [i] + spaceBetween + extraSpace;
-                }
+                continue;
+            }
 
-                break;
+            int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
 
-            // 111 2222        33333
-            case Alignment.LastEndRestStart:
-                if (sizes.Length > 1)
+            // subsequent items are placed one space after the previous item
+            positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
+        }
+    }
+
+    private static void IgnoreFirst (int [] sizes, int containerSize, int [] positions, int maxSpaceBetweenItems, int totalItemsSize, int spaces, int currentPosition)
+    {
+        if (sizes.Length > 1)
+        {
+            currentPosition = 0;
+            positions [0] = currentPosition; // first item is flush left
+
+            for (int i = sizes.Length - 1; i >= 0; i--)
+            {
+                CheckSizeCannotBeNegative (i, sizes);
+
+                if (i == sizes.Length - 1)
                 {
-                    if (totalItemsSize > containerSize)
-                    {
-                        currentPosition = containerSize - totalItemsSize - spaces;
-                    }
-                    else
-                    {
-                        currentPosition = 0;
-                    }
-
-                    for (var i = 0; i < sizes.Length; i++)
-                    {
-                        CheckSizeCannotBeNegative (i, sizes);
-
-                        if (i < sizes.Length - 1)
-                        {
-                            int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
-
-                            positions [i] = currentPosition;
-                            currentPosition += sizes [i] + spaceBefore;
-                        }
-                    }
-
-                    positions [sizes.Length - 1] = containerSize - sizes [^1];
+                    // start at right
+                    currentPosition = Math.Max (totalItemsSize, containerSize) - sizes [i];
+                    positions [i] = currentPosition;
                 }
-                else if (sizes.Length == 1)
+
+                if (i < sizes.Length - 1 && i > 0)
                 {
-                    CheckSizeCannotBeNegative (0, sizes);
+                    int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
 
-                    positions [0] = containerSize - sizes [0]; // single item is flush right
+                    positions [i] = currentPosition - sizes [i] - spaceBefore;
+                    currentPosition = positions [i];
                 }
+            }
+        }
+        else if (sizes.Length == 1)
+        {
+            CheckSizeCannotBeNegative (0, sizes);
+            positions [0] = 0; // single item is flush left
+        }
+    }
 
-                break;
+    private static void IgnoreLast (int [] sizes, int containerSize, int [] positions, int maxSpaceBetweenItems, int totalItemsSize, int spaces, int currentPosition)
+    {
+        if (sizes.Length > 1)
+        {
+            if (totalItemsSize > containerSize)
+            {
+                currentPosition = containerSize - totalItemsSize - spaces;
+            }
+            else
+            {
+                currentPosition = 0;
+            }
+
+            for (var i = 0; i < sizes.Length; i++)
+            {
+                CheckSizeCannotBeNegative (i, sizes);
 
-            // 111        2222 33333
-            case Alignment.FirstStartRestEnd:
-                if (sizes.Length > 1)
+                if (i < sizes.Length - 1)
                 {
-                    currentPosition = 0;
-                    positions [0] = currentPosition; // first item is flush left
-
-                    for (int i = sizes.Length - 1; i >= 0; i--)
-                    {
-                        CheckSizeCannotBeNegative (i, sizes);
-
-                        if (i == sizes.Length - 1)
-                        {
-                            // start at right
-                            currentPosition = Math.Max (totalItemsSize, containerSize) - sizes [i];
-                            positions [i] = currentPosition;
-                        }
-
-                        if (i < sizes.Length - 1 && i > 0)
-                        {
-                            int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
-
-                            positions [i] = currentPosition - sizes [i] - spaceBefore;
-                            currentPosition = positions [i];
-                        }
-                    }
+                    int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+
+                    positions [i] = currentPosition;
+                    currentPosition += sizes [i] + spaceBefore;
                 }
-                else if (sizes.Length == 1)
+            }
+
+            positions [sizes.Length - 1] = containerSize - sizes [^1];
+        }
+        else if (sizes.Length == 1)
+        {
+            CheckSizeCannotBeNegative (0, sizes);
+
+            positions [0] = containerSize - sizes [0]; // single item is flush right
+        }
+    }
+
+    private static void Fill (int containerSize, int [] sizes, int totalItemsSize, int [] positions)
+    {
+        int currentPosition;
+        int spaceBetween = sizes.Length > 1 ? (containerSize - totalItemsSize) / (sizes.Length - 1) : 0;
+        int remainder = sizes.Length > 1 ? (containerSize - totalItemsSize) % (sizes.Length - 1) : 0;
+        currentPosition = 0;
+
+        for (var i = 0; i < sizes.Length; i++)
+        {
+            CheckSizeCannotBeNegative (i, sizes);
+            positions [i] = currentPosition;
+            int extraSpace = i < remainder ? 1 : 0;
+            currentPosition += sizes [i] + spaceBetween + extraSpace;
+        }
+    }
+
+    private static void Center (int containerSize, int [] sizes, int totalItemsSize, int spaces, int [] positions, int maxSpaceBetweenItems)
+    {
+        if (sizes.Length > 1)
+        {
+            // remaining space to be distributed before first and after the items
+            int remainingSpace = Math.Max (0, containerSize - totalItemsSize - spaces);
+
+            for (var i = 0; i < sizes.Length; i++)
+            {
+                CheckSizeCannotBeNegative (i, sizes);
+
+                if (i == 0)
                 {
-                    CheckSizeCannotBeNegative (0, sizes);
-                    positions [0] = 0; // single item is flush left
+                    positions [i] = remainingSpace / 2; // first item position
+
+                    continue;
                 }
 
-                break;
+                int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
 
-            default:
-                throw new ArgumentOutOfRangeException (nameof (alignment), alignment, null);
+                // subsequent items are placed one space after the previous item
+                positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
+            }
+        }
+        else if (sizes.Length == 1)
+        {
+            CheckSizeCannotBeNegative (0, sizes);
+            positions [0] = (containerSize - sizes [0]) / 2; // single item is centered
         }
+    }
 
-        return positions;
+    private static void End (int containerSize, int [] sizes, int totalItemsSize, int spaces, int maxSpaceBetweenItems, int [] positions)
+    {
+        int currentPosition;
+        currentPosition = containerSize - totalItemsSize - spaces;
+
+        for (var i = 0; i < sizes.Length; i++)
+        {
+            CheckSizeCannotBeNegative (i, sizes);
+            int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+
+            positions [i] = currentPosition;
+            currentPosition += sizes [i] + spaceBefore;
+        }
     }
 
     private static void CheckSizeCannotBeNegative (int i, int [] sizes)

+ 6 - 32
Terminal.Gui/Drawing/Alignment.cs

@@ -13,6 +13,9 @@ public enum Alignment
     ///         If the container is smaller than the total size of the items, the end items will be clipped (their locations
     ///         will be greater than the container size).
     ///     </para>
+    ///     <para>
+    ///         The <see cref="AlignmentModes"/> enumeration provides additional options for aligning items in a container.
+    ///     </para>
     /// </remarks>
     /// <example>
     ///     <c>
@@ -29,6 +32,9 @@ public enum Alignment
     ///         If the container is smaller than the total size of the items, the start items will be clipped (their locations
     ///         will be negative).
     ///     </para>
+    ///     <para>
+    ///         The <see cref="AlignmentModes"/> enumeration provides additional options for aligning items in a container.
+    ///     </para>
     /// </remarks>
     /// <example>
     ///     <c>
@@ -69,36 +75,4 @@ public enum Alignment
     ///     </c>
     /// </example>
     Fill,
-
-    /// <summary>
-    ///     The first item will be aligned to the start and the remaining will aligned to the end.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         If the container is smaller than the total size of the items, the end items will be clipped (their locations
-    ///         will be greater than the container size).
-    ///     </para>
-    /// </remarks>
-    /// <example>
-    ///     <c>
-    ///         |111     2222 33333|
-    ///     </c>
-    /// </example>
-    FirstStartRestEnd,
-
-    /// <summary>
-    ///     The last item will be aligned to the end and the remaining will aligned to the start.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         If the container is smaller than the total size of the items, the start items will be clipped (their locations
-    ///         will be negative).
-    ///     </para>
-    /// </remarks>
-    /// <example>
-    ///     <c>
-    ///         |111 2222      33333|
-    ///     </c>
-    /// </example>
-    LastEndRestStart
 }

+ 49 - 0
Terminal.Gui/Drawing/AlignmentModes.cs

@@ -0,0 +1,49 @@
+namespace Terminal.Gui;
+
+/// <summary>
+///     Determines alignment modes for <see cref="Alignment"/>.
+/// </summary>
+[Flags]
+public enum AlignmentModes
+{
+    /// <summary>
+    ///     The items will be arranged from start (left/top) to end (right/bottom).
+    /// </summary>
+    StartToEnd = 0,
+
+    /// <summary>
+    ///     The items will be arranged from end (right/bottom) to start (left/top).
+    /// </summary>
+    /// <remarks>
+    ///     Not implemented.
+    /// </remarks>
+    EndToStart = 1,
+
+    /// <summary>
+    ///     At least one space will be added between items. Useful for justifying text where at least one space is needed.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         If the total size of the items is greater than the container size, the space between items will be ignored
+    ///         starting from the end.
+    ///     </para>
+    /// </remarks>
+    AddSpaceBetweenItems = 2,
+
+    /// <summary>
+    ///    When aligning via <see cref="Alignment.Start"/> or <see cref="Alignment.End"/>, the item opposite to the alignment (the first or last item) will be ignored.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         If the container is smaller than the total size of the items, the end items will be clipped (their locations
+    ///         will be greater than the container size).
+    ///     </para>
+    /// </remarks>
+    /// <example>
+    ///     <c>
+    ///         Start: |111 2222     33333|
+    ///         End:   |111     2222 33333|
+    ///     </c>
+    /// </example>
+    IgnoreFirstOrLast = 4,
+}

+ 0 - 31
Terminal.Gui/Drawing/FlowModes.cs

@@ -1,31 +0,0 @@
-namespace Terminal.Gui;
-
-/// <summary>
-///     Determines how items will be arranged in a container when alignment is <see cref="Alignment.Start"/> or <see cref="Alignment.End"/>,
-/// </summary>
-[Flags]
-public enum FlowModes
-{
-    /// <summary>
-    ///     The items will be arranged from start (left/top) to end (right/bottom).
-    /// </summary>
-    StartToEnd = 0,
-
-    /// <summary>
-    ///     The items will be arranged from end (right/bottom) to start (left/top).
-    /// </summary>
-    /// <remarks>
-    ///     Not implemented.
-    /// </remarks>
-    EndToStart = 1,
-
-    /// <summary>
-    ///    When aligning via <see cref="Alignment.Start"/> or <see cref="Alignment.End"/>, the first item will be aligned at the opposite end.
-    /// </summary>
-    IgnoreFirst = 2,
-
-    /// <summary>
-    ///    When aligning via <see cref="Alignment.Start"/> or <see cref="Alignment.End"/>, the last item will be aligned at the opposite end.
-    /// </summary>
-    IgnoreLast = 4,
-}

+ 6 - 2
Terminal.Gui/View/Layout/Pos.cs

@@ -144,13 +144,17 @@ public abstract class Pos
     /// <summary>
     ///     Creates a <see cref="Pos"/> object that aligns a set of views according to the specified alignment setting.
     /// </summary>
-    /// <param name="alignment"></param>
+    /// <param name="alignment">The alignment.</param>
+    /// <param name="mode">The optional alignment modes.</param>
     /// <param name="groupId">
     ///     The optional, unique identifier for the set of views to align according to
     ///     <paramref name="alignment"/>.
     /// </param>
     /// <returns></returns>
-    public static Pos Align (Alignment alignment, int groupId = 0) { return new PosAlign (alignment, groupId); }
+    public static Pos Align (Alignment alignment, AlignmentModes mode = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, int groupId = 0)
+    {
+        return new PosAlign (alignment, mode, groupId);
+    }
 
     /// <summary>
     ///     Creates a <see cref="Pos"/> object that is anchored to the end (right side or

+ 3 - 2
Terminal.Gui/View/Layout/PosAlign.cs

@@ -108,11 +108,12 @@ public class PosAlign : Pos
     ///     Enables alignment of a set of views.
     /// </summary>
     /// <param name="alignment"></param>
+    /// <param name="mode"></param>
     /// <param name="groupId">The unique identifier for the set of views to align according to <paramref name="alignment"/>.</param>
-    public PosAlign (Alignment alignment, int groupId = 0)
+    public PosAlign (Alignment alignment, AlignmentModes mode = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, int groupId = 0)
     {
-        Aligner.SpaceBetweenItems = true;
         Aligner.Alignment = alignment;
+        Aligner.AlignmentMode = mode;
         _groupId = groupId;
         Aligner.PropertyChanged += Aligner_PropertyChanged;
     }

+ 2 - 2
Terminal.Gui/Views/Wizard/Wizard.cs

@@ -66,8 +66,8 @@ public class Wizard : Dialog
     /// </remarks>
     public Wizard ()
     {
-        // TODO: LastRightRestLeft will enable a "Quit" button to always appear at the far left
-        ButtonAlignment = Alignment.LastEndRestStart;
+        // TODO: LastEndRestStart will enable a "Quit" button to always appear at the far left
+       // ButtonAlignment = Alignment.LastEndRestStart;
         BorderStyle = LineStyle.Double;
 
         //// Add a horiz separator

+ 1 - 0
Terminal.sln.DotSettings

@@ -391,6 +391,7 @@
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=53eecf85_002Dd821_002D40e8_002Dac97_002Dfdb734542b84/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=70345118_002D4b40_002D4ece_002D937c_002Dbbeb7a0b2e70/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=c873eafb_002Dd57f_002D481d_002D8c93_002D77f6863c2f88/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
+	<s:String x:Key="/Default/Environment/InlayHints/GeneralInlayHintsOptions/DefaultMode/@EntryValue">PushToShowHints</s:String>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>

+ 1 - 1
UICatalog/Scenarios/Buttons.cs

@@ -218,7 +218,7 @@ public class Buttons : Scenario
             X = 4,
             Y = Pos.Bottom (label) + 1,
             SelectedItem = 2,
-            RadioLabels = new [] { "Left", "Right", "Centered", "Justified" }
+            RadioLabels = new [] { "Start", "End", "Center", "Fill" }
         };
         main.Add (radioGroup);
 

+ 1 - 1
UICatalog/Scenarios/Dialogs.cs

@@ -146,7 +146,7 @@ public class Dialogs : Scenario
         };
         frame.Add (label);
 
-        var labels = new [] { "Left", "Centered", "Right", "Justified", "FirstLeftRestRight", "LastRightRestLeft" };
+        var labels = new [] { "Start", "End", "Center", "Fill", "FirstStartRestEnd", "LastEndRestStart" };
         var alignmentGroup = new RadioGroup
         {
             X = Pos.Right (label) + 1,

+ 164 - 232
UICatalog/Scenarios/PosAlignDemo.cs

@@ -25,11 +25,11 @@ public sealed class PosAlignDemo : Scenario
             Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()} - {GetDescription ()}"
         };
 
-        SetupHorizontalControls (appWindow);
+        SetupControls (appWindow, Dimension.Width, Colors.ColorSchemes ["Toplevel"]);
 
-        SetupVerticalControls (appWindow);
+        SetupControls (appWindow, Dimension.Height, Colors.ColorSchemes ["Error"]);
 
-        Setup3by3Grid (appWindow);
+        //Setup3by3Grid (appWindow);
 
         // Run - Start the application.
         Application.Run (appWindow);
@@ -39,258 +39,189 @@ public sealed class PosAlignDemo : Scenario
         Application.Shutdown ();
     }
 
-    private void SetupHorizontalControls (Window appWindow)
+    private void SetupControls (Window appWindow, Dimension dimension, ColorScheme colorScheme)
     {
-        ColorScheme colorScheme = Colors.ColorSchemes ["Toplevel"];
-
         RadioGroup alignRadioGroup = new ()
         {
-            X = Pos.Align (_horizAligner.Alignment),
-            Y = Pos.Center (),
-            RadioLabels = new [] { "Start", "End", "Center", "Fill", "FirstLeftRestRight", "LastRightRestLeft" },
+            RadioLabels = Enum.GetNames<Alignment> (),
             ColorScheme = colorScheme
         };
 
-        alignRadioGroup.SelectedItemChanged += (s, e) =>
-                                             {
-                                                 _horizAligner.Alignment =
-                                                     (Alignment)Enum.Parse (typeof (Alignment), alignRadioGroup.RadioLabels [alignRadioGroup.SelectedItem]);
-
-                                                 foreach (View view in appWindow.Subviews.Where (v => v.X is PosAlign))
-                                                 {
-                                                     if (view.X is PosAlign j)
-                                                     {
-                                                         var newJust = new PosAlign (_horizAligner.Alignment)
-                                                         {
-                                                             Aligner =
-                                                             {
-                                                                 SpaceBetweenItems = _horizAligner.SpaceBetweenItems
-                                                             }
-                                                         };
-                                                         view.X = newJust;
-                                                     }
-                                                 }
-                                             };
-        appWindow.Add (alignRadioGroup);
-
-        CheckBox putSpaces = new ()
+        if (dimension == Dimension.Width)
         {
-            X = Pos.Align (_horizAligner.Alignment),
-            Y = Pos.Top (alignRadioGroup),
-            ColorScheme = colorScheme,
-            Text = "Spaces",
-            Checked = true
-        };
+            alignRadioGroup.X = Pos.Align (_horizAligner.Alignment);
+            alignRadioGroup.Y = Pos.Center ();
+        }
+        else
+        {
+            alignRadioGroup.X = Pos.Center ();
+            alignRadioGroup.Y = Pos.Align (_vertAligner.Alignment);
+        }
 
-        putSpaces.Toggled += (s, e) =>
-                             {
-                                 _horizAligner.SpaceBetweenItems = e.NewValue is { } && e.NewValue.Value;
+        alignRadioGroup.SelectedItemChanged += (s, e) =>
+                                               {
+                                                   if (dimension == Dimension.Width)
+                                                   {
+                                                       _horizAligner.Alignment =
+                                                         (Alignment)Enum.Parse (typeof (Alignment), alignRadioGroup.RadioLabels [alignRadioGroup.SelectedItem]);
+                                                       UpdatePosAlignObjects (appWindow, dimension, _horizAligner);
+                                                   }
+                                                   else
+                                                   {
+                                                       _vertAligner.Alignment =
+                                                         (Alignment)Enum.Parse (typeof (Alignment), alignRadioGroup.RadioLabels [alignRadioGroup.SelectedItem]);
+                                                       UpdatePosAlignObjects (appWindow, dimension, _vertAligner);
+                                                   }
+
+                                               };
+        appWindow.Add (alignRadioGroup);
 
-                                 foreach (View view in appWindow.Subviews.Where (v => v.X is PosAlign))
-                                 {
-                                     if (view.X is PosAlign j)
-                                     {
-                                         j.Aligner.SpaceBetweenItems = _horizAligner.SpaceBetweenItems;
-                                     }
-                                 }
-                             };
-        appWindow.Add (putSpaces);
 
-        CheckBox margin = new ()
+        CheckBox ignoreFirstOrLast = new ()
         {
-            X = Pos.Left (putSpaces),
-            Y = Pos.Bottom (putSpaces),
             ColorScheme = colorScheme,
-            Text = "Margin"
+            Text = "IgnoreFirstOrLast",
         };
 
-        margin.Toggled += (s, e) =>
-                          {
-                              _leftMargin = e.NewValue is { } && e.NewValue.Value ? 1 : 0;
-
-                              foreach (View view in appWindow.Subviews.Where (v => v.X is PosAlign))
-                              {
-                                  // Skip the justification radio group
-                                  if (view != alignRadioGroup)
-                                  {
-                                      view.Margin.Thickness = new (_leftMargin, 0, 0, 0);
-                                  }
-                              }
-                          };
-        appWindow.Add (margin);
-
-        List<Button> addedViews =
-        [
-            new ()
-            {
-                X = Pos.Align (_horizAligner.Alignment),
-                Y = Pos.Center (),
-                Text = NumberToWords.Convert (0)
-            }
-        ];
+        if (dimension == Dimension.Width)
+        {
+            ignoreFirstOrLast.Checked = _horizAligner.AlignmentMode.HasFlag (AlignmentModes.IgnoreFirstOrLast);
+            ignoreFirstOrLast.X = Pos.Align (_horizAligner.Alignment);
+            ignoreFirstOrLast.Y = Pos.Top (alignRadioGroup);
+        }
+        else
+        {
+            ignoreFirstOrLast.Checked = _vertAligner.AlignmentMode.HasFlag (AlignmentModes.IgnoreFirstOrLast);
+            ignoreFirstOrLast.X = Pos.Left (alignRadioGroup);
+            ignoreFirstOrLast.Y = Pos.Align (_vertAligner.Alignment);
+        }
 
-        Buttons.NumericUpDown<int> addedViewsUpDown = new Buttons.NumericUpDown<int>
+        ignoreFirstOrLast.Toggled += (s, e) =>
+                               {
+                                   if (dimension == Dimension.Width)
+                                   {
+                                       _horizAligner.AlignmentMode = e.NewValue is { } &&
+                                                                 e.NewValue.Value ?
+                                                                     _horizAligner.AlignmentMode | AlignmentModes.IgnoreFirstOrLast :
+                                                                     _horizAligner.AlignmentMode & ~AlignmentModes.IgnoreFirstOrLast;
+                                       UpdatePosAlignObjects (appWindow, dimension, _horizAligner);
+                                   }
+                                   else
+                                   {
+                                       _vertAligner.AlignmentMode = e.NewValue is { } &&
+                                                                 e.NewValue.Value ?
+                                                                     _vertAligner.AlignmentMode | AlignmentModes.IgnoreFirstOrLast :
+                                                                     _vertAligner.AlignmentMode & ~AlignmentModes.IgnoreFirstOrLast;
+                                       UpdatePosAlignObjects (appWindow, dimension, _vertAligner);
+                                   }
+                               };
+        appWindow.Add (ignoreFirstOrLast);
+
+        CheckBox addSpacesBetweenItems = new ()
         {
-            X = Pos.Align (_horizAligner.Alignment),
-            Y = Pos.Top (alignRadioGroup),
-            Width = 9,
-            Title = "Added",
             ColorScheme = colorScheme,
-            BorderStyle = LineStyle.None,
-            Value = addedViews.Count
+            Text = "AddSpaceBetweenItems",
         };
-        addedViewsUpDown.Border.Thickness = new (0, 1, 0, 0);
-
-        addedViewsUpDown.ValueChanging += (s, e) =>
-                                          {
-                                              if (e.NewValue < 0)
-                                              {
-                                                  e.Cancel = true;
-
-                                                  return;
-                                              }
-
-                                              // Add or remove buttons
-                                              if (e.NewValue < e.OldValue)
-                                              {
-                                                  // Remove buttons
-                                                  for (int i = e.OldValue - 1; i >= e.NewValue; i--)
-                                                  {
-                                                      Button button = addedViews [i];
-                                                      appWindow.Remove (button);
-                                                      addedViews.RemoveAt (i);
-                                                      button.Dispose ();
-                                                  }
-                                              }
 
-                                              if (e.NewValue > e.OldValue)
-                                              {
-                                                  // Add buttons
-                                                  for (int i = e.OldValue; i < e.NewValue; i++)
-                                                  {
-                                                      var button = new Button
-                                                      {
-                                                          X = Pos.Align (_horizAligner.Alignment),
-                                                          Y = Pos.Center (),
-                                                          Text = NumberToWords.Convert (i + 1)
-                                                      };
-                                                      appWindow.Add (button);
-                                                      addedViews.Add (button);
-                                                  }
-                                              }
-                                          };
-        appWindow.Add (addedViewsUpDown);
-
-        appWindow.Add (addedViews [0]);
-    }
-
-    private void SetupVerticalControls (Window appWindow)
-    {
-        ColorScheme colorScheme = Colors.ColorSchemes ["Error"];
-
-        RadioGroup alignRadioGroup = new ()
+        if (dimension == Dimension.Width)
         {
-            X = 0,
-            Y = Pos.Align (_vertAligner.Alignment),
-            RadioLabels = new [] { "Start", "End", "Center", "Fill", "FirstStartRestEnd", "LastEndRestStart" },
-            ColorScheme = colorScheme
-        };
-
-        alignRadioGroup.SelectedItemChanged += (s, e) =>
-                                             {
-                                                 _vertAligner.Alignment =
-                                                     (Alignment)Enum.Parse (typeof (Alignment), alignRadioGroup.RadioLabels [alignRadioGroup.SelectedItem]);
-
-                                                 foreach (View view in appWindow.Subviews.Where (v => v.Y is PosAlign))
-                                                 {
-                                                     if (view.Y is PosAlign j)
-                                                     {
-                                                         var newJust = new PosAlign (_vertAligner.Alignment)
-                                                         {
-                                                             Aligner =
-                                                             {
-                                                                 SpaceBetweenItems = _vertAligner.SpaceBetweenItems
-                                                             }
-                                                         };
-                                                         view.Y = newJust;
-                                                     }
-                                                 }
-                                             };
-        appWindow.Add (alignRadioGroup);
-
-        CheckBox putSpaces = new ()
+            addSpacesBetweenItems.Checked = _horizAligner.AlignmentMode.HasFlag (AlignmentModes.AddSpaceBetweenItems);
+            addSpacesBetweenItems.X = Pos.Align (_horizAligner.Alignment);
+            addSpacesBetweenItems.Y = Pos.Top (alignRadioGroup);
+        }
+        else
         {
-            X = 0,
-            Y = Pos.Align (_vertAligner.Alignment),
-            ColorScheme = colorScheme,
-            Text = "Spaces",
-            Checked = true
-        };
+            addSpacesBetweenItems.Checked = _vertAligner.AlignmentMode.HasFlag (AlignmentModes.AddSpaceBetweenItems);
+            addSpacesBetweenItems.X = Pos.Left (alignRadioGroup);
+            addSpacesBetweenItems.Y = Pos.Align (_vertAligner.Alignment);
+        }
 
-        putSpaces.Toggled += (s, e) =>
+        addSpacesBetweenItems.Toggled += (s, e) =>
                              {
-                                 _vertAligner.SpaceBetweenItems = e.NewValue is { } && e.NewValue.Value;
-
-                                 foreach (View view in appWindow.Subviews.Where (v => v.Y is PosAlign))
+                                 if (dimension == Dimension.Width)
+                                 {
+                                     _horizAligner.AlignmentMode = e.NewValue is { } &&
+                                                             e.NewValue.Value ?
+                                                                 _horizAligner.AlignmentMode | AlignmentModes.AddSpaceBetweenItems :
+                                                                 _horizAligner.AlignmentMode & ~AlignmentModes.AddSpaceBetweenItems;
+                                     UpdatePosAlignObjects (appWindow, dimension, _horizAligner);
+                                 }
+                                 else
                                  {
-                                     if (view.Y is PosAlign j)
-                                     {
-                                         j.Aligner.SpaceBetweenItems = _vertAligner.SpaceBetweenItems;
-                                     }
+                                     _vertAligner.AlignmentMode = e.NewValue is { } &&
+                                                             e.NewValue.Value ?
+                                                                 _vertAligner.AlignmentMode | AlignmentModes.AddSpaceBetweenItems :
+                                                                 _vertAligner.AlignmentMode & ~AlignmentModes.AddSpaceBetweenItems;
+                                     UpdatePosAlignObjects (appWindow, dimension, _vertAligner);
                                  }
+
                              };
-        appWindow.Add (putSpaces);
+
+        appWindow.Add (addSpacesBetweenItems);
 
         CheckBox margin = new ()
         {
-            X = Pos.Right (putSpaces) + 1,
-            Y = Pos.Top (putSpaces),
             ColorScheme = colorScheme,
             Text = "Margin"
         };
 
+        if (dimension == Dimension.Width)
+        {
+            margin.X = Pos.Align (_horizAligner.Alignment);
+            margin.Y = Pos.Top (alignRadioGroup);
+        }
+        else
+        {
+            margin.X = Pos.Left (addSpacesBetweenItems);
+            margin.Y = Pos.Align (_vertAligner.Alignment);
+        }
+
         margin.Toggled += (s, e) =>
                           {
-                              _topMargin = e.NewValue is { } && e.NewValue.Value ? 1 : 0;
-
-                              foreach (View view in appWindow.Subviews.Where (v => v.Y is PosAlign))
+                              if (dimension == Dimension.Width)
                               {
-                                  // Skip the justification radio group
-                                  if (view != alignRadioGroup)
-                                  {
-                                      // BUGBUG: This is a hack to work around #3469
-                                      if (view is CheckBox)
-                                      {
-                                          view.Height = 1 + _topMargin;
-                                      }
-
-                                      view.Margin.Thickness = new (0, _topMargin, 0, 0);
-                                  }
+                                  _leftMargin = e.NewValue is { } && e.NewValue.Value ? 1 : 0;
+                                  UpdatePosAlignObjects (appWindow, dimension, _horizAligner);
+                              }
+                              else
+                              {
+                                  _topMargin = e.NewValue is { } && e.NewValue.Value ? 1 : 0;
+                                  UpdatePosAlignObjects (appWindow, dimension, _vertAligner);
                               }
                           };
         appWindow.Add (margin);
 
-        List<CheckBox> addedViews =
+        List<Button> addedViews =
         [
             new ()
-            {
-                X = 0,
-                Y = Pos.Align (_vertAligner.Alignment),
-                Text = NumberToWords.Convert (0)
-            }
+                                                       {
+                                                           X = dimension == Dimension.Width ? Pos.Align (_horizAligner.Alignment) : Pos.Left (alignRadioGroup),
+                                                           Y = dimension == Dimension.Width ? Pos.Top(alignRadioGroup): Pos.Align (_vertAligner.Alignment),
+                                                           Text = NumberToWords.Convert (0)
+                                                       }
         ];
 
         Buttons.NumericUpDown<int> addedViewsUpDown = new Buttons.NumericUpDown<int>
         {
-            X = 0,
-            Y = Pos.Align (_vertAligner.Alignment),
             Width = 9,
             Title = "Added",
             ColorScheme = colorScheme,
             BorderStyle = LineStyle.None,
             Value = addedViews.Count
         };
-        addedViewsUpDown.Border.Thickness = new (0, 1, 0, 0);
+
+        if (dimension == Dimension.Width)
+        {
+            addedViewsUpDown.X = Pos.Align (_horizAligner.Alignment);
+            addedViewsUpDown.Y = Pos.Top (alignRadioGroup);
+            addedViewsUpDown.Border.Thickness = new (0, 1, 0, 0);
+        }
+        else
+        {
+            addedViewsUpDown.X = Pos.Left (alignRadioGroup);
+            addedViewsUpDown.Y = Pos.Align (_vertAligner.Alignment);
+            addedViewsUpDown.Border.Thickness = new (1, 0, 0, 0);
+        }
 
         addedViewsUpDown.ValueChanging += (s, e) =>
                                           {
@@ -307,7 +238,7 @@ public sealed class PosAlignDemo : Scenario
                                                   // Remove buttons
                                                   for (int i = e.OldValue - 1; i >= e.NewValue; i--)
                                                   {
-                                                      CheckBox button = addedViews [i];
+                                                      Button button = addedViews [i];
                                                       appWindow.Remove (button);
                                                       addedViews.RemoveAt (i);
                                                       button.Dispose ();
@@ -319,10 +250,10 @@ public sealed class PosAlignDemo : Scenario
                                                   // Add buttons
                                                   for (int i = e.OldValue; i < e.NewValue; i++)
                                                   {
-                                                      var button = new CheckBox
+                                                      var button = new Button
                                                       {
-                                                          X = 0,
-                                                          Y = Pos.Align (_vertAligner.Alignment),
+                                                          X = dimension == Dimension.Width ? Pos.Align (_horizAligner.Alignment) : Pos.Left (alignRadioGroup),
+                                                          Y = dimension == Dimension.Width ? Pos.Top (alignRadioGroup) : Pos.Align (_vertAligner.Alignment),
                                                           Text = NumberToWords.Convert (i + 1)
                                                       };
                                                       appWindow.Add (button);
@@ -335,35 +266,36 @@ public sealed class PosAlignDemo : Scenario
         appWindow.Add (addedViews [0]);
     }
 
-    private void Setup3by3Grid (Window appWindow)
+    private void UpdatePosAlignObjects (Window appWindow, Dimension dimension, Aligner aligner)
     {
-        var container = new View
+        foreach (View view in appWindow.Subviews.Where (v => dimension == Dimension.Width ? v.X is PosAlign : v.Y is PosAlign))
         {
-            Title = "3 by 3",
-            BorderStyle = LineStyle.Single,
-            X = Pos.AnchorEnd (),
-            Y = Pos.AnchorEnd (),
-            Width = Dim.Percent (30),
-            Height = Dim.Percent (30)
-        };
-
-        for (var i = 0; i < 9; i++)
-
-        {
-            var v = new View
+            if (dimension == Dimension.Width ? view.X is PosAlign posAlign : view.Y is PosAlign)
             {
-                Title = $"{i}",
-                BorderStyle = LineStyle.Dashed,
-                Height = 3,
-                Width = 5
-            };
-
-            v.X = Pos.Align (Alignment.End, i / 3);
-            v.Y = Pos.Align (Alignment.Fill, i % 3 + 10);
-
-            container.Add (v);
+                //posAlign.Aligner.Alignment = _horizAligner.Alignment;
+                //posAlign.Aligner.AlignmentMode = _horizAligner.AlignmentMode;
+
+                // BUGBUG: Create and assign a new Pos object because we currently have no way for X to be notified
+                // BUGBUG: of changes in the Pos object. See https://github.com/gui-cs/Terminal.Gui/issues/3485
+                if (dimension == Dimension.Width)
+                {
+                    view.X = new PosAlign (
+                                           aligner.Alignment,
+                                           aligner.AlignmentMode);
+                    view.Margin.Thickness = new (_leftMargin, 0, 0, 0);
+
+                }
+                else
+                {
+                    view.Y = new PosAlign (
+                                           aligner.Alignment,
+                                           aligner.AlignmentMode);
+
+                    view.Margin.Thickness = new (0, _topMargin, 0, 0);
+                }
+            }
         }
 
-        appWindow.Add (container);
+        appWindow.LayoutSubviews ();
     }
 }

+ 18 - 18
UICatalog/Scenarios/TextAlignmentAndDirection.cs

@@ -33,44 +33,44 @@ public class TextAlignmentAndDirection : Scenario
         {
             X = 1,
             Y = 1,
-            Width = 9,
+            Width = 6,
             Height = 1,
             TextAlignment = Alignment.End,
             ColorScheme = Colors.ColorSchemes ["Dialog"],
-            Text = "Left"
+            Text = "Start"
         };
 
         var labelHC = new Label
         {
             X = 1,
             Y = 2,
-            Width = 9,
+            Width = 6,
             Height = 1,
             TextAlignment = Alignment.End,
             ColorScheme = Colors.ColorSchemes ["Dialog"],
-            Text = "Centered"
+            Text = "Center"
         };
 
         var labelHR = new Label
         {
             X = 1,
             Y = 3,
-            Width = 9,
+            Width = 6,
             Height = 1,
             TextAlignment = Alignment.End,
             ColorScheme = Colors.ColorSchemes ["Dialog"],
-            Text = "Right"
+            Text = "End"
         };
 
         var labelHJ = new Label
         {
             X = 1,
             Y = 4,
-            Width = 9,
+            Width = 6,
             Height = 1,
             TextAlignment = Alignment.End,
             ColorScheme = Colors.ColorSchemes ["Dialog"],
-            Text = "Justified"
+            Text = "Fill"
         };
 
         var txtLabelHL = new Label
@@ -138,11 +138,11 @@ public class TextAlignmentAndDirection : Scenario
             X = Pos.AnchorEnd (8),
             Y = 1,
             Width = 2,
-            Height = 9,
+            Height = 6,
             ColorScheme = color1,
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.End,
-            Text = "Top"
+            Text = "Start"
         };
         labelVT.TextFormatter.WordWrap = false;
 
@@ -151,11 +151,11 @@ public class TextAlignmentAndDirection : Scenario
             X = Pos.AnchorEnd (6),
             Y = 1,
             Width = 2,
-            Height = 9,
+            Height = 6,
             ColorScheme = color1,
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.End,
-            Text = "Centered"
+            Text = "Center"
         };
         labelVM.TextFormatter.WordWrap = false;
 
@@ -164,11 +164,11 @@ public class TextAlignmentAndDirection : Scenario
             X = Pos.AnchorEnd (4),
             Y = 1,
             Width = 2,
-            Height = 9,
+            Height = 6,
             ColorScheme = color1,
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.End,
-            Text = "Bottom"
+            Text = "End"
         };
         labelVB.TextFormatter.WordWrap = false;
 
@@ -177,11 +177,11 @@ public class TextAlignmentAndDirection : Scenario
             X = Pos.AnchorEnd (2),
             Y = 1,
             Width = 2,
-            Height = 9,
+            Height = 6,
             ColorScheme = color1,
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.End,
-            Text = "Justified"
+            Text = "Fill"
         };
         labelVJ.TextFormatter.WordWrap = false;
 
@@ -459,7 +459,7 @@ public class TextAlignmentAndDirection : Scenario
             Y = Pos.Y (container) + 1,
             Width = Dim.Fill (10),
             Height = 1,
-            Text = "Justify"
+            Text = "Fill"
         };
 
         app.Add (justifyCheckbox);
@@ -471,7 +471,7 @@ public class TextAlignmentAndDirection : Scenario
             X = Pos.Left (justifyCheckbox) + 1,
             Y = Pos.Y (justifyCheckbox) + 1,
             Width = Dim.Fill (11),
-            RadioLabels = ["Current direction", "Opposite direction", "Justify Both"],
+            RadioLabels = ["Current direction", "Opposite direction", "FIll Both"],
             Enabled = false
         };
 

+ 1 - 1
UICatalog/Scenarios/Unicode.cs

@@ -133,7 +133,7 @@ public class UnicodeInMenu : Scenario
             Width = Dim.Percent (50),
             Height = 1,
             TextAlignment = Alignment.End,
-            Text = $"Justify Right - {gitString}"
+            Text = $"End - {gitString}"
         };
         Win.Add (checkBox, checkBoxRight);
 

+ 303 - 312
UnitTests/Drawing/AlignerTests.cs

@@ -31,7 +31,7 @@ public class AlignerTests (ITestOutputHelper output)
     public void NoItems_Works (Alignment alignment)
     {
         int [] sizes = [];
-        int [] positions = Aligner.Align (alignment, false, 100, sizes);
+        int [] positions = Aligner.Align (alignment, AlignmentModes.StartToEnd, 100, sizes);
         Assert.Equal (new int [] { }, positions);
     }
 
@@ -62,343 +62,334 @@ public class AlignerTests (ITestOutputHelper output)
     }
 
     [Theory]
-    [InlineData (Alignment.Start, new [] { 0 }, 1, new [] { 0 })]
-    [InlineData (Alignment.Start, new [] { 0, 0 }, 1, new [] { 0, 1 })]
-    [InlineData (Alignment.Start, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
-    [InlineData (Alignment.Start, new [] { 1 }, 1, new [] { 0 })]
-    [InlineData (Alignment.Start, new [] { 1 }, 2, new [] { 0 })]
-    [InlineData (Alignment.Start, new [] { 1 }, 3, new [] { 0 })]
-    [InlineData (Alignment.Start, new [] { 1, 1 }, 2, new [] { 0, 1 })]
-    [InlineData (Alignment.Start, new [] { 1, 1 }, 3, new [] { 0, 2 })]
-    [InlineData (Alignment.Start, new [] { 1, 1 }, 4, new [] { 0, 2 })]
-    [InlineData (Alignment.Start, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 10, new [] { 0, 2, 5 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 11, new [] { 0, 2, 5 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 12, new [] { 0, 2, 5 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 13, new [] { 0, 2, 5 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0, 0 }, 1, new [] { 0, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1 }, 2, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1 }, 3, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1 }, 2, new [] { 0, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1 }, 3, new [] { 0, 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1 }, 4, new [] { 0, 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 10, new [] { 0, 2, 5 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 11, new [] { 0, 2, 5 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 12, new [] { 0, 2, 5 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 13, new [] { 0, 2, 5 })]
     [InlineData (
-                    Alignment.Start,
+                    Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems,
                     new [] { 1, 2, 3 },
                     5,
                     new [] { 0, 1, 3 })] // 5 is too small to fit the items. The first item is at 0, the items to the right are clipped.
-    [InlineData (Alignment.Start, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
-    [InlineData (Alignment.Start, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
-    [InlineData (Alignment.Start, new [] { 10 }, 101, new [] { 0 })]
-    [InlineData (Alignment.Start, new [] { 10, 20 }, 101, new [] { 0, 11 })]
-    [InlineData (Alignment.Start, new [] { 10, 20, 30 }, 100, new [] { 0, 11, 32 })]
-    [InlineData (Alignment.Start, new [] { 10, 20, 30 }, 101, new [] { 0, 11, 32 })]
-    [InlineData (Alignment.Start, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
-    [InlineData (Alignment.Start, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
-    [InlineData (Alignment.End, new [] { 0 }, 1, new [] { 1 })]
-    [InlineData (Alignment.End, new [] { 0, 0 }, 1, new [] { 0, 1 })]
-    [InlineData (Alignment.End, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 10, new [] { 2, 4, 7 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 11, new [] { 3, 5, 8 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 12, new [] { 4, 6, 9 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 13, new [] { 5, 7, 10 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 5, new [] { -1, 0, 2 })] // 5 is too small to fit the items. The first item is at -1.
-    [InlineData (Alignment.End, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30 }, 100, new [] { 38, 49, 70 })]
-    [InlineData (Alignment.End, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
-    [InlineData (Alignment.End, new [] { 10 }, 101, new [] { 91 })]
-    [InlineData (Alignment.End, new [] { 10, 20 }, 101, new [] { 70, 81 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30 }, 101, new [] { 39, 50, 71 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
-    [InlineData (Alignment.Center, new [] { 0 }, 1, new [] { 0 })]
-    [InlineData (Alignment.Center, new [] { 0, 0 }, 1, new [] { 0, 1 })]
-    [InlineData (Alignment.Center, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
-    [InlineData (Alignment.Center, new [] { 1 }, 1, new [] { 0 })]
-    [InlineData (Alignment.Center, new [] { 1 }, 2, new [] { 0 })]
-    [InlineData (Alignment.Center, new [] { 1 }, 3, new [] { 1 })]
-    [InlineData (Alignment.Center, new [] { 1, 1 }, 2, new [] { 0, 1 })]
-    [InlineData (Alignment.Center, new [] { 1, 1 }, 3, new [] { 0, 2 })]
-    [InlineData (Alignment.Center, new [] { 1, 1 }, 4, new [] { 0, 2 })]
-    [InlineData (Alignment.Center, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 10, new [] { 1, 3, 6 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 11, new [] { 1, 3, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10 }, 101, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20 }, 101, new [] { 0, 11 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 100, new [] { 0, 11, 32 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 101, new [] { 0, 11, 32 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0 }, 1, new [] { 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0, 0 }, 1, new [] { 0, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 10, new [] { 2, 4, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 11, new [] { 3, 5, 8 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 12, new [] { 4, 6, 9 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 13, new [] { 5, 7, 10 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 5, new [] { -1, 0, 2 })] // 5 is too small to fit the items. The first item is at -1.
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 100, new [] { 38, 49, 70 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10 }, 101, new [] { 91 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20 }, 101, new [] { 70, 81 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 101, new [] { 39, 50, 71 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0, 0 }, 1, new [] { 0, 1 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1 }, 2, new [] { 0 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1 }, 3, new [] { 1 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1 }, 2, new [] { 0, 1 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1 }, 3, new [] { 0, 2 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1 }, 4, new [] { 0, 2 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 10, new [] { 1, 3, 6 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 11, new [] { 1, 3, 6 })]
     [InlineData (
-                    Alignment.Center,
+                    Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems,
                     new [] { 1, 2, 3 },
                     5,
                     new [] { 0, 1, 3 })] // 5 is too small to fit the items. The first item is at 0, the items to the right are clipped.
-    [InlineData (Alignment.Center, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 9, new [] { 0, 3, 6 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 10, new [] { 0, 4, 7 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 11, new [] { 0, 4, 8 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 12, new [] { 0, 4, 8 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 13, new [] { 1, 5, 9 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 101, new [] { 0, 34, 68 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 102, new [] { 0, 34, 68 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 103, new [] { 1, 35, 69 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 104, new [] { 1, 35, 69 })]
-    [InlineData (Alignment.Center, new [] { 10 }, 101, new [] { 45 })]
-    [InlineData (Alignment.Center, new [] { 10, 20 }, 101, new [] { 35, 46 })]
-    [InlineData (Alignment.Center, new [] { 10, 20, 30 }, 100, new [] { 19, 30, 51 })]
-    [InlineData (Alignment.Center, new [] { 10, 20, 30 }, 101, new [] { 19, 30, 51 })]
-    [InlineData (Alignment.Center, new [] { 10, 20, 30, 40 }, 100, new [] { 0, 10, 30, 60 })]
-    [InlineData (Alignment.Center, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
-    [InlineData (Alignment.Center, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
-    [InlineData (Alignment.Center, new [] { 3, 4, 5, 6 }, 25, new [] { 2, 6, 11, 17 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30 }, 100, new [] { 0, 30, 70 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30 }, 101, new [] { 0, 31, 71 })]
-    [InlineData (Alignment.Fill, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
-    [InlineData (Alignment.Fill, new [] { 11, 17, 23 }, 100, new [] { 0, 36, 77 })]
-    [InlineData (Alignment.Fill, new [] { 1, 2, 3 }, 11, new [] { 0, 4, 8 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20 }, 101, new [] { 0, 81 })]
-    [InlineData (Alignment.Fill, new [] { 10 }, 101, new [] { 0 })]
-    [InlineData (Alignment.Fill, new [] { 3, 3, 3 }, 21, new [] { 0, 9, 18 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5 }, 21, new [] { 0, 8, 16 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 18, new [] { 0, 3, 7, 12 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 19, new [] { 0, 4, 8, 13 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 20, new [] { 0, 4, 9, 14 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 21, new [] { 0, 4, 9, 15 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 22, new [] { 0, 8, 14, 19 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 23, new [] { 0, 8, 15, 20 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 24, new [] { 0, 8, 15, 21 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 25, new [] { 0, 9, 16, 22 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 26, new [] { 0, 9, 17, 23 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 31, new [] { 0, 11, 20, 28 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 0 }, 1, new [] { 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 0, 0 }, 1, new [] { 0, 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1 }, 1, new [] { 0 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1 }, 2, new [] { 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1 }, 3, new [] { 2 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1 }, 2, new [] { 0, 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1 }, 3, new [] { 0, 2 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1 }, 4, new [] { 0, 3 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 8, new [] { 0, 2, 5 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 9, new [] { 0, 2, 6 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 10, new [] { 0, 2, 7 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 11, new [] { 0, 2, 8 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 5, new [] { -1, 0, 2 })] // 5 is too small to fit the items. The first item is at -1.})]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 3, 3, 3 }, 21, new [] { 0, 4, 18 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 3, 4, 5 }, 21, new [] { 0, 4, 16 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10 }, 101, new [] { 91 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20 }, 101, new [] { 0, 81 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30 }, 100, new [] { 0, 11, 70 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30 }, 101, new [] { 0, 11, 71 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 0 }, 1, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 0, 0 }, 1, new [] { 0, 1 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 0, 0, 0 }, 1, new [] { 0, 0, 1 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1 }, 1, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1 }, 2, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1 }, 3, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1 }, 2, new [] { 0, 1 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1 }, 3, new [] { 0, 2 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1 }, 4, new [] { 0, 3 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 4 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 8, new [] { 0, 2, 5 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 9, new [] { 0, 3, 6 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 10, new [] { 0, 4, 7 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 11, new [] { 0, 5, 8 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 5, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 7 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3, 4 }, 12, new [] { 0, 1, 4, 8 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 3, 3, 3 }, 21, new [] { 0, 14, 18 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 3, 4, 5 }, 21, new [] { 0, 11, 16 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 67 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10 }, 101, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20 }, 101, new [] { 0, 81 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30 }, 100, new [] { 0, 49, 70 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30 }, 101, new [] { 0, 50, 71 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 10, 30, 61 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 101 })]
-    public void Alignment_SpaceBetweenItems (Alignment alignment, int [] sizes, int containerSize, int [] expected)
-    {
-        int [] positions = new Aligner
-        {
-            SpaceBetweenItems = true,
-            Alignment = alignment,
-            ContainerSize = containerSize
-        }.Align (sizes);
-        AssertAlignment (alignment, sizes, containerSize, positions, expected);
-    }
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 3, 3 }, 9, new [] { 0, 3, 6 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 3, 3 }, 10, new [] { 0, 4, 7 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 3, 3 }, 11, new [] { 0, 4, 8 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 3, 3 }, 12, new [] { 0, 4, 8 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 3, 3 }, 13, new [] { 1, 5, 9 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 101, new [] { 0, 34, 68 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 102, new [] { 0, 34, 68 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 103, new [] { 1, 35, 69 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 104, new [] { 1, 35, 69 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10 }, 101, new [] { 45 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20 }, 101, new [] { 35, 46 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 100, new [] { 19, 30, 51 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 101, new [] { 19, 30, 51 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40 }, 100, new [] { 0, 10, 30, 60 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 4, 5, 6 }, 25, new [] { 2, 6, 11, 17 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 100, new [] { 0, 30, 70 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20, 30 }, 101, new [] { 0, 31, 71 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 11, 17, 23 }, 100, new [] { 0, 36, 77 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 1, 2, 3 }, 11, new [] { 0, 4, 8 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10, 20 }, 101, new [] { 0, 81 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 10 }, 101, new [] { 0 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 3, 3 }, 21, new [] { 0, 9, 18 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 4, 5 }, 21, new [] { 0, 8, 16 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 4, 5, 6 }, 18, new [] { 0, 3, 7, 12 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 4, 5, 6 }, 19, new [] { 0, 4, 8, 13 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 4, 5, 6 }, 20, new [] { 0, 4, 9, 14 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 3, 4, 5, 6 }, 21, new [] { 0, 4, 9, 15 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 6, 5, 4, 3 }, 22, new [] { 0, 8, 14, 19 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 6, 5, 4, 3 }, 23, new [] { 0, 8, 15, 20 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 6, 5, 4, 3 }, 24, new [] { 0, 8, 15, 21 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 6, 5, 4, 3 }, 25, new [] { 0, 9, 16, 22 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 6, 5, 4, 3 }, 26, new [] { 0, 9, 17, 23 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems, new [] { 6, 5, 4, 3 }, 31, new [] { 0, 11, 20, 28 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 0 }, 1, new [] { 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0 }, 1, new [] { 0, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 2, new [] { 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 3, new [] { 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 2, new [] { 0, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 3, new [] { 0, 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 4, new [] { 0, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 8, new [] { 0, 2, 5 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 9, new [] { 0, 2, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 10, new [] { 0, 2, 7 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 11, new [] { 0, 2, 8 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 5, new [] { -1, 0, 2 })] // 5 is too small to fit the items. The first item is at -1.})]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 3, 3 }, 21, new [] { 0, 4, 18 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 4, 5 }, 21, new [] { 0, 4, 16 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10 }, 101, new [] { 91 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20 }, 101, new [] { 0, 81 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 100, new [] { 0, 11, 70 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 101, new [] { 0, 11, 71 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 0 }, 1, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0 }, 1, new [] { 0, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0, 0 }, 1, new [] { 0, 0, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 1, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 2, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 3, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 2, new [] { 0, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 3, new [] { 0, 2 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 4, new [] { 0, 3 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 4 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 8, new [] { 0, 2, 5 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 9, new [] { 0, 3, 6 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 10, new [] { 0, 4, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 11, new [] { 0, 5, 8 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 5, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 12, new [] { 0, 1, 4, 8 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 3, 3 }, 21, new [] { 0, 14, 18 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 4, 5 }, 21, new [] { 0, 11, 16 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 67 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10 }, 101, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20 }, 101, new [] { 0, 81 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 100, new [] { 0, 49, 70 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 101, new [] { 0, 50, 71 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 10, 30, 61 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 101 })]
 
-    [Theory]
-    [InlineData (Alignment.Start, new [] { 0 }, 1, new [] { 0 })]
-    [InlineData (Alignment.Start, new [] { 0, 0 }, 1, new [] { 0, 0 })]
-    [InlineData (Alignment.Start, new [] { 0, 0, 0 }, 1, new [] { 0, 0, 0 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 10, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 11, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 12, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3 }, 13, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.Start, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 0 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 0, 0 }, 1, new [] { 0, 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 0, 0, 0 }, 1, new [] { 0, 0, 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 10, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 11, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 12, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 13, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 6 })]
     [InlineData (
-                    Alignment.Start,
+                    Alignment.Start, AlignmentModes.StartToEnd,
                     new [] { 1, 2, 3 },
                     5,
                     new [] { 0, 1, 3 })] // 5 is too small to fit the items. The first item is at 0, the items to the right are clipped.
-    [InlineData (Alignment.Start, new [] { 10, 20, 30 }, 100, new [] { 0, 10, 30 })]
-    [InlineData (Alignment.Start, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 66 })]
-    [InlineData (Alignment.Start, new [] { 10 }, 101, new [] { 0 })]
-    [InlineData (Alignment.Start, new [] { 10, 20 }, 101, new [] { 0, 10 })]
-    [InlineData (Alignment.Start, new [] { 10, 20, 30 }, 101, new [] { 0, 10, 30 })]
-    [InlineData (Alignment.Start, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 10, 30, 60 })]
-    [InlineData (Alignment.Start, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 100 })]
-    [InlineData (Alignment.End, new [] { 0 }, 1, new [] { 1 })]
-    [InlineData (Alignment.End, new [] { 0, 0 }, 1, new [] { 1, 1 })]
-    [InlineData (Alignment.End, new [] { 0, 0, 0 }, 1, new [] { 1, 1, 1 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 7, new [] { 1, 2, 4 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 10, new [] { 4, 5, 7 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 11, new [] { 5, 6, 8 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 12, new [] { 6, 7, 9 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 13, new [] { 7, 8, 10 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3 }, 5, new [] { -1, 0, 2 })] // 5 is too small to fit the items. The first item is at -1.
-    [InlineData (Alignment.End, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.End, new [] { 1, 2, 3, 4 }, 11, new [] { 1, 2, 4, 7 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30 }, 100, new [] { 40, 50, 70 })]
-    [InlineData (Alignment.End, new [] { 33, 33, 33 }, 100, new [] { 1, 34, 67 })]
-    [InlineData (Alignment.End, new [] { 10 }, 101, new [] { 91 })]
-    [InlineData (Alignment.End, new [] { 10, 20 }, 101, new [] { 71, 81 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30 }, 101, new [] { 41, 51, 71 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30, 40 }, 101, new [] { 1, 11, 31, 61 })]
-    [InlineData (Alignment.End, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 1, 11, 31, 61, 101 })]
-    [InlineData (Alignment.Center, new [] { 1 }, 1, new [] { 0 })]
-    [InlineData (Alignment.Center, new [] { 1 }, 2, new [] { 0 })]
-    [InlineData (Alignment.Center, new [] { 1 }, 3, new [] { 1 })]
-    [InlineData (Alignment.Center, new [] { 1, 1 }, 2, new [] { 0, 1 })]
-    [InlineData (Alignment.Center, new [] { 1, 1 }, 3, new [] { 0, 1 })]
-    [InlineData (Alignment.Center, new [] { 1, 1 }, 4, new [] { 1, 2 })]
-    [InlineData (Alignment.Center, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 10, new [] { 2, 3, 5 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3 }, 11, new [] { 2, 3, 5 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.Center, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 9, new [] { 0, 3, 6 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 10, new [] { 0, 3, 6 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 11, new [] { 1, 4, 7 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 12, new [] { 1, 4, 7 })]
-    [InlineData (Alignment.Center, new [] { 3, 3, 3 }, 13, new [] { 2, 5, 8 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 10, 20, 30 }, 100, new [] { 0, 10, 30 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 66 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 10 }, 101, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 10, 20 }, 101, new [] { 0, 10 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 10, 20, 30 }, 101, new [] { 0, 10, 30 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 10, 30, 60 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 100 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 0 }, 1, new [] { 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 0, 0 }, 1, new [] { 1, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 0, 0, 0 }, 1, new [] { 1, 1, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 7, new [] { 1, 2, 4 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 10, new [] { 4, 5, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 11, new [] { 5, 6, 8 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 12, new [] { 6, 7, 9 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 13, new [] { 7, 8, 10 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 5, new [] { -1, 0, 2 })] // 5 is too small to fit the items. The first item is at -1.
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 1, 2, 3, 4 }, 11, new [] { 1, 2, 4, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 10, 20, 30 }, 100, new [] { 40, 50, 70 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 100, new [] { 1, 34, 67 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 10 }, 101, new [] { 91 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 10, 20 }, 101, new [] { 71, 81 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 10, 20, 30 }, 101, new [] { 41, 51, 71 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 10, 20, 30, 40 }, 101, new [] { 1, 11, 31, 61 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 1, 11, 31, 61, 101 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1 }, 2, new [] { 0 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1 }, 3, new [] { 1 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 1 }, 2, new [] { 0, 1 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 1 }, 3, new [] { 0, 1 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 1 }, 4, new [] { 1, 2 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 10, new [] { 2, 3, 5 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 11, new [] { 2, 3, 5 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 3, 3, 3 }, 9, new [] { 0, 3, 6 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 3, 3, 3 }, 10, new [] { 0, 3, 6 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 3, 3, 3 }, 11, new [] { 1, 4, 7 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 3, 3, 3 }, 12, new [] { 1, 4, 7 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 3, 3, 3 }, 13, new [] { 2, 5, 8 })]
     [InlineData (
-                    Alignment.Center,
+                    Alignment.Center, AlignmentModes.StartToEnd,
                     new [] { 1, 2, 3 },
                     5,
                     new [] { 0, 1, 3 })] // 5 is too small to fit the items. The first item is at 0, the items to the right are clipped.
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 66 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 101, new [] { 1, 34, 67 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 102, new [] { 1, 34, 67 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 103, new [] { 2, 35, 68 })]
-    [InlineData (Alignment.Center, new [] { 33, 33, 33 }, 104, new [] { 2, 35, 68 })]
-    [InlineData (Alignment.Center, new [] { 3, 4, 5, 6 }, 25, new [] { 3, 6, 10, 15 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30 }, 100, new [] { 0, 30, 70 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20, 30 }, 101, new [] { 0, 31, 71 })]
-    [InlineData (Alignment.Fill, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
-    [InlineData (Alignment.Fill, new [] { 11, 17, 23 }, 100, new [] { 0, 36, 77 })]
-    [InlineData (Alignment.Fill, new [] { 1, 2, 3 }, 11, new [] { 0, 4, 8 })]
-    [InlineData (Alignment.Fill, new [] { 10, 20 }, 101, new [] { 0, 81 })]
-    [InlineData (Alignment.Fill, new [] { 10 }, 101, new [] { 0 })]
-    [InlineData (Alignment.Fill, new [] { 3, 3, 3 }, 21, new [] { 0, 9, 18 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5 }, 21, new [] { 0, 8, 16 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 18, new [] { 0, 3, 7, 12 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 19, new [] { 0, 4, 8, 13 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 20, new [] { 0, 4, 9, 14 })]
-    [InlineData (Alignment.Fill, new [] { 3, 4, 5, 6 }, 21, new [] { 0, 4, 9, 15 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 22, new [] { 0, 8, 14, 19 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 23, new [] { 0, 8, 15, 20 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 24, new [] { 0, 8, 15, 21 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 25, new [] { 0, 9, 16, 22 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 26, new [] { 0, 9, 17, 23 })]
-    [InlineData (Alignment.Fill, new [] { 6, 5, 4, 3 }, 31, new [] { 0, 11, 20, 28 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 0 }, 1, new [] { 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 0, 0 }, 1, new [] { 0, 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 0, 0, 0 }, 1, new [] { 0, 0, 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1 }, 1, new [] { 0 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1 }, 2, new [] { 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1 }, 3, new [] { 2 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1 }, 2, new [] { 0, 1 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1 }, 3, new [] { 0, 2 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1 }, 4, new [] { 0, 3 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 4 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 8, new [] { 0, 1, 5 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 9, new [] { 0, 1, 6 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 10, new [] { 0, 1, 7 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3 }, 11, new [] { 0, 1, 8 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 7 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 1, 2, 3, 4 }, 12, new [] { 0, 1, 3, 8 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 3, 3, 3 }, 21, new [] { 0, 3, 18 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 3, 4, 5 }, 21, new [] { 0, 3, 16 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 67 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10 }, 101, new [] { 91 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20 }, 101, new [] { 0, 81 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30 }, 100, new [] { 0, 10, 70 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30 }, 101, new [] { 0, 10, 71 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 10, 30, 61 })]
-    [InlineData (Alignment.LastEndRestStart, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 101 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 0 }, 1, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 0, 0 }, 1, new [] { 0, 1 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1 }, 1, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1 }, 2, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1 }, 3, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1 }, 2, new [] { 0, 1 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1 }, 3, new [] { 0, 2 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1 }, 4, new [] { 0, 3 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 8, new [] { 0, 3, 5 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 9, new [] { 0, 4, 6 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 10, new [] { 0, 5, 7 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3 }, 11, new [] { 0, 6, 8 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 1, 2, 3, 4 }, 12, new [] { 0, 3, 5, 8 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 3, 3, 3 }, 21, new [] { 0, 15, 18 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 3, 4, 5 }, 21, new [] { 0, 12, 16 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10 }, 101, new [] { 0 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20 }, 101, new [] { 0, 81 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30 }, 100, new [] { 0, 50, 70 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30 }, 101, new [] { 0, 51, 71 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
-    [InlineData (Alignment.FirstStartRestEnd, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
-    public void Alignment_NoSpaceBetweenItems (Alignment alignment, int [] sizes, int containerSize, int [] expected)
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 66 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 101, new [] { 1, 34, 67 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 102, new [] { 1, 34, 67 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 103, new [] { 2, 35, 68 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 104, new [] { 2, 35, 68 })]
+    [InlineData (Alignment.Center, AlignmentModes.StartToEnd, new [] { 3, 4, 5, 6 }, 25, new [] { 3, 6, 10, 15 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 10, 20, 30 }, 100, new [] { 0, 30, 70 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 10, 20, 30 }, 101, new [] { 0, 31, 71 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 11, 17, 23 }, 100, new [] { 0, 36, 77 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 1, 2, 3 }, 11, new [] { 0, 4, 8 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 10, 20 }, 101, new [] { 0, 81 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 10 }, 101, new [] { 0 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 3, 3, 3 }, 21, new [] { 0, 9, 18 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 3, 4, 5 }, 21, new [] { 0, 8, 16 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 3, 4, 5, 6 }, 18, new [] { 0, 3, 7, 12 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 3, 4, 5, 6 }, 19, new [] { 0, 4, 8, 13 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 3, 4, 5, 6 }, 20, new [] { 0, 4, 9, 14 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 3, 4, 5, 6 }, 21, new [] { 0, 4, 9, 15 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 6, 5, 4, 3 }, 22, new [] { 0, 8, 14, 19 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 6, 5, 4, 3 }, 23, new [] { 0, 8, 15, 20 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 6, 5, 4, 3 }, 24, new [] { 0, 8, 15, 21 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 6, 5, 4, 3 }, 25, new [] { 0, 9, 16, 22 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 6, 5, 4, 3 }, 26, new [] { 0, 9, 17, 23 })]
+    [InlineData (Alignment.Fill, AlignmentModes.StartToEnd, new [] { 6, 5, 4, 3 }, 31, new [] { 0, 11, 20, 28 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 0 }, 1, new [] { 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0 }, 1, new [] { 0, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0, 0 }, 1, new [] { 0, 0, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 1, new [] { 0 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 2, new [] { 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 3, new [] { 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 2, new [] { 0, 1 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 3, new [] { 0, 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 4, new [] { 0, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 7, new [] { 0, 1, 4 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 8, new [] { 0, 1, 5 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 9, new [] { 0, 1, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 10, new [] { 0, 1, 7 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 11, new [] { 0, 1, 8 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 1, 3, 7 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 12, new [] { 0, 1, 3, 8 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 3, 3 }, 21, new [] { 0, 3, 18 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 4, 5 }, 21, new [] { 0, 3, 16 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 33, 33, 33 }, 100, new [] { 0, 33, 67 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10 }, 101, new [] { 91 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20 }, 101, new [] { 0, 81 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 100, new [] { 0, 10, 70 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 101, new [] { 0, 10, 71 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 10, 30, 61 })]
+    [InlineData (Alignment.Start, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 101 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 0 }, 1, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0 }, 1, new [] { 0, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 0, 0, 0 }, 1, new [] { 0, 1, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 1, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 2, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1 }, 3, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 2, new [] { 0, 1 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 3, new [] { 0, 2 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1 }, 4, new [] { 0, 3 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 1, 1 }, 3, new [] { 0, 1, 2 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 6, new [] { 0, 1, 3 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 7, new [] { 0, 2, 4 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 8, new [] { 0, 3, 5 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 9, new [] { 0, 4, 6 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 10, new [] { 0, 5, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3 }, 11, new [] { 0, 6, 8 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 10, new [] { 0, 1, 3, 6 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 11, new [] { 0, 2, 4, 7 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 1, 2, 3, 4 }, 12, new [] { 0, 3, 5, 8 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 3, 3 }, 21, new [] { 0, 15, 18 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 3, 4, 5 }, 21, new [] { 0, 12, 16 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 33, 33, 33 }, 100, new [] { 0, 34, 67 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10 }, 101, new [] { 0 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20 }, 101, new [] { 0, 81 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 100, new [] { 0, 50, 70 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30 }, 101, new [] { 0, 51, 71 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 11, 31, 61 })]
+    [InlineData (Alignment.End, AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 11, 31, 61, 101 })]
+
+    public void Alignment_Aligns (Alignment alignment, AlignmentModes modes, int [] sizes, int containerSize, int [] expected)
     {
         int [] positions = new Aligner
         {
-            SpaceBetweenItems = false,
             Alignment = alignment,
+            AlignmentMode = AlignmentModes.StartToEnd | modes,
             ContainerSize = containerSize
         }.Align (sizes);
         AssertAlignment (alignment, sizes, containerSize, positions, expected);
     }
 
+
     private void AssertAlignment (Alignment alignment, int [] sizes, int totalSize, int [] positions, int [] expected)
     {
         try