debugging3

--- WebApp-B2C-DotNet/Controllers/HomeController.cs
+++ WebApp-B2C-DotNet/Controllers/HomeController.cs
@@ -107,9 +107,10 @@
             msg.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(clientId + ":" + clientSecret)));
             msg.Content = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");

-            throw new Exception("Move me: " + msg);
+
             var response = await client.SendAsync(msg);
-
+
+            throw new Exception("Move me: \n" + response);

             JObject tokenResponse = JObject.Parse(await response.Content.ReadAsStringAsync());


Extract pdf photos into temp folder

Extract pdf photos into temp folder

--- WindowsStore/Service/PdfPageExtractorService.cs
+++ WindowsStore/Service/PdfPageExtractorService.cs
@@ -21,7 +21,7 @@
         {
             var doc = await PdfDocument.LoadFromFileAsync(file);

-            var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(document.Id.ToString(), CreationCollisionOption.OpenIfExists);
+            var folder = ApplicationData.Current.TemporaryFolder;
             var extractTasks = Enumerable.Range(0, (int)doc.PageCount)
                 .Select(i => ExtractPage(doc, file.Name, i, folder));
             var images = await Task.WhenAll(extractTasks);


GapList now implements IReadOnlyList<T> and ICollection.

--- WmcSoft.Core/Collections/Specialized/GapList.cs
+++ WmcSoft.Core/Collections/Specialized/GapList.cs
@@ -29,6 +29,7 @@
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
+using System.Threading;
 using WmcSoft.Collections.Generic;

 namespace WmcSoft.Collections.Specialized
@@ -38,9 +39,9 @@
     /// </summary>
     /// <typeparam name="T">The type of the elements in the list.</typeparam>
     [Serializable]
-    [DebuggerDisplay("Count = {Count}")]
+    [DebuggerDisplay("Count = {Count,nq}")]
     [DebuggerTypeProxy(typeof(CollectionDebugView<>))]
-    public sealed class GapList<T> : IList<T>
+    public sealed class GapList<T> : IList<T>, IReadOnlyList<T>, ICollection
     {
         // *************........................*******
         // ^            ^                       ^      ^
@@ -64,10 +65,10 @@
                 Debug.Assert(list != null);

                 _list = list;
-                _storage = list._storage;
+                _storage = list.storage;
                 _index = 0;
-                _count = list._gapStartIndex;
-                _version = list._version;
+                _count = list.gapStartIndex;
+                _version = list.version;
                 _current = default(T);
             }

@@ -77,11 +78,11 @@

             public bool MoveNext()
             {
-                if (_version == _list._version && _index < _count) {
+                if (_version == _list.version && _index < _count) {
                     _current = _storage[_index++];
                     return true;
-                } else if (_version == _list._version && _index < _list._gapEndIndex && _list._gapEndIndex != _storage.Length) {
-                    _index = _list._gapEndIndex;
+                } else if (_version == _list.version && _index < _list.gapEndIndex && _list.gapEndIndex != _storage.Length) {
+                    _index = _list.gapEndIndex;
                     _count = _storage.Length;
                     _current = _storage[_index++];
                     return true;
@@ -91,7 +92,7 @@

             private bool MoveNextRare()
             {
-                if (_version != _list._version)
+                if (_version != _list.version)
                     throw new InvalidOperationException();
                 _index = 0;
                 _current = default(T);
@@ -110,10 +111,10 @@

             void IEnumerator.Reset()
             {
-                if (_version != _list._version)
+                if (_version != _list.version)
                     throw new InvalidOperationException();
                 _index = -1;
-                _count = _list._gapStartIndex;
+                _count = _list.gapStartIndex;
                 _current = default(T);
             }
         }
@@ -123,22 +124,22 @@
         private static readonly T[] Empty = new T[0];
         private const int DefaultCapacity = 4;

-        private T[] _storage;
-
-        private int _gapStartIndex;
-        private int _gapEndIndex;
-        private int _version;
+        private T[] storage;
+
+        private int gapStartIndex;
+        private int gapEndIndex;
+        private int version;

         public GapList()
         {
-            _storage = Empty;
+            storage = Empty;
         }

         public GapList(int capacity)
         {
             if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity));
-            _storage = capacity == 0 ? Empty : new T[capacity];
-            _gapEndIndex = capacity;
+            storage = capacity == 0 ? Empty : new T[capacity];
+            gapEndIndex = capacity;
         }

         public GapList(IEnumerable<T> collection)
@@ -149,15 +150,15 @@
             if (c != null) {
                 var count = c.Count;
                 if (count == 0) {
-                    _storage = Empty;
+                    storage = Empty;
                 } else {
-                    _storage = new T[count];
-                    c.CopyTo(_storage, 0);
-                    _gapStartIndex = count;
-                    _gapEndIndex = count;
+                    storage = new T[count];
+                    c.CopyTo(storage, 0);
+                    gapStartIndex = count;
+                    gapEndIndex = count;
                 }
             } else {
-                _storage = Empty;
+                storage = Empty;
                 using (IEnumerator<T> enumerator = collection.GetEnumerator()) {
                     while (enumerator.MoveNext()) {
                         Add(enumerator.Current);
@@ -168,21 +169,21 @@

         private int Slide(int index)
         {
-            if (index < _gapStartIndex)
+            if (index < gapStartIndex)
                 return index;
-            return index - _gapStartIndex + _gapEndIndex;
+            return index - gapStartIndex + gapEndIndex;
         }

         void Reserve(int grow)
         {
-            var gap = _gapEndIndex - _gapStartIndex;
+            var gap = gapEndIndex - gapStartIndex;
             if (gap < grow) {
-                Capacity = Math.Max(Count + gap, _storage.Length == 0 ? DefaultCapacity : _storage.Length * 2);
+                Capacity = Math.Max(Count + gap, storage.Length == 0 ? DefaultCapacity : storage.Length * 2);
             }
         }

         public int Position {
-            get { return _gapStartIndex; }
+            get { return gapStartIndex; }
             set { Seek(value, SeekOrigin.Begin); }
         }

@@ -197,7 +198,7 @@
                 break;
             case SeekOrigin.Current:
             default:
-                offset = _gapStartIndex + offset;
+                offset = gapStartIndex + offset;
                 break;
             }
             if (offset < 0)
@@ -205,107 +206,138 @@
             else if (offset > Count)
                 offset = count;
             Seek(offset);
-            return _gapStartIndex;
+            return gapStartIndex;
         }

         void Seek(int position)
         {
-            _version++; // alsways increment the version
-            if (position < _gapStartIndex) {
+            version++; // alsways increment the version
+            if (position < gapStartIndex) {
                 // *****-----.....*****
                 //      ^
                 // *****.....-----*****
-                var n = _gapStartIndex - position;
-                _gapEndIndex = _storage.Rotate(-n, position, _gapEndIndex - position);
-                _gapStartIndex = position;
-            } else if (position > _gapStartIndex) {
+                var n = gapStartIndex - position;
+                gapEndIndex = storage.Rotate(-n, position, gapEndIndex - position);
+                gapStartIndex = position;
+            } else if (position > gapStartIndex) {
                 // ***********.....******
                 //                    ^
                 // **************.....***
-                var n = position - _gapStartIndex;
-                var gap = _gapEndIndex - _gapStartIndex;
-                _gapEndIndex = _storage.Rotate(n, _gapStartIndex, n + gap) + gap;
-                _gapStartIndex = position;
+                var n = position - gapStartIndex;
+                var gap = gapEndIndex - gapStartIndex;
+                gapEndIndex = storage.Rotate(n, gapStartIndex, n + gap) + gap;
+                gapStartIndex = position;
             }
         }

         public int Capacity {
             get {
-                return _storage.Length;
+                return storage.Length;
             }
             set {
                 var count = Count;
                 if (value < count) throw new ArgumentOutOfRangeException(nameof(value));

-                if (value != _storage.Length) {
+                if (value != storage.Length) {
                     if (value > 0) {
                         T[] storage = new T[value];
                         if (count > 0) {
-                            Array.Copy(_storage, 0, storage, 0, _gapStartIndex);
-                            var n = _storage.Length - _gapEndIndex;
-                            Array.Copy(_storage, _gapEndIndex, storage, storage.Length - n, n);
-                            _gapEndIndex = storage.Length - n;
+                            Array.Copy(this.storage, 0, storage, 0, gapStartIndex);
+                            var n = this.storage.Length - gapEndIndex;
+                            Array.Copy(this.storage, gapEndIndex, storage, storage.Length - n, n);
+                            gapEndIndex = storage.Length - n;
                         }
-                        _storage = storage;
+                        this.storage = storage;
                     } else {
-                        _storage = Empty;
-                        _gapEndIndex = 0;
+                        storage = Empty;
+                        gapEndIndex = 0;
                     }
                 }
             }
         }

         public T this[int index] {
-            get { return _storage[Slide(index)]; }
-            set { _storage[Slide(index)] = value; }
-        }
-
-        public int Count => _gapStartIndex + _storage.Length - _gapEndIndex;
+            get { return storage[Slide(index)]; }
+            set { storage[Slide(index)] = value; }
+        }
+
+        public int Count => gapStartIndex + storage.Length - gapEndIndex;
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033", Justification = "Provided only for legacy.")]
+        object ICollection.SyncRoot {
+            get {
+                if (_syncRoot == null)
+                    Interlocked.CompareExchange<object>(ref _syncRoot, new object(), null);
+                return _syncRoot;
+            }
+        }
+        [NonSerialized]
+        private object _syncRoot;
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033", Justification = "Provided only for legacy.")]
+        bool ICollection.IsSynchronized => false;

         public bool IsReadOnly => false;

+        /// <summary>
+        /// Adds an item to the <see cref="Bag{T}"/>.
+        /// </summary>
+        /// <param name="item">The item to add to the <see cref="GapList{T}"/>.</param>
         public void Add(T item)
         {
             Reserve(1);
-            _version++;
-            _storage[_gapStartIndex++] = item;
-        }
-
+            version++;
+            storage[gapStartIndex++] = item;
+        }
+
+        /// <summary>
+        /// Removes all elements from the <see cref="Bag{T}"/>.
+        /// </summary>
+        /// <remarks>This method is an O(n) when n is <see cref="Count"/>.</remarks>
         public void Clear()
         {
-            _version++;
-            _gapStartIndex = 0;
-            _gapEndIndex = _storage.Length;
-        }
-
+            version++;
+            gapStartIndex = 0;
+            gapEndIndex = storage.Length;
+        }
+
+        /// <summary>
+        /// Determines whether an element is in the <see cref="Bag{T}"/>.
+        /// </summary>
+        /// <param name="item">The item to locate in the <see cref="Bag{T}"/>. The value can be <c>null</c> for reference types.</param>
+        /// <returns><c>true</c> if <paramref name="item"/> is found in the <see cref="Bag{T}"/>; otherwise <c>false</c>.</returns>
+        /// <remarks>The same comparer as <see cref="Array.IndexOf"/> to locate the item.</remarks>
         public bool Contains(T item)
         {
             return IndexOf(item) >= 0;
         }

+        /// <summary>
+        /// Copies the <see cref="Bag{T}"/> to a compatible one-dimensional array,
+        /// starting at the specified index of the target array.
+        /// </summary>
+        /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="Bag{T}"/>.
+        /// The <see cref="Array"/> must have zero-based indexing.</param>
+        /// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
         public void CopyTo(T[] array, int arrayIndex)
         {
-            Array.Copy(_storage, 0, array, arrayIndex, _gapStartIndex);
-            Array.Copy(_storage, _gapEndIndex, array, arrayIndex + _gapStartIndex, _storage.Length - _gapEndIndex);
-        }
-
-        public Enumerator GetEnumerator()
-        {
-            return new Enumerator(this);
-        }
-
-        IEnumerator<T> IEnumerable<T>.GetEnumerator()
-        {
-            return GetEnumerator();
+            Array.Copy(storage, 0, array, arrayIndex, gapStartIndex);
+            Array.Copy(storage, gapEndIndex, array, arrayIndex + gapStartIndex, storage.Length - gapEndIndex);
+        }
+
+        void ICollection.CopyTo(Array array, int index)
+        {
+            Array.Copy(storage, 0, array, index, gapStartIndex);
+            Array.Copy(storage, gapEndIndex, array, index + gapStartIndex, storage.Length - gapEndIndex);
         }

         public int IndexOf(T item)
         {
-            var found = Array.IndexOf(_storage, item, 0, _gapStartIndex);
+            var found = Array.IndexOf(storage, item, 0, gapStartIndex);
             if (found >= 0)
                 return found;
-            var gap = _gapEndIndex - _gapStartIndex;
-            return Array.IndexOf(_storage, item, _gapEndIndex, _storage.Length - _gapEndIndex) - gap;
+            var gap = gapEndIndex - gapStartIndex;
+            return Array.IndexOf(storage, item, gapEndIndex, storage.Length - gapEndIndex) - gap;
         }

         public void Insert(int index, T item)
@@ -314,6 +346,12 @@
             Add(item);
         }

+        /// <summary>
+        /// Removes the first occurrence of a specific item from the <see cref="Bag{T}"/>.
+        /// </summary>
+        /// <param name="item">The item to remove from the <see cref="Bag{T}"/>. The value can be <c>null</c> for reference types.</param>
+        /// <returns><c>true</c> if <paramref name="item"/> is successfully removed; otherwise <c>false</c>.</returns>
+        /// <remarks>The same comparer as <see cref="Array.IndexOf"/> to locate the item.</remarks>
         public bool Remove(T item)
         {
             var found = IndexOf(item);
@@ -326,8 +364,18 @@
         public void RemoveAt(int index)
         {
             Seek(index + 1); // seek increment the version
-            _gapStartIndex--;
-            _storage[_gapStartIndex] = default; // no loitering
+            gapStartIndex--;
+            storage[gapStartIndex] = default; // no loitering
+        }
+
+        public Enumerator GetEnumerator()
+        {
+            return new Enumerator(this);
+        }
+
+        IEnumerator<T> IEnumerable<T>.GetEnumerator()
+        {
+            return GetEnumerator();
         }

         IEnumerator IEnumerable.GetEnumerator()


Small updates.

Small updates.

--- Xamarin.RangeSlider.Droid/RangeSliderControl.cs
+++ Xamarin.RangeSlider.Droid/RangeSliderControl.cs
@@ -13,10 +13,11 @@
 {
     public class RangeSliderControl : ImageView
     {
-        public static readonly Color ActiveColor = Color.Argb(0xFF, 0x33, 0xB5, 0xE5);
-        /**
-         * An invalid pointer id.
-         */
+        public static readonly Color DefaultActiveColor = Color.Argb(0xFF, 0x33, 0xB5, 0xE5);
+
+        /// <summary>
+        ///     An invalid pointer id.
+        /// </summary>
         public static readonly int InvalidPointerId = 255;

         // Localized constants from MotionEvent for compatibility
@@ -39,12 +40,7 @@
         private readonly Matrix _thumbShadowMatrix = new Matrix();
         private readonly Path _translatedThumbShadowPath = new Path();

-        private bool _activateOnDefaultValues;
-        private Color _activeColor;
-
         private int _activePointerId = InvalidPointerId;
-        private bool _alwaysActive;
-        private Color _defaultColor;
         private int _distanceToTop;

         private float _downMotionX;
@@ -57,27 +53,14 @@
         private RectF _rect;

         private int _scaledTouchSlop;
-        private bool _showLabels;
-        private bool _showTextAboveThumbs;
-
-        private bool _singleThumb;
-        private Color _textAboveThumbsColor;

         private int _textOffset;
         private int _textSize;
-        private Bitmap _thumbDisabledImage;
         private float _thumbHalfHeight;

         private float _thumbHalfWidth;
-
-        private Bitmap _thumbImage;
-        private Bitmap _thumbPressedImage;
-
-        private bool _thumbShadow;
         private int _thumbShadowBlur;
         private Path _thumbShadowPath;
-        private int _thumbShadowXOffset;
-        private int _thumbShadowYOffset;
         protected float AbsoluteMinValue, AbsoluteMaxValue;
         protected float AbsoluteMinValuePrim, AbsoluteMaxValuePrim;
         protected float MinDeltaForDefault = 0;
@@ -98,7 +81,8 @@
             Init(context, attrs);
         }

-        public RangeSliderControl(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
+        public RangeSliderControl(Context context, IAttributeSet attrs, int defStyleAttr)
+            : base(context, attrs, defStyleAttr)
         {
             Init(context, attrs);
         }
@@ -108,6 +92,24 @@
         {
             Init(context, attrs);
         }
+
+        public bool ActivateOnDefaultValues { get; set; }
+        public Color ActiveColor { get; set; }
+        public bool AlwaysActive { get; set; }
+        public Color DefaultColor { get; set; }
+        public bool ShowLabels { get; set; }
+        public bool ShowTextAboveThumbs { get; set; }
+
+        public bool SingleThumb { get; set; }
+        public Color TextAboveThumbsColor { get; set; }
+        public Bitmap ThumbDisabledImage { get; set; }
+
+        public Bitmap ThumbImage { get; set; }
+        public Bitmap ThumbPressedImage { get; set; }
+
+        public bool ThumbShadow { get; set; }
+        public int ThumbShadowXOffset { get; set; }
+        public int ThumbShadowYOffset { get; set; }

         /// <summary>
         ///     Should the widget notify the listener callback while the user is still dragging a thumb? Default is false.
@@ -138,64 +140,56 @@
                 SetRangeToDefaultValues();
                 _internalPad = PixelUtil.DpToPx(context, InitialPaddingInDp);
                 barHeight = PixelUtil.DpToPx(context, LineHeightInDp);
-                _activeColor = ActiveColor;
-                _defaultColor = Color.Gray;
-                _alwaysActive = false;
-                _showTextAboveThumbs = true;
-                _textAboveThumbsColor = Color.White;
+                ActiveColor = DefaultActiveColor;
+                DefaultColor = Color.Gray;
+                AlwaysActive = false;
+                ShowTextAboveThumbs = true;
+                TextAboveThumbsColor = Color.White;
                 thumbShadowColor = defaultShadowColor;
-                _thumbShadowXOffset = defaultShadowXOffset;
-                _thumbShadowYOffset = defaultShadowYOffset;
+                ThumbShadowXOffset = defaultShadowXOffset;
+                ThumbShadowYOffset = defaultShadowYOffset;
                 _thumbShadowBlur = defaultShadowBlur;
-                _activateOnDefaultValues = false;
+                ActivateOnDefaultValues = false;
             }
             else
             {
                 var a = Context.ObtainStyledAttributes(attrs, Resource.Styleable.RangeSliderControl, 0, 0);
                 try
                 {
-                    SetRangeValues(
-                        extractNumericValueFromAttributes(a, Resource.Styleable.RangeSliderControl_absoluteMinValue,
-                            DefaultMinimum),
-                        extractNumericValueFromAttributes(a, Resource.Styleable.RangeSliderControl_absoluteMaxValue,
-                            DefaultMaximum));
-                    _showTextAboveThumbs = a.GetBoolean(Resource.Styleable.RangeSliderControl_valuesAboveThumbs, true);
-                    _textAboveThumbsColor = a.GetColor(Resource.Styleable.RangeSliderControl_textAboveThumbsColor, Color.White);
-                    _singleThumb = a.GetBoolean(Resource.Styleable.RangeSliderControl_singleThumb, false);
-                    _showLabels = a.GetBoolean(Resource.Styleable.RangeSliderControl_showLabels, true);
-                    _internalPad = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_internalPadding,
-                        InitialPaddingInDp);
+                    SetRangeValues(extractNumericValueFromAttributes(a, Resource.Styleable.RangeSliderControl_absoluteMinValue, DefaultMinimum),
+                        extractNumericValueFromAttributes(a, Resource.Styleable.RangeSliderControl_absoluteMaxValue, DefaultMaximum));
+                    ShowTextAboveThumbs = a.GetBoolean(Resource.Styleable.RangeSliderControl_valuesAboveThumbs, true);
+                    TextAboveThumbsColor = a.GetColor(Resource.Styleable.RangeSliderControl_textAboveThumbsColor, Color.White);
+                    SingleThumb = a.GetBoolean(Resource.Styleable.RangeSliderControl_singleThumb, false);
+                    ShowLabels = a.GetBoolean(Resource.Styleable.RangeSliderControl_showLabels, true);
+                    _internalPad = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_internalPadding, InitialPaddingInDp);
                     barHeight = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_barHeight, LineHeightInDp);
-                    _activeColor = a.GetColor(Resource.Styleable.RangeSliderControl_activeColor, ActiveColor);
-                    _defaultColor = a.GetColor(Resource.Styleable.RangeSliderControl_defaultColor, Color.Gray);
-                    _alwaysActive = a.GetBoolean(Resource.Styleable.RangeSliderControl_alwaysActive, false);
+                    ActiveColor = a.GetColor(Resource.Styleable.RangeSliderControl_activeColor, DefaultActiveColor);
+                    DefaultColor = a.GetColor(Resource.Styleable.RangeSliderControl_defaultColor, Color.Gray);
+                    AlwaysActive = a.GetBoolean(Resource.Styleable.RangeSliderControl_alwaysActive, false);

                     var normalDrawable = a.GetDrawable(Resource.Styleable.RangeSliderControl_thumbNormal);
                     if (normalDrawable != null)
                     {
-                        _thumbImage = BitmapUtil.DrawableToBitmap(normalDrawable);
+                        ThumbImage = BitmapUtil.DrawableToBitmap(normalDrawable);
                     }
                     var disabledDrawable = a.GetDrawable(Resource.Styleable.RangeSliderControl_thumbDisabled);
                     if (disabledDrawable != null)
                     {
-                        _thumbDisabledImage = BitmapUtil.DrawableToBitmap(disabledDrawable);
+                        ThumbDisabledImage = BitmapUtil.DrawableToBitmap(disabledDrawable);
                     }
                     var pressedDrawable = a.GetDrawable(Resource.Styleable.RangeSliderControl_thumbPressed);
                     if (pressedDrawable != null)
                     {
-                        _thumbPressedImage = BitmapUtil.DrawableToBitmap(pressedDrawable);
+                        ThumbPressedImage = BitmapUtil.DrawableToBitmap(pressedDrawable);
                     }
-                    _thumbShadow = a.GetBoolean(Resource.Styleable.RangeSliderControl_thumbShadow, false);
+                    ThumbShadow = a.GetBoolean(Resource.Styleable.RangeSliderControl_thumbShadow, false);
                     thumbShadowColor = a.GetColor(Resource.Styleable.RangeSliderControl_thumbShadowColor, defaultShadowColor);
-                    _thumbShadowXOffset = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowXOffset,
-                        defaultShadowXOffset);
-                    _thumbShadowYOffset = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowYOffset,
-                        defaultShadowYOffset);
-                    _thumbShadowBlur = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowBlur,
-                        defaultShadowBlur);
-
-                    _activateOnDefaultValues = a.GetBoolean(Resource.Styleable.RangeSliderControl_activateOnDefaultValues,
-                        false);
+                    ThumbShadowXOffset = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowXOffset, defaultShadowXOffset);
+                    ThumbShadowYOffset = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowYOffset, defaultShadowYOffset);
+                    _thumbShadowBlur = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowBlur, defaultShadowBlur);
+
+                    ActivateOnDefaultValues = a.GetBoolean(Resource.Styleable.RangeSliderControl_activateOnDefaultValues, false);
                 }
                 finally
                 {
@@ -203,30 +197,29 @@
                 }
             }

-            if (_thumbImage == null)
-            {
-                _thumbImage = BitmapFactory.DecodeResource(Resources, thumbNormal);
-            }
-            if (_thumbPressedImage == null)
-            {
-                _thumbPressedImage = BitmapFactory.DecodeResource(Resources, thumbPressed);
-            }
-            if (_thumbDisabledImage == null)
-            {
-                _thumbDisabledImage = BitmapFactory.DecodeResource(Resources, thumbDisabled);
-            }
-
-            _thumbHalfWidth = 0.5f*_thumbImage.Width;
-            _thumbHalfHeight = 0.5f*_thumbImage.Height;
+            if (ThumbImage == null)
+            {
+                ThumbImage = BitmapFactory.DecodeResource(Resources, thumbNormal);
+            }
+            if (ThumbPressedImage == null)
+            {
+                ThumbPressedImage = BitmapFactory.DecodeResource(Resources, thumbPressed);
+            }
+            if (ThumbDisabledImage == null)
+            {
+                ThumbDisabledImage = BitmapFactory.DecodeResource(Resources, thumbDisabled);
+            }
+
+            _thumbHalfWidth = 0.5f*ThumbImage.Width;
+            _thumbHalfHeight = 0.5f*ThumbImage.Height;

             SetValuePrimAndNumberType();

             _textSize = PixelUtil.DpToPx(context, DefaultTextSizeInDp);
             _distanceToTop = PixelUtil.DpToPx(context, DefaultTextDistanceToTopInDp);
-            _textOffset = !_showTextAboveThumbs
+            _textOffset = !ShowTextAboveThumbs
                 ? 0
-                : _textSize + PixelUtil.DpToPx(context,
-                    DefaultTextDistanceToButtonInDp) + _distanceToTop;
+                : _textSize + PixelUtil.DpToPx(context, DefaultTextDistanceToButtonInDp) + _distanceToTop;

             _rect = new RectF(_padding,
                 _textOffset + _thumbHalfHeight - barHeight/2,
@@ -238,16 +231,14 @@
             FocusableInTouchMode = true;
             _scaledTouchSlop = ViewConfiguration.Get(Context).ScaledTouchSlop;

-            if (_thumbShadow)
+            if (ThumbShadow)
             {
                 // We need to remove hardware acceleration in order to blur the shadow
                 SetLayerType(LayerType.Software, null);
                 _shadowPaint.Color = thumbShadowColor;
                 _shadowPaint.SetMaskFilter(new BlurMaskFilter(_thumbShadowBlur, BlurMaskFilter.Blur.Normal));
                 _thumbShadowPath = new Path();
-                _thumbShadowPath.AddCircle(0, 0,
-                    _thumbHalfHeight,
-                    Path.Direction.Cw);
+                _thumbShadowPath.AddCircle(0, 0, _thumbHalfHeight, Path.Direction.Cw);
             }
         }

@@ -260,7 +251,7 @@

         public void SetTextAboveThumbsColor(Color textAboveThumbsColor)
         {
-            _textAboveThumbsColor = textAboveThumbsColor;
+            TextAboveThumbsColor = textAboveThumbsColor;
             Invalidate();
         }

@@ -290,34 +281,28 @@
             SetSelectedMaxValue(AbsoluteMaxValue);
         }

-        /**
-         * Returns the absolute minimum value of the range that has been set at construction time.
-         *
-         * @return The absolute minimum value of the range.
-         */
-
+        /// <summary>
+        /// Returns the absolute minimum value of the range that has been set at construction time.
+        /// </summary>
+        /// <returns>The absolute minimum value of the range.</returns>
         public float GetAbsoluteMinValue()
         {
             return AbsoluteMinValue;
         }

-        /**
-         * Returns the absolute maximum value of the range that has been set at construction time.
-         *
-         * @return The absolute maximum value of the range.
-         */
-
+        /// <summary>
+        /// Returns the absolute maximum value of the range that has been set at construction time.
+        /// </summary>
+        /// <returns>The absolute maximum value of the range.</returns>
         public float GetAbsoluteMaxValue()
         {
             return AbsoluteMaxValue;
         }

-        /**
-         * Returns the currently selected min value.
-         *
-         * @return The currently selected min value.
-         */
-
+        /// <summary>
+        /// Returns the currently selected min value.
+        /// </summary>
+        /// <returns>The currently selected min value.</returns>
         public float GetSelectedMinValue()
         {
             return NormalizedToValue(NormalizedMinValue);
@@ -513,7 +498,7 @@
             var pointerIndex = ev.FindPointerIndex(_activePointerId);
             var x = ev.GetX(pointerIndex);

-            if (Thumb.Min.Equals(_pressedThumb) && !_singleThumb)
+            if (Thumb.Min.Equals(_pressedThumb) && !SingleThumb)
             {
                 SetNormalizedMinValue(ScreenToNormalized(x));
             }
@@ -558,9 +543,9 @@
                 width = MeasureSpec.GetSize(widthMeasureSpec);
             }

-            var height = _thumbImage.Height
-                         + (!_showTextAboveThumbs ? 0 : PixelUtil.DpToPx(Context, HeightInDp))
-                         + (_thumbShadow ? _thumbShadowYOffset + _thumbShadowBlur : 0);
+            var height = ThumbImage.Height
+                         + (!ShowTextAboveThumbs ? 0 : PixelUtil.DpToPx(Context, HeightInDp))
+                         + (ThumbShadow ? ThumbShadowYOffset + _thumbShadowBlur : 0);
             if (MeasureSpecMode.Unspecified != MeasureSpec.GetMode(heightMeasureSpec))
             {
                 height = Math.Min(height, MeasureSpec.GetSize(heightMeasureSpec));
@@ -577,11 +562,11 @@

             _paint.TextSize = _textSize;
             _paint.SetStyle(Paint.Style.Fill);
-            _paint.Color = _defaultColor;
+            _paint.Color = DefaultColor;
             _paint.AntiAlias = true;
             float minMaxLabelSize = 0;

-            if (_showLabels)
+            if (ShowLabels)
             {
                 // draw min and max labels
                 var minLabel = Context.GetString(Resource.String.demo_min_label);
@@ -601,11 +586,11 @@
             var selectedValuesAreDefault = NormalizedMinValue <= MinDeltaForDefault &&
                                            NormalizedMaxValue >= 1 - MinDeltaForDefault;

-            var colorToUseForButtonsAndHighlightedLine = !_alwaysActive && !_activateOnDefaultValues &&
+            var colorToUseForButtonsAndHighlightedLine = !AlwaysActive && !ActivateOnDefaultValues &&
                                                          selectedValuesAreDefault
-                ? _defaultColor
+                ? DefaultColor
                 : // default values
-                _activeColor; // non default, filter is active
+                ActiveColor; // non default, filter is active

             // draw seek bar active range line
             _rect.Left = NormalizedToScreen(NormalizedMinValue);
@@ -615,9 +600,9 @@
             canvas.DrawRect(_rect, _paint);

             // draw minimum thumb (& shadow if requested) if not a single thumb control
-            if (!_singleThumb)
-            {
-                if (_thumbShadow)
+            if (!SingleThumb)
+            {
+                if (ThumbShadow)
                 {
                     DrawThumbShadow(NormalizedToScreen(NormalizedMinValue), canvas);
                 }
@@ -626,7 +611,7 @@
             }

             // draw maximum thumb & shadow (if necessary)
-            if (_thumbShadow)
+            if (ThumbShadow)
             {
                 DrawThumbShadow(NormalizedToScreen(NormalizedMaxValue), canvas);
             }
@@ -634,11 +619,11 @@
                 selectedValuesAreDefault);

             // draw the text if sliders have moved from default edges
-            if (!_showTextAboveThumbs || (!_activateOnDefaultValues && selectedValuesAreDefault))
+            if (!ShowTextAboveThumbs || (!ActivateOnDefaultValues && selectedValuesAreDefault))
                 return;

             _paint.TextSize = _textSize;
-            _paint.Color = _textAboveThumbsColor;
+            _paint.Color = TextAboveThumbsColor;

             var minText = ValueToString(GetSelectedMinValue());
             var maxText = ValueToString(GetSelectedMaxValue());
@@ -649,7 +634,7 @@
             var maxPosition = Math.Min(Width - maxTextWidth,
                 NormalizedToScreen(NormalizedMaxValue) - maxTextWidth*0.5f);

-            if (!_singleThumb)
+            if (!SingleThumb)
             {
                 // check if the labels overlap, or are too close to each other
                 var spacing = PixelUtil.DpToPx(Context, TextLateralPaddingInDp);
@@ -679,7 +664,9 @@
         }

         /// <summary>
-        /// Overridden to save instance state when device orientation changes. This method is called automatically if you assign an id to the RangeSliderControl widget using the Id. Other members of this class than the normalized min and max values don't need to be saved.
+        ///     Overridden to save instance state when device orientation changes. This method is called automatically if you
+        ///     assign an id to the RangeSliderControl widget using the Id. Other members of this class than the normalized min and
+        ///     max values don't need to be saved.
         /// </summary>
         protected override IParcelable OnSaveInstanceState()
         {
@@ -691,7 +678,8 @@
         }

         /// <summary>
-        ///  Overridden to restore instance state when device orientation changes. This method is called automatically if you assign an id to the RangeSliderControl widget using the {@link #setId(int)} method.
+        ///     Overridden to restore instance state when device orientation changes. This method is called automatically if you
+        ///     assign an id to the RangeSliderControl widget using the {@link #setId(int)} method.
         /// </summary>
         protected override void OnRestoreInstanceState(IParcelable parcel)
         {
@@ -702,7 +690,7 @@
         }

         /// <summary>
-        /// Draws the "normal" resp. "pressed" thumb image on specified x-coordinate.
+        ///     Draws the "normal" resp. "pressed" thumb image on specified x-coordinate.
         /// </summary>
         /// <param name="screenCoord">The x-coordinate in screen space where to draw the image.</param>
         /// <param name="pressed">Is the thumb currently in "pressed" state?</param>
@@ -711,13 +699,13 @@
         private void DrawThumb(float screenCoord, bool pressed, Canvas canvas, bool areSelectedValuesDefault)
         {
             Bitmap buttonToDraw;
-            if (!_activateOnDefaultValues && areSelectedValuesDefault)
-            {
-                buttonToDraw = _thumbDisabledImage;
+            if (!ActivateOnDefaultValues && areSelectedValuesDefault)
+            {
+                buttonToDraw = ThumbDisabledImage;
             }
             else
             {
-                buttonToDraw = pressed ? _thumbPressedImage : _thumbImage;
+                buttonToDraw = pressed ? ThumbPressedImage : ThumbImage;
             }

             canvas.DrawBitmap(buttonToDraw, screenCoord - _thumbHalfWidth,
@@ -725,14 +713,14 @@
         }

         /// <summary>
-        /// Draws a drop shadow beneath the slider thumb.
+        ///     Draws a drop shadow beneath the slider thumb.
         /// </summary>
         /// <param name="screenCoord">the x-coordinate of the slider thumb</param>
         /// <param name="canvas">the canvas on which to draw the shadow</param>
         private void DrawThumbShadow(float screenCoord, Canvas canvas)
         {
-            _thumbShadowMatrix.SetTranslate(screenCoord + _thumbShadowXOffset,
-                _textOffset + _thumbHalfHeight + _thumbShadowYOffset);
+            _thumbShadowMatrix.SetTranslate(screenCoord + ThumbShadowXOffset,
+                _textOffset + _thumbHalfHeight + ThumbShadowYOffset);
             _translatedThumbShadowPath.Set(_thumbShadowPath);
             _translatedThumbShadowPath.Transform(_thumbShadowMatrix);
             canvas.DrawPath(_translatedThumbShadowPath, _shadowPaint);
@@ -767,7 +755,8 @@
         }

         /// <summary>
-        /// Decides if given x-coordinate in screen space needs to be interpreted as "within" the normalized thumb x-coordinate.
+        ///     Decides if given x-coordinate in screen space needs to be interpreted as "within" the normalized thumb
+        ///     x-coordinate.
         /// </summary>
         /// <param name="touchX">The x-coordinate in screen space to check.</param>
         /// <param name="normalizedThumbValue">The normalized x-coordinate of the thumb to check.</param>


Enable exception logging

Enable exception logging

--- pass-winmenu/src/Logger.cs
+++ pass-winmenu/src/Logger.cs
@@ -36,6 +36,11 @@
 		{
 			SendRaw("An unhandled exception occurred. Stack trace:");
 			LogExceptionAsText(unhandledExceptionEventArgs.ExceptionObject as Exception, 0);
+		}
+
+		public static void ReportException(Exception e)
+		{
+			LogExceptionAsText(e, 0);
 		}

 		private static void LogExceptionAsText(Exception e, int level)


generator: Fix handle being passed when type is a struct

A static getter method would always generate a Handle parameter even
though some types do not have a Handle, for example structs.

Closes issue #99.

Signed-off-by: Bertrand Lorentz <eb7ac131ef7bff6d2ebccd6e5bf9a7cb6485cf2c@gmail.com>

--- generator/Method.cs
+++ generator/Method.cs
@@ -243,7 +243,7 @@
 						return;
 					else {
 						is_set = false;
-						call = "(Handle, " + Body.GetCallString (false) + ")";
+						call = "(" + (IsStatic ? "" : container_type.CallByName () + (parms.Count > 0 ? ", " : "")) + Body.GetCallString (false) + ")";
 						comp = null;
 					}
 				}


Add SupportedLanguageNames.

Add SupportedLanguageNames.

--- osu.Framework/Localisation/LocalisationEngine.cs
+++ osu.Framework/Localisation/LocalisationEngine.cs
@@ -15,7 +15,8 @@
         private Bindable<bool> preferUnicode;
         private Bindable<string> locale;

-        public virtual string[] SupportedLocales => new[] { "en" };
+        public virtual IEnumerable<string> SupportedLocales => new[] { "en" };
+        public IEnumerable<string> SupportedLanguageNames => SupportedLocales.Select(x => new CultureInfo(x).DisplayName);

         [BackgroundDependencyLoader]
         private void load(FrameworkConfigManager config)


Fix memory leak when using the SDL2 clipboard

--- osu.Framework/Platform/Linux/Sdl/SdlClipboard.cs
+++ osu.Framework/Platform/Linux/Sdl/SdlClipboard.cs
@@ -1,6 +1,7 @@
 // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
 // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE

+using System;
 using System.Runtime.InteropServices;

 namespace osu.Framework.Platform.Linux.Sdl
@@ -8,6 +9,9 @@
     public class SdlClipboard : Clipboard
     {
         private const string lib = "libSDL2-2.0";
+
+        [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_free", ExactSpelling = true)]
+        internal static extern void SDL_free(IntPtr ptr);

         [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetClipboardText", ExactSpelling = true)]
         internal static extern string SDL_GetClipboardText();
@@ -17,7 +21,10 @@

         public override string GetText()
         {
-            return SDL_GetClipboardText();
+            string text = SDL_GetClipboardText();
+            IntPtr ptrToText = Marshal.StringToHGlobalAnsi(text);
+            SDL_free(ptrToText);
+            return text;
         }

         public override void SetText(string selectedText)


nerfed rhythm further to attempt to balance

--- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
+++ osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
@@ -21,7 +21,7 @@
         private const double pi_over_4 = Math.PI / 4;
         private const double pi_over_2 = Math.PI / 2;

-        private const double rhythm_multiplier = 0.75;
+        private const double rhythm_multiplier = 0.5;
         private const int history_time_max = 5000; // 5 seconds of calculatingRhythmBonus max.

         private double skillMultiplier => 1375;


Change the order of global bindings to give overlays lowest priority

--- osu.Game/Input/Bindings/GlobalActionContainer.cs
+++ osu.Game/Input/Bindings/GlobalActionContainer.cs
@@ -31,14 +31,17 @@
             parentInputManager = GetContainingInputManager();
         }

-        // IMPORTANT: Do not change the order of key bindings in this list.
-        // It is used to decide the order of precedence (see note in DatabasedKeyBindingContainer).
+        // IMPORTANT: Take care when changing order of the items in the enumerable.
+        // It is used to decide the order of precedence, with the earlier items having higher precedence.
         public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings
-                                                                       .Concat(OverlayKeyBindings)
                                                                        .Concat(EditorKeyBindings)
                                                                        .Concat(InGameKeyBindings)
                                                                        .Concat(SongSelectKeyBindings)
-                                                                       .Concat(AudioControlKeyBindings);
+                                                                       .Concat(AudioControlKeyBindings)
+                                                                       // Overlay bindings may conflict with more local cases like the editor so they are checked last.
+                                                                       // It has generally been agreed on that local screens like the editor should have priority,
+                                                                       // based on such usages potentially requiring a lot more key bindings that may be "shared" with global ones.
+                                                                       .Concat(OverlayKeyBindings);

         public IEnumerable<KeyBinding> GlobalKeyBindings => new[]
         {


revert globalaction changes

revert globalaction changes

--- osu.Game/Input/Bindings/GlobalActionContainer.cs
+++ osu.Game/Input/Bindings/GlobalActionContainer.cs
@@ -7,7 +7,6 @@
 using osu.Framework.Graphics;
 using osu.Framework.Input;
 using osu.Framework.Input.Bindings;
-using osu.Game.Graphics.UserInterface;

 namespace osu.Game.Input.Bindings
 {
@@ -56,11 +55,8 @@
             new KeyBinding(new[] { InputKey.Control, InputKey.Minus }, GlobalAction.DecreaseScrollSpeed),
         };

-        /// <summary>
-        /// Make sure that the <see cref="OsuGame"/> handles global input first, and that <see cref="BackButton"/> handles global input last.
-        /// </summary>
         protected override IEnumerable<Drawable> KeyBindingInputQueue =>
-            (handler == null ? base.KeyBindingInputQueue : base.KeyBindingInputQueue.Prepend(handler)).OrderBy(d => d is BackButton);
+            handler == null ? base.KeyBindingInputQueue : base.KeyBindingInputQueue.Prepend(handler);
     }

     public enum GlobalAction


[trunk] Put the QMake top level .pro file into the build root, so that subdirs do not contain special characters.

--- packages/QMakeBuilder/dev/Scripts/PostExecute.cs
+++ packages/QMakeBuilder/dev/Scripts/PostExecute.cs
@@ -41,7 +41,7 @@

             var mainPackage = Opus.Core.State.PackageInfo[0];
             string proFileName = mainPackage + ".pro";
-            string rootDirectory = mainPackage.BuildDirectory;
+            string rootDirectory = Opus.Core.State.BuildRoot;
             string proFilePath = System.IO.Path.Combine(rootDirectory, proFileName);

             // relative paths need a trailing slash to work


fixed a problem where token request from unknown client resulted in a null item. This resulted in NRE in the cache. @brockallen - best place to fix here? please review

--- source/Core/Extensions/ICacheExtensions.cs
+++ source/Core/Extensions/ICacheExtensions.cs
@@ -50,7 +50,11 @@
             if (item == null)
             {
                 item = await get();
-                await cache.SetAsync(key, item);
+
+                if (item != null)
+                {
+                    await cache.SetAsync(key, item);
+                }
             }

             return item;


Send data always as application/octet-stream

--- FubarDev.FtpServer.FileSystem.GoogleDrive/BackgroundUpload.cs
+++ FubarDev.FtpServer.FileSystem.GoogleDrive/BackgroundUpload.cs
@@ -40,7 +40,7 @@
         {
             using (var stream = new FileStream(_tempFileName, FileMode.Open))
             {
-                await _fileSystem.Service.UploadAsync(File, stream, cancellationToken);
+                await _fileSystem.Service.UploadAsync(File.Id, stream, "application/octet-stream", cancellationToken);
             }
         }


Stretch the console window

Stretch the console window

--- GitBackup.FileBackup/Program.cs
+++ GitBackup.FileBackup/Program.cs
@@ -15,6 +15,17 @@
             Console.WriteLine("GitBackup is a tool to create incremental backups in a git flavour.");
             Console.WriteLine("===================================================================");
             Console.WriteLine ();
+
+            //Try to expand the console window
+            try
+            {
+                Console.WindowWidth = Console.BufferWidth = 150;
+            }
+// ReSharper disable EmptyGeneralCatchClause
+            catch
+// ReSharper restore EmptyGeneralCatchClause
+            {
+            }

             Trace.Listeners.Add(new ConsoleTraceListener ());


added namespace GitSharp.Core.Diff to MyersDiff.cs. it seems to have been forgotten

--- GitSharp.Core/Diff/MyersDiff.cs
+++ GitSharp.Core/Diff/MyersDiff.cs
@@ -89,462 +89,464 @@
  * albeit with a larger constant factor.
  */
 using System;
-using GitSharp.Core.Diff;
 using GitSharp.Core.Util;

-public class MyersDiff {
-	/**
-	 * The list of edits found during the last call to {@link #calculateEdits()}
-	 */
-	protected EditList edits;
-
-	/**
-	 * The first text to be compared. Referred to as "Text A" in the comments
-	 */
-	protected Sequence a;
-
-	/**
-	 * The second text to be compared. Referred to as "Text B" in the comments
-	 */
-	protected Sequence b;
-
-	/**
-	 * The only constructor
-	 *
-	 * @param a   the text A which should be compared
-	 * @param b   the text B which should be compared
-	 */
-	public MyersDiff(Sequence a, Sequence b) {
-		this.a = a;
-		this.b = b;
-	    middle = new MiddleEdit(a, b);
-		calculateEdits();
-	}
-
-	/**
-	 * @return the list of edits found during the last call to {@link #calculateEdits()}
-	 */
-	public EditList getEdits() {
-		return edits;
-	}
-
-	// TODO: use ThreadLocal for future multi-threaded operations
-	MiddleEdit middle;
-
-	/**
-	 * Entrypoint into the algorithm this class is all about. This method triggers that the
-	 * differences between A and B are calculated in form of a list of edits.
-	 */
-	protected void calculateEdits() {
-		edits = new EditList();
-
-		middle.initialize(0, a.size(), 0, b.size());
-		if (middle.beginA >= middle.endA &&
+namespace GitSharp.Core.Diff
+{
+	public class MyersDiff {
+		/**
+	     * The list of edits found during the last call to {@link #calculateEdits()}
+	     */
+		protected EditList edits;
+
+		/**
+	     * The first text to be compared. Referred to as "Text A" in the comments
+	     */
+		protected Sequence a;
+
+		/**
+	     * The second text to be compared. Referred to as "Text B" in the comments
+	     */
+		protected Sequence b;
+
+		/**
+	     * The only constructor
+	     *
+	     * @param a   the text A which should be compared
+	     * @param b   the text B which should be compared
+	     */
+		public MyersDiff(Sequence a, Sequence b) {
+			this.a = a;
+			this.b = b;
+			middle = new MiddleEdit(a, b);
+			calculateEdits();
+		}
+
+		/**
+	     * @return the list of edits found during the last call to {@link #calculateEdits()}
+	     */
+		public EditList getEdits() {
+			return edits;
+		}
+
+		// TODO: use ThreadLocal for future multi-threaded operations
+		MiddleEdit middle;
+
+		/**
+	     * Entrypoint into the algorithm this class is all about. This method triggers that the
+	     * differences between A and B are calculated in form of a list of edits.
+	     */
+		protected void calculateEdits() {
+			edits = new EditList();
+
+			middle.initialize(0, a.size(), 0, b.size());
+			if (middle.beginA >= middle.endA &&
 				middle.beginB >= middle.endB)
-			return;
-
-		calculateEdits(middle.beginA, middle.endA,
+				return;
+
+			calculateEdits(middle.beginA, middle.endA,
 				middle.beginB, middle.endB);
-	}
-
-	/*
-	 * Calculates the differences between a given part of A against another given part of B
-	 * @param beginA start of the part of A which should be compared (0<=beginA<sizeof(A))
-	 * @param endA end of the part of A which should be compared (beginA<=endA<sizeof(A))
-	 * @param beginB start of the part of B which should be compared (0<=beginB<sizeof(B))
-	 * @param endB end of the part of B which should be compared (beginB<=endB<sizeof(B))
-	 */
-	protected void calculateEdits(int beginA, int endA,
+		}
+
+		/*
+	     * Calculates the differences between a given part of A against another given part of B
+	     * @param beginA start of the part of A which should be compared (0<=beginA<sizeof(A))
+	     * @param endA end of the part of A which should be compared (beginA<=endA<sizeof(A))
+	     * @param beginB start of the part of B which should be compared (0<=beginB<sizeof(B))
+	     * @param endB end of the part of B which should be compared (beginB<=endB<sizeof(B))
+	     */
+		protected void calculateEdits(int beginA, int endA,
 			int beginB, int endB) {
-		Edit edit = middle.calculate(beginA, endA, beginB, endB);
-
-		if (beginA < edit.BeginA || beginB < edit.BeginB) {
-			int k = edit.BeginB - edit.BeginA;
-			int x = middle.backward.snake(k, edit.BeginA);
-			calculateEdits(beginA, x, beginB, k + x);
-		}
-
-		if (edit.EditType != Edit.Type.EMPTY)
-            edits.Add(edit);
-
-
-		// after middle
-		if (endA > edit.EndA || endB > edit.EndB) {
-			int k = edit.EndB - edit.EndA;
-			int x = middle.forward.snake(k, edit.EndA);
-			calculateEdits(x, endA, k + x, endB);
-		}
-	}
-
-	/**
-	 * A class to help bisecting the sequences a and b to find minimal
-	 * edit paths.
-	 *
-	 * As the arrays are reused for space efficiency, you will need one
-	 * instance per thread.
-	 *
-	 * The entry function is the calculate() method.
-	 */
-	class MiddleEdit {
-	    private readonly Sequence _a;
-	    private readonly Sequence _b;
-
-	    public MiddleEdit(Sequence a, Sequence b)
-	    {
-	        _a = a;
-	        _b = b;
-            forward = new ForwardEditPaths(this);
-            backward = new BackwardEditPaths(this);
-	    }
-
-	    public void initialize(int beginA, int endA, int beginB, int endB) {
-			this.beginA = beginA; this.endA = endA;
-			this.beginB = beginB; this.endB = endB;
-
-			// strip common parts on either end
-			int k = beginB - beginA;
-			this.beginA = forward.snake(k, beginA);
-			this.beginB = k + this.beginA;
-
-			k = endB - endA;
-			this.endA = backward.snake(k, endA);
-			this.endB = k + this.endA;
-		}
-
-		/*
-		 * This function calculates the "middle" Edit of the shortest
-		 * edit path between the given subsequences of a and b.
-		 *
-		 * Once a forward path and a backward path meet, we found the
-		 * middle part.  From the last snake end point on both of them,
-		 * we construct the Edit.
-		 *
-		 * It is assumed that there is at least one edit in the range.
-		 */
-		// TODO: measure speed impact when this is synchronized
-	    public Edit calculate(int beginA, int endA, int beginB, int endB) {
-			if (beginA == endA || beginB == endB)
-				return new Edit(beginA, endA, beginB, endB);
-			this.beginA = beginA; this.endA = endA;
-			this.beginB = beginB; this.endB = endB;
+			Edit edit = middle.calculate(beginA, endA, beginB, endB);
+
+			if (beginA < edit.BeginA || beginB < edit.BeginB) {
+				int k = edit.BeginB - edit.BeginA;
+				int x = middle.backward.snake(k, edit.BeginA);
+				calculateEdits(beginA, x, beginB, k + x);
+			}
+
+			if (edit.EditType != Edit.Type.EMPTY)
+				edits.Add(edit);
+
+
+			// after middle
+			if (endA > edit.EndA || endB > edit.EndB) {
+				int k = edit.EndB - edit.EndA;
+				int x = middle.forward.snake(k, edit.EndA);
+				calculateEdits(x, endA, k + x, endB);
+			}
+			}
+
+		/**
+	     * A class to help bisecting the sequences a and b to find minimal
+	     * edit paths.
+	     *
+	     * As the arrays are reused for space efficiency, you will need one
+	     * instance per thread.
+	     *
+	     * The entry function is the calculate() method.
+	     */
+		class MiddleEdit {
+			private readonly Sequence _a;
+			private readonly Sequence _b;
+
+			public MiddleEdit(Sequence a, Sequence b)
+			{
+				_a = a;
+				_b = b;
+				forward = new ForwardEditPaths(this);
+				backward = new BackwardEditPaths(this);
+			}
+
+			public void initialize(int beginA, int endA, int beginB, int endB) {
+				this.beginA = beginA; this.endA = endA;
+				this.beginB = beginB; this.endB = endB;
+
+				// strip common parts on either end
+				int k = beginB - beginA;
+				this.beginA = forward.snake(k, beginA);
+				this.beginB = k + this.beginA;
+
+				k = endB - endA;
+				this.endA = backward.snake(k, endA);
+				this.endB = k + this.endA;
+			}

 			/*
-			 * Following the conventions in Myers' paper, "k" is
-			 * the difference between the index into "b" and the
-			 * index into "a".
-			 */
-			int minK = beginB - endA;
-			int maxK = endB - beginA;
-
-			forward.initialize(beginB - beginA, beginA, minK, maxK);
-			backward.initialize(endB - endA, endA, minK, maxK);
-
-			for (int d = 1; ; d++)
-				if (forward.calculate(d) ||
+		     * This function calculates the "middle" Edit of the shortest
+		     * edit path between the given subsequences of a and b.
+		     *
+		     * Once a forward path and a backward path meet, we found the
+		     * middle part.  From the last snake end point on both of them,
+		     * we construct the Edit.
+		     *
+		     * It is assumed that there is at least one edit in the range.
+		     */
+			// TODO: measure speed impact when this is synchronized
+			public Edit calculate(int beginA, int endA, int beginB, int endB) {
+				if (beginA == endA || beginB == endB)
+					return new Edit(beginA, endA, beginB, endB);
+				this.beginA = beginA; this.endA = endA;
+				this.beginB = beginB; this.endB = endB;
+
+				/*
+			     * Following the conventions in Myers' paper, "k" is
+			     * the difference between the index into "b" and the
+			     * index into "a".
+			     */
+				int minK = beginB - endA;
+				int maxK = endB - beginA;
+
+				forward.initialize(beginB - beginA, beginA, minK, maxK);
+				backward.initialize(endB - endA, endA, minK, maxK);
+
+				for (int d = 1; ; d++)
+					if (forward.calculate(d) ||
 						backward.calculate(d))
+					{
+						return _edit;
+					}
+			}
+
+			/*
+		     * For each d, we need to hold the d-paths for the diagonals
+		     * k = -d, -d + 2, ..., d - 2, d.  These are stored in the
+		     * forward (and backward) array.
+		     *
+		     * As we allow subsequences, too, this needs some refinement:
+		     * the forward paths start on the diagonal forwardK =
+		     * beginB - beginA, and backward paths start on the diagonal
+		     * backwardK = endB - endA.
+		     *
+		     * So, we need to hold the forward d-paths for the diagonals
+		     * k = forwardK - d, forwardK - d + 2, ..., forwardK + d and
+		     * the analogue for the backward d-paths.  This means that
+		     * we can turn (k, d) into the forward array index using this
+		     * formula:
+		     *
+		     *	i = (d + k - forwardK) / 2
+		     *
+		     * There is a further complication: the edit paths should not
+		     * leave the specified subsequences, so k is bounded by
+		     * minK = beginB - endA and maxK = endB - beginA.  However,
+		     * (k - forwardK) _must_ be odd whenever d is odd, and it
+		     * _must_ be even when d is even.
+		     *
+		     * The values in the "forward" and "backward" arrays are
+		     * positions ("x") in the sequence a, to get the corresponding
+		     * positions ("y") in the sequence b, you have to calculate
+		     * the appropriate k and then y:
+		     *
+		     *	k = forwardK - d + i * 2
+		     *	y = k + x
+		     *
+		     * (substitute backwardK for forwardK if you want to get the
+		     * y position for an entry in the "backward" array.
+		     */
+			public EditPaths forward;
+			public EditPaths backward;
+
+			/* Some variables which are shared between methods */
+			public int beginA;
+			public int endA;
+			public int beginB;
+			public int endB;
+			protected Edit _edit;
+
+			internal abstract class EditPaths {
+				protected readonly MiddleEdit _middleEdit;
+				private IntList x = new IntList();
+				private LongList _snake = new LongList();
+				public int beginK;
+				public int endK;
+				public int middleK;
+				int prevBeginK, prevEndK;
+				/* if we hit one end early, no need to look further */
+				protected int minK, maxK; // TODO: better explanation
+
+				protected EditPaths(MiddleEdit middleEdit)
 				{
-                    return _edit;
-				}
-		}
-
-		/*
-		 * For each d, we need to hold the d-paths for the diagonals
-		 * k = -d, -d + 2, ..., d - 2, d.  These are stored in the
-		 * forward (and backward) array.
-		 *
-		 * As we allow subsequences, too, this needs some refinement:
-		 * the forward paths start on the diagonal forwardK =
-		 * beginB - beginA, and backward paths start on the diagonal
-		 * backwardK = endB - endA.
-		 *
-		 * So, we need to hold the forward d-paths for the diagonals
-		 * k = forwardK - d, forwardK - d + 2, ..., forwardK + d and
-		 * the analogue for the backward d-paths.  This means that
-		 * we can turn (k, d) into the forward array index using this
-		 * formula:
-		 *
-		 *	i = (d + k - forwardK) / 2
-		 *
-		 * There is a further complication: the edit paths should not
-		 * leave the specified subsequences, so k is bounded by
-		 * minK = beginB - endA and maxK = endB - beginA.  However,
-		 * (k - forwardK) _must_ be odd whenever d is odd, and it
-		 * _must_ be even when d is even.
-		 *
-		 * The values in the "forward" and "backward" arrays are
-		 * positions ("x") in the sequence a, to get the corresponding
-		 * positions ("y") in the sequence b, you have to calculate
-		 * the appropriate k and then y:
-		 *
-		 *	k = forwardK - d + i * 2
-		 *	y = k + x
-		 *
-		 * (substitute backwardK for forwardK if you want to get the
-		 * y position for an entry in the "backward" array.
-		 */
-	    public EditPaths forward;
-	    public EditPaths backward;
-
-		/* Some variables which are shared between methods */
-	    public int beginA;
-	    public int endA;
-	    public int beginB;
-	    public int endB;
-	    protected Edit _edit;
-
-	    internal abstract class EditPaths {
-	        protected readonly MiddleEdit _middleEdit;
-	        private IntList x = new IntList();
-			private LongList _snake = new LongList();
-	        public int beginK;
-	        public int endK;
-	        public int middleK;
-			int prevBeginK, prevEndK;
-			/* if we hit one end early, no need to look further */
-			protected int minK, maxK; // TODO: better explanation
-
-	        protected EditPaths(MiddleEdit middleEdit)
-	        {
-                _middleEdit = middleEdit;
-	        }
-
-	        int getIndex(int d, int k) {
+					_middleEdit = middleEdit;
+				}
+
+				int getIndex(int d, int k) {
 // TODO: remove
-if (((d + k - middleK) % 2) == 1)
-	throw new InvalidOperationException("odd: " + d + " + " + k + " - " + middleK);
-				return (d + k - middleK) / 2;
-			}
-
-	        public int getX(int d, int k) {
+					if (((d + k - middleK) % 2) == 1)
+						throw new InvalidOperationException("odd: " + d + " + " + k + " - " + middleK);
+					return (d + k - middleK) / 2;
+				}
+
+				public int getX(int d, int k) {
 // TODO: remove
-if (k < beginK || k > endK)
-	throw new InvalidOperationException("k " + k + " not in " + beginK + " - " + endK);
-				return x.get(getIndex(d, k));
-			}
-
-	        public long getSnake(int d, int k) {
+					if (k < beginK || k > endK)
+						throw new InvalidOperationException("k " + k + " not in " + beginK + " - " + endK);
+					return x.get(getIndex(d, k));
+				}
+
+				public long getSnake(int d, int k) {
 // TODO: remove
-if (k < beginK || k > endK)
-	throw new InvalidOperationException("k " + k + " not in " + beginK + " - " + endK);
-				return _snake.get(getIndex(d, k));
-			}
-
-			private int forceKIntoRange(int k) {
-				/* if k is odd, so must be the result */
-				if (k < minK)
-					return minK + ((k ^ minK) & 1);
-				else if (k > maxK)
-					return maxK - ((k ^ maxK) & 1);
-				return k;
-			}
-
-		    public void initialize(int k, int x, int minK, int maxK) {
-				this.minK = minK;
-				this.maxK = maxK;
-				beginK = endK = middleK = k;
-				this.x.clear();
-				this.x.add(x);
-				_snake.clear();
-				_snake.add(newSnake(k, x));
-			}
-
-		    public abstract int snake(int k, int x);
-		    protected abstract int getLeft(int x);
-		    protected abstract int getRight(int x);
-		    protected abstract bool isBetter(int left, int right);
-		    protected abstract void adjustMinMaxK(int k, int x);
-		    protected abstract bool meets(int d, int k, int x, long snake);
-
-			long newSnake(int k, int x) {
-				long y = k + x;
-				long ret = ((long) x) << 32;
-				return ret | y;
-			}
-
-			int snake2x(long snake) {
-				return (int) ((ulong)snake >> 32);
-			}
-
-			int snake2y(long snake) {
-				return (int) snake;
-			}
-
-	        protected bool makeEdit(long snake1, long snake2) {
-				int x1 = snake2x(snake1), x2 = snake2x(snake2);
-				int y1 = snake2y(snake1), y2 = snake2y(snake2);
-
-                /*
-				 * Check for incompatible partial edit paths:
-				 * when there are ambiguities, we might have
-				 * hit incompatible (i.e. non-overlapping)
-				 * forward/backward paths.
-				 *
-				 * In that case, just pretend that we have
-				 * an empty edit at the end of one snake; this
-				 * will force a decision which path to take
-				 * in the next recursion step.
-				 */
-				if (x1 > x2 || y1 > y2) {
-					x1 = x2;
-					y1 = y2;
-				}
-				_middleEdit._edit = new Edit(x1, x2, y1, y2);
-				return true;
-			}
-
-		    public bool calculate(int d) {
-                prevBeginK = beginK;
-				prevEndK = endK;
-				beginK = forceKIntoRange(middleK - d);
-				endK = forceKIntoRange(middleK + d);
-				// TODO: handle i more efficiently
-				// TODO: walk snake(k, getX(d, k)) only once per (d, k)
-				// TODO: move end points out of the loop to avoid conditionals inside the loop
-				// go backwards so that we can avoid temp vars
-				for (int k = endK; k >= beginK; k -= 2) {
-					int left = -1, right = -1;
-					long leftSnake = -1L, rightSnake = -1L;
-					// TODO: refactor into its own function
-				    int i;
-                    if (k > prevBeginK) {
-						i = getIndex(d - 1, k - 1);
-						left = x.get(i);
-						int end = snake(k - 1, left);
-						leftSnake = left != end ?
-							newSnake(k - 1, end) :
-							_snake.get(i);
-
-						if (meets(d, k - 1, end, leftSnake))
+					if (k < beginK || k > endK)
+						throw new InvalidOperationException("k " + k + " not in " + beginK + " - " + endK);
+					return _snake.get(getIndex(d, k));
+				}
+
+				private int forceKIntoRange(int k) {
+					/* if k is odd, so must be the result */
+					if (k < minK)
+						return minK + ((k ^ minK) & 1);
+					else if (k > maxK)
+						return maxK - ((k ^ maxK) & 1);
+					return k;
+				}
+
+				public void initialize(int k, int x, int minK, int maxK) {
+					this.minK = minK;
+					this.maxK = maxK;
+					beginK = endK = middleK = k;
+					this.x.clear();
+					this.x.add(x);
+					_snake.clear();
+					_snake.add(newSnake(k, x));
+				}
+
+				public abstract int snake(int k, int x);
+				protected abstract int getLeft(int x);
+				protected abstract int getRight(int x);
+				protected abstract bool isBetter(int left, int right);
+				protected abstract void adjustMinMaxK(int k, int x);
+				protected abstract bool meets(int d, int k, int x, long snake);
+
+				long newSnake(int k, int x) {
+					long y = k + x;
+					long ret = ((long) x) << 32;
+					return ret | y;
+				}
+
+				int snake2x(long snake) {
+					return (int) ((ulong)snake >> 32);
+				}
+
+				int snake2y(long snake) {
+					return (int) snake;
+				}
+
+				protected bool makeEdit(long snake1, long snake2) {
+					int x1 = snake2x(snake1), x2 = snake2x(snake2);
+					int y1 = snake2y(snake1), y2 = snake2y(snake2);
+
+					/*
+				     * Check for incompatible partial edit paths:
+				     * when there are ambiguities, we might have
+				     * hit incompatible (i.e. non-overlapping)
+				     * forward/backward paths.
+				     *
+				     * In that case, just pretend that we have
+				     * an empty edit at the end of one snake; this
+				     * will force a decision which path to take
+				     * in the next recursion step.
+				     */
+					if (x1 > x2 || y1 > y2) {
+						x1 = x2;
+						y1 = y2;
+					}
+					_middleEdit._edit = new Edit(x1, x2, y1, y2);
+					return true;
+				}
+
+				public bool calculate(int d) {
+					prevBeginK = beginK;
+					prevEndK = endK;
+					beginK = forceKIntoRange(middleK - d);
+					endK = forceKIntoRange(middleK + d);
+					// TODO: handle i more efficiently
+					// TODO: walk snake(k, getX(d, k)) only once per (d, k)
+					// TODO: move end points out of the loop to avoid conditionals inside the loop
+					// go backwards so that we can avoid temp vars
+					for (int k = endK; k >= beginK; k -= 2) {
+						int left = -1, right = -1;
+						long leftSnake = -1L, rightSnake = -1L;
+						// TODO: refactor into its own function
+						int i;
+						if (k > prevBeginK) {
+							i = getIndex(d - 1, k - 1);
+							left = x.get(i);
+							int end = snake(k - 1, left);
+							leftSnake = left != end ?
+														newSnake(k - 1, end) :
+																				 _snake.get(i);
+
+							if (meets(d, k - 1, end, leftSnake))
+								return true;
+							left = getLeft(end);
+						}
+						if (k < prevEndK) {
+							i = getIndex(d - 1, k + 1);
+							right = x.get(i);
+							int end = snake(k + 1, right);
+							rightSnake = right != end ?
+														  newSnake(k + 1, end) :
+																				   _snake.get(i);
+
+							if (meets(d, k + 1, end, rightSnake))
+								return true;
+							right = getRight(end);
+						}
+						int newX;
+						long newSnakeTmp;
+						if (k >= prevEndK ||
+							(k > prevBeginK &&
+								isBetter(left, right))) {
+									newX = left;
+									newSnakeTmp = leftSnake;
+								}
+						else {
+							newX = right;
+							newSnakeTmp = rightSnake;
+						}
+
+						if (meets(d, k, newX, newSnakeTmp))
 							return true;
-						left = getLeft(end);
+						adjustMinMaxK(k, newX);
+						i = getIndex(d, k);
+						x.set(i, newX);
+						_snake.set(i, newSnakeTmp);
 					}
-					if (k < prevEndK) {
-						i = getIndex(d - 1, k + 1);
-						right = x.get(i);
-						int end = snake(k + 1, right);
-						rightSnake = right != end ?
-							newSnake(k + 1, end) :
-							_snake.get(i);
-
-                        if (meets(d, k + 1, end, rightSnake))
-							return true;
-						right = getRight(end);
+					return false;
+				}
+			}
+
+			class ForwardEditPaths : EditPaths {
+				public ForwardEditPaths(MiddleEdit middleEdit) : base(middleEdit)
+				{
+				}
+
+				public override int snake(int k, int x) {
+					for (; x < _middleEdit.endA && k + x < _middleEdit.endB; x++)
+						if (!_middleEdit._a.equals(x, _middleEdit._b, k + x))
+							break;
+					return x;
+				}
+
+				protected override int getLeft(int x) {
+					return x;
+				}
+
+				protected override int getRight(int x) {
+					return x + 1;
+				}
+
+				protected override bool isBetter(int left, int right) {
+					return left > right;
+				}
+
+				protected override void adjustMinMaxK(int k, int x) {
+					if (x >= _middleEdit.endA || k + x >= _middleEdit.endB)
+					{
+						if (k > _middleEdit.backward.middleK)
+							maxK = k;
+						else
+							minK = k;
 					}
-					int newX;
-					long newSnakeTmp;
-					if (k >= prevEndK ||
-							(k > prevBeginK &&
-							 isBetter(left, right))) {
-						newX = left;
-						newSnakeTmp = leftSnake;
+				}
+
+				protected override bool meets(int d, int k, int x, long snake) {
+					if (k < _middleEdit.backward.beginK || k > _middleEdit.backward.endK)
+						return false;
+					// TODO: move out of loop
+					if (((d - 1 + k - _middleEdit.backward.middleK) % 2) == 1)
+						return false;
+					if (x < _middleEdit.backward.getX(d - 1, k))
+						return false;
+					makeEdit(snake, _middleEdit.backward.getSnake(d - 1, k));
+					return true;
+				}
+			}
+
+			class BackwardEditPaths : EditPaths {
+				public BackwardEditPaths(MiddleEdit middleEdit) : base(middleEdit)
+				{
+				}
+
+				public override int snake(int k, int x) {
+					for (; x > _middleEdit.beginA && k + x > _middleEdit.beginB; x--)
+						if (!_middleEdit._a.equals(x - 1, _middleEdit._b, k + x - 1))
+							break;
+					return x;
+				}
+
+				protected override int getLeft(int x) {
+					return x - 1;
+				}
+
+				protected override int getRight(int x) {
+					return x;
+				}
+
+				protected override bool isBetter(int left, int right) {
+					return left < right;
+				}
+
+				protected override void adjustMinMaxK(int k, int x) {
+					if (x <= _middleEdit.beginA || k + x <= _middleEdit.beginB)
+					{
+						if (k > _middleEdit.forward.middleK)
+							maxK = k;
+						else
+							minK = k;
 					}
-					else {
-						newX = right;
-						newSnakeTmp = rightSnake;
-					}
-
-                    if (meets(d, k, newX, newSnakeTmp))
-						return true;
-					adjustMinMaxK(k, newX);
-					 i = getIndex(d, k);
-					x.set(i, newX);
-					_snake.set(i, newSnakeTmp);
-				}
-				return false;
-			}
-		}
-
-		class ForwardEditPaths : EditPaths {
-		    public ForwardEditPaths(MiddleEdit middleEdit) : base(middleEdit)
-		    {
-		    }
-
-		    public override int snake(int k, int x) {
-                for (; x < _middleEdit.endA && k + x < _middleEdit.endB; x++)
-                    if (!_middleEdit._a.equals(x, _middleEdit._b, k + x))
-						break;
-				return x;
-			}
-
-		    protected override int getLeft(int x) {
-				return x;
-			}
-
-		    protected override int getRight(int x) {
-				return x + 1;
-			}
-
-		    protected override bool isBetter(int left, int right) {
-				return left > right;
-			}
-
-		    protected override void adjustMinMaxK(int k, int x) {
-                if (x >= _middleEdit.endA || k + x >= _middleEdit.endB)
-                {
-                    if (k > _middleEdit.backward.middleK)
-						maxK = k;
-					else
-						minK = k;
-				}
-			}
-
-		    protected override bool meets(int d, int k, int x, long snake) {
-                if (k < _middleEdit.backward.beginK || k > _middleEdit.backward.endK)
-					return false;
-				// TODO: move out of loop
-                if (((d - 1 + k - _middleEdit.backward.middleK) % 2) == 1)
-					return false;
-                if (x < _middleEdit.backward.getX(d - 1, k))
-					return false;
-                makeEdit(snake, _middleEdit.backward.getSnake(d - 1, k));
-				return true;
-			}
-		}
-
-		class BackwardEditPaths : EditPaths {
-		    public BackwardEditPaths(MiddleEdit middleEdit) : base(middleEdit)
-		    {
-		    }
-
-		    public override int snake(int k, int x) {
-                for (; x > _middleEdit.beginA && k + x > _middleEdit.beginB; x--)
-                    if (!_middleEdit._a.equals(x - 1, _middleEdit._b, k + x - 1))
-						break;
-				return x;
-			}
-
-		    protected override int getLeft(int x) {
-				return x - 1;
-			}
-
-		    protected override int getRight(int x) {
-				return x;
-			}
-
-		    protected override bool isBetter(int left, int right) {
-				return left < right;
-			}
-
-		    protected override void adjustMinMaxK(int k, int x) {
-                if (x <= _middleEdit.beginA || k + x <= _middleEdit.beginB)
-                {
-                    if (k > _middleEdit.forward.middleK)
-						maxK = k;
-					else
-						minK = k;
-				}
-			}
-
-		    protected override bool meets(int d, int k, int x, long snake) {
-                if (k < _middleEdit.forward.beginK || k > _middleEdit.forward.endK)
-					return false;
-				// TODO: move out of loop
-                if (((d + k - _middleEdit.forward.middleK) % 2) == 1)
-					return false;
-                if (x > _middleEdit.forward.getX(d, k))
-					return false;
-                makeEdit(_middleEdit.forward.getSnake(d, k), snake);
-				return true;
+				}
+
+				protected override bool meets(int d, int k, int x, long snake) {
+					if (k < _middleEdit.forward.beginK || k > _middleEdit.forward.endK)
+						return false;
+					// TODO: move out of loop
+					if (((d + k - _middleEdit.forward.middleK) % 2) == 1)
+						return false;
+					if (x > _middleEdit.forward.getX(d, k))
+						return false;
+					makeEdit(_middleEdit.forward.getSnake(d, k), snake);
+					return true;
+				}
 			}
 		}
 	}


PG-1168: Enhanced (already failing) test to show need to re-apply reference text alignments

--- GlyssenTests/BookScriptTests.cs
+++ GlyssenTests/BookScriptTests.cs
@@ -1281,11 +1281,12 @@

 		// MAT 21:31
 		[Test]
-		public void ApplyUserDecisions_SplitBetweenTwoVersesChunkedOutByReferenceTextAndMultipleSplitsInFollowingVerse_TextUnchanged_SplitsApplied()
-		{
+		public void ApplyUserDecisions_SplitBetweenTwoVersesChunkedOutByReferenceTextAndMultipleSplitsInFollowingVerse_TextUnchanged_MatchesAndSplitsApplied()
+		{
+			const int kChapter = 21;
 			var blocks = new List<Block> {
-				NewChapterBlock(21, "MAT"),
-				new Block("p", 21, 30)
+				NewChapterBlock(kChapter, "MAT"),
+				new Block("p", kChapter, 30)
 					.AddVerse(30, "Ia amaama i ditopot ma sianggian i, laos songon i do hatana, gabe didok i ma mangalusi: Olo, tuan! Hape, ndang saut laho. ")
 					// Offset:               1         2         3         4         5         6         7         8          9        10        11        12        13        14        15
 					// Offset:     012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890
@@ -1303,11 +1304,18 @@
 			var target = source.Clone(false);

 			var origBlockCount = source.GetScriptBlocks().Count;
-			ReferenceText.GetStandardReferenceText(ReferenceTextType.English).ApplyTo(source, ScrVers.English);
+			var englishRefText = ReferenceText.GetStandardReferenceText(ReferenceTextType.English);
+			englishRefText.ApplyTo(source, ScrVers.English);
 			var sourceBlocksChunkedOut = source.GetScriptBlocks();
 			Assert.IsTrue(origBlockCount < sourceBlocksChunkedOut.Count);

-			var iBlockToSplit = source.GetIndexOfFirstBlockForVerse(21, 31);
+			var iBlockV30 = source.GetIndexOfFirstBlockForVerse(kChapter, 30);
+			Assert.AreEqual(1, iBlockV30);
+			var blockV30 = source.GetScriptBlocks()[iBlockV30];
+			Assert.AreEqual("30", blockV30.BlockElements.OfType<Verse>().Single().Number);
+			blockV30.SetMatchedReferenceBlock(englishRefText.Books[source.BookNumber].GetFirstBlockForVerse(kChapter, 30));
+
+			var iBlockToSplit = source.GetIndexOfFirstBlockForVerse(kChapter, 31);
 			Assert.AreEqual(2, iBlockToSplit);
 			var blockToSplit = source.GetScriptBlocks()[iBlockToSplit];
 			var narrator = CharacterVerseData.GetStandardCharacterId(source.BookId, CharacterVerseData.StandardCharacter.Narrator);
@@ -1329,16 +1337,17 @@
 			split1.UserConfirmed = true;

 			blockToSplit.SetCharacterIdAndCharacterIdInScript("Jesus", source.BookNumber, ScrVers.English);
-			// This next line is really unnecessary, but it matches the real data. We won't check that this gets
-			// reset because we won't expect v. 31 to get broken out. Glyssen will be able to re-apply this
-			// on the fly (I think).
 			blockToSplit.SetMatchedReferenceBlock("{31}Which one of the two did the will of his father?”");
-			// FWIW, in the actual data that this test is based on, neither this block, nor the ones for vv. 30 or 32 had
+			// In the actual data that this test is based on, neither this block, nor the ones for vv. 30 or 32 had
 			// UserConfirmed set to true. (By contrast, in the above test for 1CO 15:26-26, all three blocks involved in
 			// the split DID have UserConfirmed set to true in the actual data.) I'm not sure the implementation is really
 			// 100% logivcal, but if blocks in the vernacular match automatically to the reference text and already have
 			// the correct character ID (because there was only one possiblity in the control file), then we don't mark
 			// them as user-confirmed when the user clicks apply.
+
+			var blockV32 = source.GetScriptBlocks()[source.GetIndexOfFirstBlockForVerse(kChapter, 32)];
+			Assert.AreEqual("32", blockV32.BlockElements.OfType<Verse>().Single().Number);
+			blockV32.SetMatchedReferenceBlock(englishRefText.Books[source.BookNumber].GetFirstBlockForVerse(kChapter, 32));

 			Assert.AreEqual(split4.SplitId, blockToSplit.SplitId);
 			Assert.AreEqual(split3.SplitId, blockToSplit.SplitId);
@@ -1354,32 +1363,46 @@
 			var blockVerse31Start = targetBlocksAfterApplyingSplit.Single(b => b.BlockElements.OfType<Verse>().Any(v => v.Number == "31"));
 			Assert.AreEqual(kSplitPos1, blockVerse31Start.BlockElements.OfType<ScriptText>().Last().Content.Length);

-			var iBlock = targetBlocksAfterApplyingSplit.IndexOf(blockVerse31Start) + 1;
-
-			var block = targetBlocksAfterApplyingSplit[iBlock++];
+			var iBlock = targetBlocksAfterApplyingSplit.IndexOf(blockVerse31Start);
+
+			var block = targetBlocksAfterApplyingSplit[iBlock - 1];
+			Assert.AreEqual("{30}\u00A0Ia amaama i ditopot ma sianggian i, laos songon i do hatana, gabe didok i ma mangalusi: Olo, tuan! Hape, ndang saut laho. ",
+				block.GetText(true));
+			Assert.IsTrue(block.CharacterIs(source.BookId, CharacterVerseData.StandardCharacter.Narrator));
+			Assert.IsTrue(block.MatchesReferenceText);
+			Assert.AreEqual("He came to the second, and said the same thing. He answered, ‘I go, sir,’ but he didn't go.",
+				block.ReferenceBlocks.Single().GetText(true));
+
+			block = targetBlocksAfterApplyingSplit[++iBlock];
 			Assert.AreEqual(kSplitPos2 - kSplitPos1, ((ScriptText)block.BlockElements.Single()).Content.Length);
 			Assert.IsTrue(block.CharacterIs(source.BookId, CharacterVerseData.StandardCharacter.Narrator));
 			Assert.IsTrue(block.MatchesReferenceText);
 			Assert.AreEqual("They said to him,", block.ReferenceBlocks.Single().GetText(true));

-			block = targetBlocksAfterApplyingSplit[iBlock++];
+			block = targetBlocksAfterApplyingSplit[++iBlock];
 			Assert.AreEqual(kSplitPos3 - kSplitPos2, ((ScriptText)block.BlockElements.Single()).Content.Length);
 			Assert.AreEqual("chief priests/elders", block.CharacterId);
 			Assert.AreEqual("Good Priest", block.CharacterIdInScript);
 			Assert.IsTrue(block.MatchesReferenceText);
 			Assert.AreEqual("“The first.”", block.ReferenceBlocks.Single().GetText(true));

-			block = targetBlocksAfterApplyingSplit[iBlock++];
+			block = targetBlocksAfterApplyingSplit[++iBlock];
 			Assert.AreEqual(kSplitPos4 - kSplitPos3, ((ScriptText)block.BlockElements.Single()).Content.Length);
 			Assert.IsTrue(block.CharacterIs(source.BookId, CharacterVerseData.StandardCharacter.Narrator));
 			Assert.IsTrue(block.MatchesReferenceText);
 			Assert.AreEqual("Jesus said to them,", block.ReferenceBlocks.Single().GetText(true));

-			block = targetBlocksAfterApplyingSplit[iBlock];
+			block = targetBlocksAfterApplyingSplit[++iBlock];
 			Assert.AreEqual(origLengthOfVerse31 - kSplitPos4, block.BlockElements.OfType<ScriptText>().First().Content.Length);
 			Assert.AreEqual("Jesus", block.CharacterId);
 			Assert.IsTrue(block.MatchesReferenceText);
 			Assert.AreEqual("“Most certainly I tell you that the tax collectors and the prostitutes are entering into the Kingdom of God before you.",
+				block.ReferenceBlocks.Single().GetText(true));
+
+			block = targetBlocksAfterApplyingSplit[++iBlock];
+			Assert.AreEqual("{32}\u00A0Ai na ro do si Johannes tu hamu di dalan hatigoran, ndang dihaporseai hamu ibana; alai anggo angka sijalobeo dohot angka boru na jahat porsea do. Diida hamu do i nian; laos tong so disolsoli hamu rohamuna, laho mangkaporseai ibana. ",
+				block.GetText(true));
+			Assert.AreEqual("For John came to you in the way of righteousness, and you didn't believe him, but the tax collectors and the prostitutes believed him. When you saw it, you didn't even repent afterward, that you might believe him.”",
 				block.ReferenceBlocks.Single().GetText(true));

 			Assert.IsNotNull(target.UnappliedSplits);


fix: Split transports on "+" instead of ";"

(Corresponding documentation change will be needed in google-cloud-dotnet)

--- Google.Api.Generator/Program.cs
+++ Google.Api.Generator/Program.cs
@@ -60,7 +60,7 @@
             [Option(nameCommonResourcesConfig, Required = false, HelpText = "Common resources config path. JSON proto of type CommonResources.")]
             public IEnumerable<string> CommonResourcesConfigs { get; private set; }

-            [Option(nameTransport, Required = false, HelpText = "Semi-colon-separated list of transports to generate for the main API.")]
+            [Option(nameTransport, Required = false, HelpText = "Plus-separated list of transports to generate for the main API.")]
             public string Transport { get; private set; }

             [Usage]
@@ -74,7 +74,7 @@
                         Descriptor = Path.Combine("path", "to", "serialized", "FileDescriptorSet"),
                         Package = "your.service.proto_package",
                         Output = Path.Combine("path", "to", "output", "directory"),
-                        Transport = "grpc;rest"
+                        Transport = "grpc+rest"
                     }),
             };
         }
@@ -257,7 +257,7 @@
             {
                 return ApiTransports.Grpc;
             }
-            var parts = text.Split(';');
+            var parts = text.Split('+');
             ApiTransports ret = ApiTransports.None;
             foreach (var part in parts)
             {


fixes network list sorting

fixes network list sorting

--- Handle.WPF/Handle.WPF/ViewModels/NetworkSelectionViewModel.cs
+++ Handle.WPF/Handle.WPF/ViewModels/NetworkSelectionViewModel.cs
@@ -137,9 +137,10 @@
     public void Connect()
     {
       var nsv = GetView() as NetworkSelectionView;
-      if (nsv.NetworkList.SelectedIndex != -1)
-      {
-        this.ConnectButtonPressed(this.Networks[nsv.NetworkList.SelectedIndex]);
+      List<Network> nets = nsv.NetworkList.SelectedItems.Cast<Network>().ToList<Network>();
+      foreach (Network n in nets)
+      {
+        this.ConnectButtonPressed(this.Networks[networks.IndexOf(n)]);
       }
       saveGlobalIdentity();
     }
@@ -147,9 +148,10 @@
     public void Remove()
     {
       var nsv = GetView() as NetworkSelectionView;
-      while (nsv.NetworkList.SelectedIndex != -1)
-      {
-        this.Networks.RemoveAt(nsv.NetworkList.SelectedIndex);
+      List<Network> nets = nsv.NetworkList.SelectedItems.Cast<Network>().ToList<Network>();
+      foreach (Network n in nets)
+      {
+        this.Networks.Remove(n);
       }
       this.saveNetworks();
     }
@@ -162,7 +164,8 @@
       {
         return;
       }
-
+      Network n = (Network)nsv.NetworkList.SelectedItem;
+      index = this.networks.IndexOf(n);
       NetworkEditViewModel nevm = new NetworkEditViewModel(this.Networks[index].ShallowCopy());

       if (this.windowManager.ShowDialog(nevm) == true)


Style changes to the list

Style changes to the list

--- ItemCollageUI/Form1.Designer.cs
+++ ItemCollageUI/Form1.Designer.cs
@@ -56,11 +56,14 @@
             //
             // itemListBox1
             //
+            this.itemListBox1.BackColor = System.Drawing.Color.Black;
+            this.itemListBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
             this.itemListBox1.Dock = System.Windows.Forms.DockStyle.Fill;
             this.itemListBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
-            this.itemListBox1.FormattingEnabled = true;
+            this.itemListBox1.ForeColor = System.Drawing.Color.White;
             this.itemListBox1.Location = new System.Drawing.Point(0, 0);
             this.itemListBox1.Name = "itemListBox1";
+            this.itemListBox1.SelectionMode = System.Windows.Forms.SelectionMode.None;
             this.itemListBox1.Size = new System.Drawing.Size(278, 301);
             this.itemListBox1.TabIndex = 4;
             //
@@ -73,7 +76,6 @@
             this.Controls.Add(this.itemListBox1);
             this.Controls.Add(this.panel1);
             this.ForeColor = System.Drawing.Color.White;
-            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
             this.MaximizeBox = false;
             this.Name = "Form1";
             this.ShowIcon = false;


Leave the default timeout.

Leave the default timeout.

--- JabbR/App_Start/Bootstrapper.cs
+++ JabbR/App_Start/Bootstrapper.cs
@@ -70,12 +70,7 @@

             Kernel = kernel;

-            IDependencyResolver resolver = new NinjectDependencyResolver(kernel);
-
-            var configurationManager = resolver.Resolve<IConfigurationManager>();
-
-            // Make the timeout one minute
-            configurationManager.ReconnectionTimeout = TimeSpan.FromMinutes(1);
+            var resolver = new NinjectDependencyResolver(kernel);

             AspNetHost.SetResolver(resolver);


fixed unauthorized access exception

fixed unauthorized access exception

--- Jirabox/Services/JiraService.cs
+++ Jirabox/Services/JiraService.cs
@@ -33,7 +33,10 @@
         private readonly IJsonHttpClient jsonClient;
         private readonly IDialogService dialogService;
         private readonly ICacheService cacheService;
+
         public CancellationTokenSource TokenSource;
+
+        private static readonly object Sync = new object();

         public JiraService(IHttpManager httpManager, IJsonHttpClient jsonClient, IDialogService dialogService, ICacheService cacheDataService)
         {
@@ -545,15 +548,15 @@
         {
             try
             {
-                using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    if (!isf.DirectoryExists("Images"))
+                using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
+                {
+                    if (!storage.DirectoryExists("Images"))
                     {
-                        isf.CreateDirectory("Images");
+                        storage.CreateDirectory("Images");
                     }

                     var path = Path.Combine("Images", filename.Replace(":", ".").Replace(" ", "") + ".png");
-                    if (isf.FileExists(path)) return;
+                    if (storage.FileExists(path)) return;

                     var result = await httpManager.GetAsync(url, true, App.UserName, App.Password);
                     if (result.IsSuccessStatusCode)
@@ -566,12 +569,15 @@
                             image.SetSource(stream);
                         }

-                        var wb = new WriteableBitmap(image);
-
-                        using (var fs = isf.CreateFile(path))
+                        var writeableBitmap = new WriteableBitmap(image);
+                        lock (Sync)
                         {
-                            PngWriter.WritePNG(wb, fs);
+                            using (var fs = storage.CreateFile(path))
+                            {
+                                PngWriter.WritePNG(writeableBitmap, fs);
+                            }
                         }
+
                         if (isProjectAvatar)
                         {
                             CreateCustomeLiveTile(image, filename);


implement delete function, change more styles

--- SSSEditor/PairList.cshtml
+++ SSSEditor/PairList.cshtml
@@ -143,6 +143,27 @@

                 $(this).focus();
             });
+
+            $("input.delete").click(function () {
+                if (confirm("Are you sure you want to delete this entry?")) {
+                    var row = $(this).parents(".stageRow");
+                    var defClassName = row[0].className.match(/def[^ ]*/)[0];
+
+                    var index = +row.find(".indexDisplay").text();
+                    for (var next = row.next() ; next.length == 1; next = next.next()) {
+                        next.find(".indexDisplay").text(index + ".");
+                        if (next.parents("#pairDefinitions").length > 0) {
+                            // First column
+                            var nextDefClassName = next[0].className.match(/def[^ ]*/)[0];
+                            $("." + nextDefClassName + " input.defIndex").val(index);
+                        }
+                        index++;
+                    }
+
+                    row.remove();
+                    $("." + defClassName + " input.defIndex:enabled").val(0).change();
+                }
+            });
         });
     </script>

@@ -242,6 +282,7 @@

                         @i.
                         <select class="stagename"></select>
+                        <input type="button" class="delete" value="x" />

                         <input class="defIndex" value="@i" disabled />
                         <input class="stageID" value="@pair.stage" type="number" />
@@ -254,7 +295,7 @@
                 }

-                buttons
+                <input type="button" class="add" value="Add (+)" />

@@ -267,6 +308,7 @@

                         @i.
                         <select class="stagename" disabled></select>
+                        <input type="button" class="delete" value="x" />

                         <input class="defIndex" value="@defID" />
                         <input class="stageID" value="@pair.stage" type="number" disabled />
@@ -277,6 +319,9 @@
                         <input class="down" value="v" type="button" />

                 }
+

+

+                <input type="button" class="add" value="Add (+)" />

@@ -289,6 +334,7 @@

                         @i.
                         <select class="stagename" disabled></select>
+                        <input type="button" class="delete" value="x" />

                         <input class="defIndex" value="@defID" />
                         <input class="stageID" value="@pair.stage" type="number" disabled />
@@ -300,6 +346,9 @@

                 }

+

+                <input type="button" class="add" value="Add (+)" />
+


Properly dispose Ping (#2787)

Properly dispose Ping (#2787)

--- src/Agent.Listener/Diagnostics/PingTest.cs
+++ src/Agent.Listener/Diagnostics/PingTest.cs
@@ -6,25 +6,27 @@
     {
         public bool Execute(ITerminal terminal)
         {
-            Ping ping = new Ping();
-            try
+            using (Ping ping = new Ping())
             {
-                terminal.WriteLine(string.Format("Attempt to Ping: {0} with timeout {1}", c_hostname, c_timeout));
-                PingReply pingreply = ping.Send(c_hostname, c_timeout);
-                terminal.WriteLine(string.Format("Address: {0}", pingreply.Address));
-                terminal.WriteLine(string.Format("Status: {0}", pingreply.Status));
-                terminal.WriteLine(string.Format("Round trip time: {0}", pingreply.RoundtripTime));
+                try
+                {
+                    terminal.WriteLine(string.Format("Attempt to Ping: {0} with timeout {1}", c_hostname, c_timeout));
+                    PingReply pingreply = ping.Send(c_hostname, c_timeout);
+                    terminal.WriteLine(string.Format("Address: {0}", pingreply.Address));
+                    terminal.WriteLine(string.Format("Status: {0}", pingreply.Status));
+                    terminal.WriteLine(string.Format("Round trip time: {0}", pingreply.RoundtripTime));

-                if (pingreply.Status != IPStatus.Success)
+                    if (pingreply.Status != IPStatus.Success)
+                    {
+                        terminal.WriteError(string.Format("Unsuccessful status response from {0}.  Verify internet connection is working", c_hostname));
+                        return false;
+                    }
+                }
+                catch (PingException ex)
                 {
-                    terminal.WriteError(string.Format("Unsuccessful status response from {0}.  Verify internet connection is working", c_hostname));
+                    terminal.WriteError(ex);
                     return false;
                 }
-            }
-            catch (PingException ex)
-            {
-                terminal.WriteError(ex);
-                return false;
             }

             return true;


Use PadRight

Use PadRight

--- src/AppHarbor/Commands/DeployAppCommand.cs
+++ src/AppHarbor/Commands/DeployAppCommand.cs
@@ -140,8 +140,9 @@

 				int width = Console.WindowWidth - 1;
 				int newWidth = (int)((width * percentage) / 100d);
-				string progressBar = new string(progressBarCharacter, newWidth) +
-					  new string(' ', width - newWidth);
+				string progressBar = string.Empty
+					.PadRight(newWidth, progressBarCharacter)
+					.PadRight(width - newWidth, ' ');

 				_writer.Write(progressBar);
 				message = message ?? string.Empty;


Remove generic methods from IDispatcher.

--- src/Avalonia.Base/Threading/IDispatcher.cs
+++ src/Avalonia.Base/Threading/IDispatcher.cs
@@ -27,29 +27,12 @@
         void Post(Action action, DispatcherPriority priority = default);

         /// <summary>
-        /// Posts an action that will be invoked on the dispatcher thread.
-        /// </summary>
-        /// <typeparam name="T">type of argument</typeparam>
-        /// <param name="action">The method to call.</param>
-        /// <param name="arg">The argument of method to call.</param>
-        /// <param name="priority">The priority with which to invoke the method.</param>
-        void Post<T>(Action<T> action, T arg, DispatcherPriority priority = default);
-
-        /// <summary>
         /// Invokes a action on the dispatcher thread.
         /// </summary>
         /// <param name="action">The method.</param>
         /// <param name="priority">The priority with which to invoke the method.</param>
         /// <returns>A task that can be used to track the method's execution.</returns>
         Task InvokeAsync(Action action, DispatcherPriority priority = default);
-
-        /// <summary>
-        /// Invokes a method on the dispatcher thread.
-        /// </summary>
-        /// <param name="function">The method.</param>
-        /// <param name="priority">The priority with which to invoke the method.</param>
-        /// <returns>A task that can be used to track the method's execution.</returns>
-        Task<TResult> InvokeAsync<TResult>(Func<TResult> function, DispatcherPriority priority = default);

         /// <summary>
         /// Queues the specified work to run on the dispatcher thread and returns a proxy for the
@@ -59,14 +42,5 @@
         /// <param name="priority">The priority with which to invoke the method.</param>
         /// <returns>A task that represents a proxy for the task returned by <paramref name="function"/>.</returns>
         Task InvokeAsync(Func<Task> function, DispatcherPriority priority = default);
-
-        /// <summary>
-        /// Queues the specified work to run on the dispatcher thread and returns a proxy for the
-        /// task returned by <paramref name="function"/>.
-        /// </summary>
-        /// <param name="function">The work to execute asynchronously.</param>
-        /// <param name="priority">The priority with which to invoke the method.</param>
-        /// <returns>A task that represents a proxy for the task returned by <paramref name="function"/>.</returns>
-        Task<TResult> InvokeAsync<TResult>(Func<Task<TResult>> function, DispatcherPriority priority = default);
     }
 }