new game menu works now properly

new game menu works now properly

--- ParticleStormControl/ParticleStormControl/Menu/NewGame.cs
+++ ParticleStormControl/ParticleStormControl/Menu/NewGame.cs
@@ -219,7 +219,7 @@

             int textBoxHeight = (int)menu.Font.MeasureString("ABC").Y + SimpleButton.PADDING * 2;
             int ARROW_SIZE = textBoxHeight;
-            int SIDE_PADDING = ARROW_SIZE + 20;
+            int SIDE_PADDING = ARROW_SIZE + 30;

             virusRenderEffect.Parameters["ScreenSize"].SetValue(new Vector2(menu.ScreenWidth, menu.ScreenHeight));

@@ -249,8 +249,9 @@
                     SimpleButton.Instance.Draw(spriteBatch, menu.FontHeading, Player.VirusNames[Settings.Instance.PlayerVirusIndices[i]].ToString(),
                                                     origin + new Vector2(SIDE_PADDING, 0),false, menu.PixelTexture);

+                    // controlls
                     SimpleButton.Instance.Draw(spriteBatch, menu.Font, Player.ControlNames[(int)Settings.Instance.PlayerControls[i]].ToString(),
-                                                    origin + new Vector2(SIDE_PADDING, textBoxHeight + SimpleButton.PADDING * 3), false, menu.PixelTexture);
+                                                    origin + new Vector2(SIDE_PADDING, textBoxHeight*2 + SimpleButton.PADDING * 2), false, menu.PixelTexture);

                     /*
                     string colorString = "Color: ";
@@ -259,9 +260,12 @@
                                     origin + new Vector2(SIDE_PADDING + SimpleButton.PADDING * 2 + menu.Font.MeasureString(colorString).X, textBoxHeight * 2.5f), Settings.Instance.GetPlayerColor(i), menu.PixelTexture);
                     */

+                    // ready
+                    int readyHeight = textBoxHeight * 4;
                     string playerReadyText = playerReady[i] ? "ready!" : "not ready";
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, playerReadyText, origin + new Vector2(SIDE_PADDING + ARROW_SIZE, textBoxHeight*3), playerReady[i], menu.PixelTexture);
-                    SimpleButton.Instance.DrawTexture_NoScalingNoPadding(spriteBatch, icons, new Rectangle((int)origin.X + SIDE_PADDING - SimpleButton.PADDING, (int)origin.Y + textBoxHeight * 3 - SimpleButton.PADDING, ARROW_SIZE, ARROW_SIZE), new Rectangle(playerReady[i] ? 48 : 0, 32, 16, 16), playerReady[i], menu.PixelTexture);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, playerReadyText, origin + new Vector2(SIDE_PADDING + ARROW_SIZE, readyHeight), playerReady[i], menu.PixelTexture);
+                    SimpleButton.Instance.DrawTexture_NoScalingNoPadding(spriteBatch, icons, new Rectangle((int)origin.X + SIDE_PADDING - SimpleButton.PADDING,
+                                            (int)origin.Y + readyHeight - SimpleButton.PADDING, ARROW_SIZE, ARROW_SIZE), new Rectangle(playerReady[i] ? 48 : 0, 32, 16, 16), playerReady[i], menu.PixelTexture);

                     // description
                     int descpStrLen = (int)menu.Font.MeasureString("Discipline").X + 7;
@@ -269,26 +273,29 @@
                     int backgroundLength = boxWidth - SIDE_PADDING * 2 + SimpleButton.PADDING*2;//(descpStrLen + symbolLen) * 2 + 15;
                     int descpX0 = SIDE_PADDING;
                     int descpX1 = descpX0 + backgroundLength / 2;
-                    float descpY = textBoxHeight * 6.5f;
+                    float descpY = boxHeight - textBoxHeight * 2;

                     string symbols = Player.AttributValueToString(Player.speed_byVirus[Settings.Instance.PlayerVirusIndices[i]]);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Speed", origin + new Vector2(descpX0, descpY - textBoxHeight), false, menu.PixelTexture, backgroundLength);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX0 + descpStrLen, descpY - textBoxHeight), false, menu.PixelTexture, -1);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Speed", origin + new Vector2(descpX0, descpY), false, menu.PixelTexture, backgroundLength);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX0 + descpStrLen, descpY), false, menu.PixelTexture, -1);
                     symbols = Player.AttributValueToString(Player.mass_byVirus[Settings.Instance.PlayerVirusIndices[i]]);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Mass", origin + new Vector2(descpX0, descpY), false, menu.PixelTexture, backgroundLength);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX0 + descpStrLen, descpY), false, menu.PixelTexture, -1);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Mass", origin + new Vector2(descpX0, descpY + textBoxHeight), false, menu.PixelTexture, backgroundLength);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX0 + descpStrLen, descpY + textBoxHeight), false, menu.PixelTexture, -1);
                     symbols = Player.AttributValueToString(Player.disciplin_byVirus[Settings.Instance.PlayerVirusIndices[i]]);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Discipline", origin + new Vector2(descpX1, descpY - textBoxHeight), false, menu.PixelTexture, -1);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX1 + descpStrLen, descpY - textBoxHeight), false, menu.PixelTexture, -1);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Discipline", origin + new Vector2(descpX1, descpY), false, menu.PixelTexture, -1);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX1 + descpStrLen, descpY), false, menu.PixelTexture, -1);
                     symbols = Player.AttributValueToString(Player.health_byVirus[Settings.Instance.PlayerVirusIndices[i]]);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Health", origin + new Vector2(descpX1, descpY), false, menu.PixelTexture, -1);
-                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX1 + descpStrLen, descpY), false, menu.PixelTexture, -1);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, "Health", origin + new Vector2(descpX1, descpY + textBoxHeight), false, menu.PixelTexture, -1);
+                    SimpleButton.Instance.Draw(spriteBatch, menu.Font, symbols, origin + new Vector2(descpX1 + descpStrLen, descpY + textBoxHeight), false, menu.PixelTexture, -1);

                     // image
-                    Rectangle destination = new Rectangle((int)origin.X + 240, (int)origin.Y + textBoxHeight + SimpleButton.PADDING * 2, 120, 120);
-                    destination.Inflate(10, 10);
-                    spriteBatch.Draw(menu.PixelTexture, destination, new Color(10, 10, 10));
-                    destination.Inflate(-10, -10);
+                    const int VIRUS_SIZE = 110;
+                    const int VIRUS_PADDING = 10;
+                    Rectangle virusImageRect = new Rectangle((int)origin.X + boxWidth - VIRUS_SIZE - SIDE_PADDING,
+                                                    (int)origin.Y + textBoxHeight + 40, VIRUS_SIZE, VIRUS_SIZE);
+                    virusImageRect.Inflate(VIRUS_PADDING, VIRUS_PADDING);
+                    spriteBatch.Draw(menu.PixelTexture, virusImageRect, Color.Black);
+                    virusImageRect.Inflate(-VIRUS_PADDING, -VIRUS_PADDING);
                     spriteBatch.End(); // yeah this sucks terrible! TODO better solution
                     switch(Player.Viruses[Settings.Instance.PlayerVirusIndices[i]])
                     {
@@ -305,14 +312,23 @@
                             virusRenderEffect.CurrentTechnique = virusRenderEffect.Techniques["HepatitisB_Spritebatch"];
                             break;
                     }
-                    virusRenderEffect.Parameters["Color"].SetValue(Settings.Instance.GetPlayerColor(i).ToVector4());
+                    virusRenderEffect.Parameters["Color"].SetValue(Player.ParticleColors[Settings.Instance.PlayerColorIndices[i]].ToVector4() * 1.5f);
                     spriteBatch.Begin(0, BlendState.Additive, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullNone, virusRenderEffect);
-                    spriteBatch.Draw(menu.PixelTexture, destination, Color.White);
+                    spriteBatch.Draw(menu.PixelTexture, virusImageRect, Color.White);
                     spriteBatch.End();
                     spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullNone);

+                    const int ARROW_UP_SIZE = 25;
+                    const int ARROW_WIDDEN = 8;
+                    SimpleButton.Instance.DrawTexture_NoScalingNoPadding(spriteBatch, icons, new Rectangle(virusImageRect.Center.X - (ARROW_UP_SIZE + ARROW_WIDDEN) / 2,
+                                                            virusImageRect.Y - ARROW_UP_SIZE - VIRUS_PADDING / 2, ARROW_UP_SIZE + ARROW_WIDDEN, ARROW_UP_SIZE),
+                                                new Rectangle(0 + isActive(InputManager.ControlActions.UP, i, 32), 16, 16, 16), isActive(InputManager.ControlActions.UP, i), menu.PixelTexture);
+                    SimpleButton.Instance.DrawTexture_NoScalingNoPadding(spriteBatch, icons, new Rectangle(virusImageRect.Center.X - (ARROW_UP_SIZE + ARROW_WIDDEN) / 2,
+                                                            virusImageRect.Bottom + VIRUS_PADDING / 2, ARROW_UP_SIZE + ARROW_WIDDEN, ARROW_UP_SIZE),
+                                                new Rectangle(16 + isActive(InputManager.ControlActions.DOWN, i, 32), 16, 16, 16), isActive(InputManager.ControlActions.DOWN, i), menu.PixelTexture);
+
                     // arrows left & right
-                    int arrowY = (int)descpY - ARROW_SIZE;//boxHeight / 2 - ARROW_SIZE;
+                    int arrowY = (int)readyHeight - ARROW_SIZE;//boxHeight / 2 - ARROW_SIZE;
                     SimpleButton.Instance.DrawTexture_NoScalingNoPadding(spriteBatch, icons, new Rectangle((int)origin.X, (int)origin.Y + arrowY, ARROW_SIZE, ARROW_SIZE), new Rectangle(0 + isActive(InputManager.ControlActions.LEFT, i, 32), 0, 16, 16), isActive(InputManager.ControlActions.LEFT, i), menu.PixelTexture);
                     SimpleButton.Instance.DrawTexture_NoScalingNoPadding(spriteBatch, icons, new Rectangle((int)origin.X + boxWidth - ARROW_SIZE, (int)origin.Y + arrowY, ARROW_SIZE, ARROW_SIZE), new Rectangle(16 + isActive(InputManager.ControlActions.RIGHT, i, 32), 0, 16, 16), isActive(InputManager.ControlActions.RIGHT, i), menu.PixelTexture);
                 }


Issue #171

Issue #171

--- PowerShellIntegrations/Provider/PsSitecoreItemProvider.cs
+++ PowerShellIntegrations/Provider/PsSitecoreItemProvider.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Data;
 using System.Linq;
 using System.Management.Automation;
 using System.Management.Automation.Provider;
@@ -40,13 +41,16 @@
                 if (item != null)
                 {
                     CheckOperationAllowed("remove", item.Access.CanDelete(), item.Uri.ToString());
-                    if (IsDynamicParamSet(PermanentlyParam))
-                    {
-                        item.Delete();
-                    }
-                    else
-                    {
-                        item.Recycle();
+                    if (ShouldProcess(item.Paths.Path))
+                    {
+                        if (IsDynamicParamSet(PermanentlyParam))
+                        {
+                            item.Delete();
+                        }
+                        else
+                        {
+                            item.Recycle();
+                        }
                     }
                 }
             }
@@ -329,9 +333,12 @@
                     }
                 }

-                var id = new ID(Guid.NewGuid());
-                Item itemCopy = sourceItem.CopyTo(destinationItem, leafName, id, recurse);
-                WriteItem(itemCopy);
+                if (ShouldProcess(sourceItem.Paths.Path, "Copy to '" + destinationItem.Paths.Path + "/" + leafName+"'"))
+                {
+                    var id = new ID(Guid.NewGuid());
+                    Item itemCopy = sourceItem.CopyTo(destinationItem, leafName, id, recurse);
+                    WriteItem(itemCopy);
+                }
             }
             catch (Exception ex)
             {
@@ -375,12 +382,15 @@
                     }
                 }

-                sourceItem.MoveTo(destinationItem);
-
-                if (sourceItem.Name != leafName)
-                {
-                    sourceItem.Edit(
-                        args => { sourceItem.Name = leafName; });
+                if (ShouldProcess(sourceItem.Paths.Path, "Move to '" + destinationItem.Paths.Path + "/"+leafName))
+                {
+                    sourceItem.MoveTo(destinationItem);
+
+                    if (sourceItem.Name != leafName)
+                    {
+                        sourceItem.Edit(
+                            args => { sourceItem.Name = leafName; });
+                    }
                 }
             }
             catch (Exception ex)
@@ -402,8 +412,11 @@
                 if (item != null)
                 {
                     CheckOperationAllowed("rename", item.Access.CanRename(), item.Uri.ToString());
-                    item.Edit(
-                        args => { item.Name = newName; });
+                    if (ShouldProcess(item.Paths.Path, "Rename to '" +newName + "'"))
+                    {
+                        item.Edit(
+                            args => { item.Name = newName; });
+                    }
                 }
             }
             catch (Exception ex)
@@ -436,6 +449,12 @@

                 Item srcItem = GetItemForPath("/" + itemTypeName);

+                if(srcItem == null)
+                {
+                    throw new ObjectNotFoundException(
+                        string.Format("Template '{0}' does not exist or wrong path provided.",
+                            itemTypeName));
+                }
                 Item parentItem = GetItemForPath(GetParentFromPath(path));

                 var dic = DynamicParameters as RuntimeDefinedParameterDictionary;
@@ -444,39 +463,42 @@
                     parentItem = dic[ParentParam].Value as Item;
                 }

-                Item createdItem = null;
-                if (srcItem.TemplateName == "Template")
-                {
-                    createdItem = parentItem.Add(GetLeafFromPath(path), (TemplateItem) srcItem);
-                }
-                else if (srcItem.TemplateName == "Branch")
-                {
-                    createdItem = parentItem.Add(GetLeafFromPath(path), (BranchItem) srcItem);
-                }
-
-                if (dic != null && dic[LanguageParam].IsSet)
-                {
-                    string forcedLanguage = dic[LanguageParam].Value.ToString();
-                    Language language = LanguageManager.GetLanguage(forcedLanguage);
-                    // Based on: http://sdn.sitecore.net/Forum/ShowPost.aspx?postid=16551
-                    // switching language with LanguageSwitcher didn't work
-                    // Thanks Kern!
-                    createdItem.Versions.RemoveAll(true);
-                    createdItem = createdItem.Database.GetItem(createdItem.ID, language);
-                    createdItem = createdItem.Versions.AddVersion();
-                }
-                // start default workflow on the created item if necessary
-                if (dic != null && dic[StartWorkflowParam].IsSet && Context.Workflow.HasDefaultWorkflow(createdItem))
-                {
-                    IWorkflow defaultWorkflow =
-                        createdItem.Database.WorkflowProvider.GetWorkflow(createdItem[FieldIDs.DefaultWorkflow]);
-                    if (null != defaultWorkflow)
-                    {
-                        defaultWorkflow.Start(createdItem);
-                    }
-                }
-
-                WriteItem(createdItem);
+                if (ShouldProcess(GetParentFromPath(path), "Create item '" + GetLeafFromPath(path) + "' of type '" + itemTypeName + "'"))
+                {
+                    Item createdItem = null;
+                    if (srcItem.TemplateName == "Template")
+                    {
+                        createdItem = parentItem.Add(GetLeafFromPath(path), (TemplateItem) srcItem);
+                    }
+                    else if (srcItem.TemplateName == "Branch")
+                    {
+                        createdItem = parentItem.Add(GetLeafFromPath(path), (BranchItem) srcItem);
+                    }
+
+                    if (dic != null && dic[LanguageParam].IsSet)
+                    {
+                        string forcedLanguage = dic[LanguageParam].Value.ToString();
+                        Language language = LanguageManager.GetLanguage(forcedLanguage);
+                        // Based on: http://sdn.sitecore.net/Forum/ShowPost.aspx?postid=16551
+                        // switching language with LanguageSwitcher didn't work
+                        // Thanks Kern!
+                        createdItem.Versions.RemoveAll(true);
+                        createdItem = createdItem.Database.GetItem(createdItem.ID, language);
+                        createdItem = createdItem.Versions.AddVersion();
+                    }
+                    // start default workflow on the created item if necessary
+                    if (dic != null && dic[StartWorkflowParam].IsSet && Context.Workflow.HasDefaultWorkflow(createdItem))
+                    {
+                        IWorkflow defaultWorkflow =
+                            createdItem.Database.WorkflowProvider.GetWorkflow(createdItem[FieldIDs.DefaultWorkflow]);
+                        if (null != defaultWorkflow)
+                        {
+                            defaultWorkflow.Start(createdItem);
+                        }
+                    }
+
+                    WriteItem(createdItem);
+                }
             }
             catch (Exception ex)
             {


> >= < <= operators implementation

> >= < <= operators implementation

--- app/ISukces.SolutionDoctor.Logic/NuGet/NugetVersion.cs
+++ app/ISukces.SolutionDoctor.Logic/NuGet/NugetVersion.cs
@@ -7,16 +7,6 @@
         #regionStaticMethods

         //PublicMethods
-
-        public static bool operator !=(NugetVersion left, NugetVersion right)
-        {
-            return !Equals(left, right);
-        }
-
-        public static bool operator ==(NugetVersion left, NugetVersion right)
-        {
-            return Equals(left, right);
-        }

         public static NugetVersion Parse(string ver)
         {
@@ -108,5 +98,39 @@
         public string Suffix { get; set; }

         #endregionProperties
+
+        #region Operators
+
+        public static bool operator !=(NugetVersion left, NugetVersion right)
+        {
+            return !Equals(left, right);
+        }
+
+        public static bool operator ==(NugetVersion left, NugetVersion right)
+        {
+            return Equals(left, right);
+        }
+
+        public static bool operator >(NugetVersion a, NugetVersion b)
+        {
+            return a.CompareTo(b) > 0;
+        }
+
+        public static bool operator >=(NugetVersion a, NugetVersion b)
+        {
+            return a.CompareTo(b) >= 0;
+        }
+
+        public static bool operator <(NugetVersion a, NugetVersion b)
+        {
+            return a.CompareTo(b) < 0;
+        }
+
+        public static bool operator <=(NugetVersion a, NugetVersion b)
+        {
+            return a.CompareTo(b) <= 0;
+        }
+
+        #endregion
     }
 }


Adding a way to reset the Any cached type, useful if user is programatically modifying the Any instance

SVN: 488784591515bd4cdaa016be4ec9b172dc4e7caf@5060

--- src/NHibernate/Mapping/Any.cs
+++ src/NHibernate/Mapping/Any.cs
@@ -48,6 +48,13 @@
 			}
 		}

+        public void ResetCachedType()
+        {
+            // this is required if the user is programatically modifying the Any instance
+            // and need to reset the cached type instance;
+            type = null;
+        }
+
 		public override void SetTypeUsingReflection(string className, string propertyName, string access)
 		{
 		}


Fix: Missing parameter + simplification.

--- src/Narvalo.Fx/Enumerable$.cs
+++ src/Narvalo.Fx/Enumerable$.cs
@@ -37,9 +37,12 @@
         // Named <c>listToMaybe</c> in Haskell parlance.
         public static Maybe<TSource> FirstOrNone<TSource>(this IEnumerable<TSource> @this)
         {
-            Expect.NotNull(@this);
-
-            return FirstOrNone(@this, Stubs<TSource>.AlwaysTrue);
+            Require.NotNull(@this, nameof(@this));
+
+            using (var iter = @this.GetEnumerator())
+            {
+                return iter.MoveNext() ? Maybe.Of(iter.Current) : Maybe<TSource>.None;
+            }
         }

         public static Maybe<TSource> FirstOrNone<TSource>(
@@ -61,22 +64,29 @@
         {
             Expect.NotNull(@this);

-            return LastOrNone(@this, Stubs<TSource>.AlwaysTrue);
+            return @this.Reverse().EmptyIfNull().FirstOrNone();
         }

         public static Maybe<TSource> LastOrNone<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
         {
-            Require.NotNull(@this, nameof(@this));
-            Require.NotNull(predicate, nameof(predicate));
-
-            return @this.Reverse().EmptyIfNull().FirstOrNone();
+            Expect.NotNull(@this);
+            Expect.NotNull(predicate);
+
+            return @this.Reverse().EmptyIfNull().FirstOrNone(predicate);
         }

         public static Maybe<TSource> SingleOrNone<TSource>(this IEnumerable<TSource> @this)
         {
-            Expect.NotNull(@this);
-
-            return SingleOrNone(@this, Stubs<TSource>.AlwaysTrue);
+            Require.NotNull(@this, nameof(@this));
+
+            using (var iter = @this.EmptyIfNull().GetEnumerator())
+            {
+                // Return None if the sequence is empty.
+                var result = iter.MoveNext() ? Maybe.Of(iter.Current) : Maybe<TSource>.None;
+
+                // Return None if there is one more element.
+                return iter.MoveNext() ? Maybe<TSource>.None : result;
+            }
         }

         public static Maybe<TSource> SingleOrNone<TSource>(


work in progress

work in progress

loadproperties done, now loadcollections.

--- Cfg/CfgNet.cs
+++ Cfg/CfgNet.cs
@@ -1,7 +1,6 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
-using System.Diagnostics.SymbolStore;
 using System.Globalization;
 using System.Linq;
 using System.Reflection;
@@ -212,13 +211,15 @@
         }

         public bool IsInDomain(object value) {
-            return _domainSet == null || _domainSet.Contains(value.ToString());
+            return _domainSet == null || (value != null && _domainSet.Contains(value.ToString()));
         }
     }

     public abstract class CfgNode {

         private static readonly Dictionary<Type, Dictionary<string, CfgMetadata>> MetadataCache = new Dictionary<Type, Dictionary<string, CfgMetadata>>();
+        private static readonly Dictionary<Type, HashSet<string>> KeyCache = new Dictionary<Type, HashSet<string>>();
+        private static readonly Dictionary<Type, HashSet<string>> ListCache = new Dictionary<Type, HashSet<string>>();
         private static Dictionary<string, char> _entities;

         private readonly List<string> _propertyKeys = new List<string>();
@@ -401,7 +402,7 @@
             if (!_properties.ContainsKey(name)) {
                 _propertyKeys.Add(name);
             }
-            _properties[name] = new CfgProperty(name, type, value, attribute) {Set = value != null};
+            _properties[name] = new CfgProperty(name, type, value, attribute) { Set = value != null };
             if (attribute.required) {
                 _requiredProperties.Add(name);
             }
@@ -543,8 +544,14 @@

         private void LoadProperties(NanoXmlNode node, string parentName, IDictionary<string, string> parameters = null) {

-            //ConfigureProperties();
-            var metadata = GetMetadata(GetType(), _builder);
+            var type = GetType();
+            var metadata = GetMetadata(type, _builder);
+            var keys = KeyCache[type];
+
+            if (keys.Count == 0)
+                return;
+
+            var keyHits = new HashSet<string>();

             for (var i = 0; i < node.Attributes.Count; i++) {
                 var attribute = node.Attributes[i];
@@ -561,9 +568,11 @@

                     if (item.PropertyInfo.PropertyType == typeof(string) || item.PropertyInfo.PropertyType == typeof(object)) {
                         item.PropertyInfo.SetValue(this, value, null);
+                        keyHits.Add(attribute.Name);
                     } else {
                         try {
                             item.PropertyInfo.SetValue(this, Converter[item.PropertyInfo.PropertyType](value), null);
+                            keyHits.Add(attribute.Name);
                         } catch (Exception ex) {
                             _problems.SettingValue(item.PropertyInfo.Name, value, parentName, node.Name, ex.Message);
                         }
@@ -573,44 +582,21 @@
                         _problems.ValueNotInDomain(parentName, node.Name, attribute.Name, value, item.Attribute.domain.Replace(item.Attribute.domainDelimiter.ToString(CultureInfo.InvariantCulture), ", "));
                     }
                 } else {
-                    _problems.InvalidAttribute(parentName, node.Name, attribute.Name, string.Join(", ", _properties.Select(kv => kv.Key)));
-                }
-            }
-
-            //for (var i = 0; i < node.Attributes.Count; i++) {
-            //    var attribute = node.Attributes[i];
-            //    if (_properties.ContainsKey(attribute.Name)) {
-            //        if (attribute.Value == null)
-            //            continue;
-
-            //        var value = CheckParameters(parameters, attribute.Value);
-            //        var property = _properties[attribute.Name];
-
-            //        if (value.IndexOf(CfgConstants.ENTITY_START) > -1) {
-            //            value = Decode(value, _builder);
-            //        }
-
-            //        if (!property.IsInDomain(value)) {
-            //            _problems.ValueNotInDomain(parentName, node.Name, property.Name, attribute.Value, property.Attributes.domain.Replace(property.Attributes.domainDelimiter.ToString(CultureInfo.InvariantCulture), ", "));
-            //        }
-
-            //        if (property.Type == typeof(string) || property.Type == typeof(object)) {
-            //            property.Value = value;
-            //            property.Set = true;
-            //        } else {
-            //            try {
-            //                property.Value = Converter[property.Type](value);
-            //                property.Set = true;
-            //            } catch (Exception ex) {
-            //                _problems.SettingValue(property.Name, value, parentName, node.Name, ex.Message);
-            //            }
-            //        }
-            //    } else {
-            //        _problems.InvalidAttribute(parentName, node.Name, attribute.Name, string.Join(", ", _properties.Select(kv => kv.Key)));
-            //    }
-            //}
-
-            CheckRequiredProperties(node, parentName);
+                    _problems.InvalidAttribute(parentName, node.Name, attribute.Name, string.Join(", ", keys));
+                }
+            }
+
+            //set missed keys
+            foreach (var key in keys.Except(keyHits)) {
+                var item = metadata[key];
+                if (item.Attribute.value != null) {
+                    item.PropertyInfo.SetValue(this, item.Attribute.value, null);
+                }
+                if (item.Attribute.required) {
+                    _problems.MissingAttribute(parentName, node.Name, key);
+                }
+            }
+
         }

         private string CheckParameters(IDictionary<string, string> parameters, string input) {
@@ -653,27 +639,6 @@
                 }
             }
             return new Tuple<string, string[]>(builder.ToString(), badKeys == null ? new string[0] : badKeys.ToArray());
-        }
-
-        private void ConfigureProperties() {
-            if (_properties.Count != 0)
-                return;
-
-            var propertyInfos = GetMetadata(GetType(), _builder);
-            foreach (var pair in propertyInfos) {
-                if (pair.Value.PropertyInfo.PropertyType.IsGenericType)
-                    continue;
-
-                Property(pair.Key, pair.Value.PropertyInfo.PropertyType, null, pair.Value.Attribute);
-            }
-        }
-
-        private void CheckRequiredProperties(NanoXmlNode node, string parentName) {
-            for (var i = 0; i < _requiredProperties.Count; i++) {
-                if (!_properties[_requiredProperties[i]].Set) {
-                    _problems.MissingAttribute(parentName, node.Name, _requiredProperties[i]);
-                }
-            }
         }

         protected List<string> UniqueProperties {
@@ -960,17 +925,6 @@

             var metadata = GetMetadata(GetType(), _builder);

-            for (var i = 0; i < _propertyKeys.Count; i++) {
-                var key = _propertyKeys[i];
-                if (!metadata.ContainsKey(key))
-                    continue;
-                try {
-                    metadata[key].PropertyInfo.SetValue(this, _properties[key].Value, null);
-                } catch (Exception ex) {
-                    _problems.SettingProperty(metadata[key].PropertyInfo.Name, _properties[key].Value, _properties[key].Name, ex.Message);
-                }
-            }
-
             foreach (var pair in _collections) {
                 if (!metadata.ContainsKey(pair.Key))
                     continue;
@@ -1015,8 +969,11 @@
             if (MetadataCache.TryGetValue(type, out metadata))
                 return metadata;

-            metadata = new Dictionary<string, CfgMetadata>();
+            var keyCache = new HashSet<string>(StringComparer.Ordinal);
+            var listCache = new HashSet<string>(StringComparer.Ordinal);
             var propertyInfos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
+
+            metadata = new Dictionary<string, CfgMetadata>(StringComparer.Ordinal);
             for (var i = 0; i < propertyInfos.Length; i++) {
                 var propertyInfo = propertyInfos[i];
                 if (propertyInfo.MemberType != MemberTypes.Property)
@@ -1024,11 +981,20 @@
                 var attribute = (CfgAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(CfgAttribute));
                 if (attribute == null)
                     continue;
-                metadata[ToXmlNameStyle(propertyInfo.Name, sb)] = new CfgMetadata(propertyInfo, attribute);
+
+                var key = ToXmlNameStyle(propertyInfo.Name, sb);
+                metadata[key] = new CfgMetadata(propertyInfo, attribute);
+
+                if (propertyInfo.PropertyType.IsGenericType) {
+                    listCache.Add(key);
+                } else {
+                    keyCache.Add(key);
+                }
             }
             MetadataCache[type] = metadata;
+            KeyCache[type] = keyCache;
+            ListCache[type] = listCache;
             return metadata;
-
         }

         public static string Decode(string input, StringBuilder builder) {


Just get the id

Just get the id

--- Anlab.Jobs.SendMail/Program.cs
+++ Anlab.Jobs.SendMail/Program.cs
@@ -79,12 +79,7 @@
                 {
                     Log.Error(failedRecipientEx.Message);
                     message.FailureCount = 5; //Say it failed 5 times so it doesn't try to send again. Otherwise need to change the db.
-                    var messageWithOrder = dbContext.MailMessages.Include(i => i.Order).SingleOrDefault(a => a.Id == message.Id);
-                    int orderId = 0;
-                    if (messageWithOrder != null && messageWithOrder.Order != null)
-                    {
-                        orderId = messageWithOrder.Order.Id;
-                    }
+                    var orderId = dbContext.MailMessages.Where(a => a.Id == message.Id).Select(s => s.Order.Id).Single();

                     MailService.SendFailureNotification(orderId, failedRecipientEx.Message);
                     message.Sent = false;


Add Chaining, and Curry support.

Add Chaining, and Curry support.

Chaining, Service Provider, Curry, and added a new each function. Refactored: renamed Functional<T> to F<T>. Added better argument validation. Moved some functions from F<T> to F, and others from F to F<T>. Goal is to have F<T> contain generic functions, and F to contain non-generic functions.

--- Functional.cs
+++ Functional.cs
@@ -6,302 +6,443 @@
 using System.Threading.Tasks;

 using Functional.Contracts;
+
+//using validate = Validate.NonNullArgument;
 namespace Functional.Implementation {
     public class Something<T> : ISomething<T> {
         public T Item { get; set; }
         public override string ToString() { return this.Item.ToString(); }
         private Something(T t){ this.Item = t; }
-        public static ISomething<T> Create(T t) { return new Something<T>(t); }
+        public static Func<T,ISomething<T>> Create = (t) => new Something<T>(t);
         public static Func<T,T,int> compare = (t1, t2) => 0; //set this to be useful
-        public static int Compare(ISomething<T> t1, ISomething<T> t2) { return compare(t1.Item, t2.Item); }
+        public static Func<ISomething<T>,ISomething<T>,int> Compare = (t1,t2) => compare(t1.Item, t2.Item);
     }
     public class SomethingImmutable<T> : ISomethingImmutable<T> {
         public T Item { get; private set; }
         public override string ToString() { return this.Item.ToString(); }
         private SomethingImmutable(T t) { this.Item = t; }
-        public static ISomethingImmutable<T> Create(T t) { return new SomethingImmutable<T>(t); }
+        public static Func<T,ISomethingImmutable<T>> Create = (t) => new SomethingImmutable<T>(t);
         public static Func<T,T,int> compare = (t1, t2) => 0; //set this to be useful
-        public static int Compare(ISomethingImmutable<T> t1, ISomethingImmutable<T> t2) { return compare(t1.Item, t2.Item); }
+        public static Func<ISomethingImmutable<T>,ISomethingImmutable<T>,int> Compare = (t1,t2) => compare(t1.Item, t2.Item);
     }
     public static class F {
+        private const string FN = "fn";
+        private const string ITEM = "item";
+        private const string LST = "lst";
+        private const string LEFT = "left";
+        private const string RIGHT = "right";
+        private const string X = "x";
+        private const string Y = "y";
+
         public static void DoNothins() { }
         public static void DoNothing<T>(T t) { }
         public static void DoNothing<T,U>(T t, U u) { }
         public static void DoNothing<T,U,V>(T t, U u, V v) { }

-        public static Func<string, IEnumerable<char>> Chars = (s) => s.AsEnumerable();
-        public static Func<IEnumerable<char>, string> CharSequenceToString = (sequence) => {
-            string s = String.Empty;
-            foreach (char c in sequence) s = s + c;
-            return s;
-        };
-        public static Func<int, bool> even = (x) => (0 == (x & 0x0001));
-        public static Func<int, bool> odd = (x) => (1 == (x & 0x0001));
+        /// returns a function that returns either true or false<returns>a Function that returns a bool</returns>
+        public static Func<bool> always(bool b) { return (b) ? alwaysTrue() : alwaysFalse(); }
+        /// returns a function that returns true<returns>a Function that returns a bool</returns>
+        public static Func<Func<bool>> alwaysTrue = () => () => true;
+        /// returns a function that returns false<returns>a Function that returns a bool</returns>
+        public static Func<Func<bool>> alwaysFalse = () => () => false;
+
+        public static Func<string, IEnumerable<char>> Chars = (item) => {
+            Validate.NonNullArgument(item, ITEM);
+            return item.AsEnumerable();
+        };
+        public static Func<IEnumerable<char>,string> CharSequenceToString = (lst) => {
+            Validate.NonNullArgument(lst, LST);
+            return F<char>.reduce<string>(lst,F.add_char_to_string, String.Empty);
+        };
+        public static Func<int,bool> even = (x) => (0 == (x & 0x0001));
+        public static Func<int,bool>  odd = (x) => (1 == (x & 0x0001));
+        public static bool And(this bool b, bool other) { return F.and(b, other); }
+        public static bool Or(this bool b, bool other) { return F.or(b, other); }
+        public static bool All(bool b) { return b; }
+        public static bool All(bool b1, bool b2) { return F.and(b1, b2); }
+        public static bool All(bool b1, bool b2, bool b3) { return (b1 && b2 && b3); }
+        public static bool All(bool b1, bool b2, bool b3, bool b4) { return (b1 && b2 && b3 && b4); }
+        public static bool All(bool b1, bool b2, bool b3, bool b4, bool b5) { return (b1 && b2 && b3 && b4 && b5); }
+        public static bool All(bool b1, bool b2, bool b3, bool b4, bool b5, bool b6) { return (b1 && b2 && b3 && b4 && b5 && b6); }
+        public static bool Any(bool b) { return b; }
+        public static bool Any(bool b1, bool b2) { return F.or(b1, b2); }
+        public static bool Any(bool b1, bool b2, bool b3) { return (b1 || b2 || b3); }
+        public static bool Any(bool b1, bool b2, bool b3, bool b4) { return (b1 || b2 || b3 || b4); }
+        public static bool Any(bool b1, bool b2, bool b3, bool b4, bool b5) { return (b1 || b2 || b3 || b4 || b5); }
+        public static bool Any(bool b1, bool b2, bool b3, bool b4, bool b5, bool b6) { return (b1 || b2 || b3 || b4 || b5 || b6); }

         public static Func<int,int,int>              compare = (l, r) => (l == r) ? 0 : (l < r) ? -1 : 1;
         public static Func<int,int,int>          compare_int = (l, r) => (l == r) ? 0 : (l < r) ? -1 : 1;
         public static Func<long,long,int>       compare_long = (l, r) => (l == r) ? 0 : (l < r) ? -1 : 1;
         public static Func<short,short,int>    compare_short = (l, r) => (l == r) ? 0 : (l < r) ? -1 : 1;
+        public static Func<bool,bool,int>       compare_bool = (l, r) => (eqv(l, r)) ? 0 : (l == false) ? -1 : 1;
         public static Func<char,char,int>       compare_char = (l, r) => (l == r) ? 0 : (l < r) ? -1 : 1;
-        public static Func<string,string,int> compare_string = (l, r) => String.Compare(l, r); // need more testing around this
-        public static Func<string,string,int> compare_string_case_insensative = (l, r) => String.Compare(l.ToUpper(), r.ToUpper());
-
-        public static Func<int,int,bool>              equ = (l, r) => (l == r);
-        public static Func<int,int,bool>          equ_int = (l, r) => (l == r);
-        public static Func<long,long,bool>       equ_long = (l, r) => (l == r);
-        public static Func<short,short,bool>    equ_short = (l, r) => (l == r);
-        public static Func<char,char,bool>       equ_char = (l, r) => (l == r);
-        public static Func<string,string,bool> equ_string = (l, r) => (l == r);
-
-        public static Func<int,int,bool>           neq = (l, r) => (l != r);
-        public static Func<int,int,bool>       neq_int = (l, r) => (l != r);
-        public static Func<long,long,bool>    neq_long = (l, r) => (l != r);
-        public static Func<short,short,bool> neq_short = (l, r) => (l != r);
-
-        public static Func<int,int,int>             add = (x, y) => x + y;
-        public static Func<int,int,int>         add_int = (x, y) => x + y;
-        public static Func<long,long,long>     add_long = (x, y) => x + y;
-        public static Func<short,short,short> add_short = (x, y) => (short)(x + y); //beware overflow
-
-        public static Func<int,int,int>             sub = (x, y) => x - y;
-        public static Func<int,int,int>         sub_int = (x, y) => x - y;
-        public static Func<long,long,long>     sub_long = (x, y) => x - y;
-        public static Func<short,short,short> sub_short = (x, y) => (short)(x - y); //beware underflow
-
-        public static Func<int,int,int>             max = (x, y) => (x > y) ? x : y;
-        public static Func<int,int,int>         max_int = (x, y) => (x > y) ? x : y;
-        public static Func<long,long,long>     max_long = (x, y) => (x > y) ? x : y;
-        public static Func<short,short,short> max_short = (x, y) => (x > y) ? x : y;
-
-        public static Func<int,int,int>             min = (x, y) => (x < y) ? x : y;
-        public static Func<int,int,int>         min_int = (x, y) => (x < y) ? x : y;
-        public static Func<long,long,long>     min_long = (x, y) => (x < y) ? x : y;
-        public static Func<short,short,short> min_short = (x, y) => (x < y) ? x : y;
-
-        public static Func<int,int>           neg = (x) => -x;
-        public static Func<int,int>       neg_int = (x) => -x;
-        public static Func<long,long>    neg_long = (x) => -x;
-        public static Func<short,short> neg_short = (x) => (short)(-x);
-
-        public static Func<float, float, float> fadd = (x, y) => x + y;
-        public static Func<float, float, float> fsub = (x, y) => x - y;
-        public static Func<float, float, float> fmax = (x, y) => (x > y) ? x : y;
-        public static Func<float, float, float> fmin = (x, y) => (x < y) ? x : y;
-        public static Func<float, float> fneg = (x) => -x;
-        public static Func<float, float, bool> close = (x, y) => (Math.Abs(x - y) < 0.01f);
+        public static Func<string, string, int> compare_string = (left, right) => {
+            Validate.NonNullArgument(left, LEFT);
+            Validate.NonNullArgument(right, RIGHT);
+            return String.Compare(left, right);
+        };
+        public static Func<string,string,int> compare_string_case_insensative = (left, right) => {
+            Validate.NonNullArgument(left, LEFT);
+            Validate.NonNullArgument(right, RIGHT);
+            return String.Compare(left.ToUpper(), right.ToUpper());
+        };
+
+        public static Func<int,int,bool>              equ = (left, right) => (left == right);
+        public static Func<int,int,bool>          equ_int = (left, right) => (left == right);
+        public static Func<long,long,bool>       equ_long = (left, right) => (left == right);
+        public static Func<short,short,bool>    equ_short = (left, right) => (left == right);
+        public static Func<bool,bool,bool>       equ_bool = eqv;
+        public static Func<char,char,bool>       equ_char = (left, right) => (left == right);
+
+        public static Func<int,int,bool>              neq = (left, right) => (left != right);
+        public static Func<int,int,bool>          neq_int = (left, right) => (left != right);
+        public static Func<long,long,bool>       neq_long = (left, right) => (left != right);
+        public static Func<short,short,bool>    neq_short = (left, right) => (left != right);
+        public static Func<bool,bool,bool>       neq_bool = xor;
+        public static Func<char,char,bool>       neq_char = (left, right) => (left != right);
+
+        public static Func<int,int,int>                 add = (x, y) => x + y;
+        public static Func<int,int,int>             add_int = (x, y) => x + y;
+        public static Func<long,long,long>         add_long = (x, y) => x + y;
+        public static Func<short,short,short>     add_short = (x, y) => (short)(x + y); //beware overflow
+        public static Func<float,float,float>     add_float = (x, y) => x + y;
+        public static Func<double,double,double> add_double = (x, y) => x + y;
+
+        public static Func<int,int,int>                 sub = (x, y) => x - y;
+        public static Func<int,int,int>             sub_int = (x, y) => x - y;
+        public static Func<long,long,long>         sub_long = (x, y) => x - y;
+        public static Func<short,short,short>     sub_short = (x, y) => (short)(x - y); //beware underflow
+        public static Func<float, float, float>   sub_float = (x, y) => x - y;
+        public static Func<double,double,double> sub_double = (x, y) => x - y;
+
+        public static Func<int,int,int>                 mult = (x, y) => x * y;
+        public static Func<int,int,int>             mult_int = (x, y) => x * y;
+        public static Func<long,long,long>         mult_long = (x, y) => x * y;
+        public static Func<short,short,short>     mult_short = (x, y) => (short)(x * y);
+        public static Func<float,float,float>     mult_float = (x, y) => x * y;
+        public static Func<double,double,double> mult_double = (x, y) => x * y;
+
+        public static Func<int, int, int>               max = (x, y) => (F.gt(x, y)) ? x : y;
+        public static Func<int, int, int>           max_int = (x, y) => (F.gt(x, y)) ? x : y;
+        public static Func<long,long,long>         max_long = (x, y) => (F.gt_long(x,y)) ? x : y;
+        public static Func<short,short,short>     max_short = (x, y) => (F.gt_short(x,y)) ? x : y;
+        public static Func<float,float,float>     max_float = (x, y) => (F.gt_float(x, y)) ? x : y;
+        public static Func<double,double,double> max_double = (x, y) => (F.gt_double(x, y)) ? x : y;
+
+        public static Func<int,int,int>                 min = (x, y) => (F.lt(x,y)) ? x : y;
+        public static Func<int,int,int>             min_int = (x, y) => (F.lt(x,y)) ? x : y;
+        public static Func<long,long,long>         min_long = (x, y) => (F.lt_long(x,y)) ? x : y;
+        public static Func<short,short,short>     min_short = (x, y) => (F.lt_short(x,y)) ? x : y;
+        public static Func<float,float,float>     min_float = (x, y) => (F.lt_float(x, y)) ? x : y;
+        public static Func<double,double,double> min_double = (x, y) => (F.lt_double(x, y)) ? x : y;
+
+        public static Func<int,int>              neg = (x) => -x;
+        public static Func<int,int>          neg_int = (x) => -x;
+        public static Func<long,long>       neg_long = (x) => -x;
+        public static Func<short,short>    neg_short = (x) => (short)(-x);
+        public static Func<float,float>    neg_float = (x) => -x;
+        public static Func<double,double> neg_double = (x) => -x;
+
+        public static Func<int,int>           inc = (x) => F.add(x,1);
+        public static Func<int, int>      inc_int = inc;
+        public static Func<long,long>    inc_long = (x) => F.add_long(x,1L);
+        public static Func<short,short> inc_short = (x) => (short)(x + 1);
+

-        public static Func<int,int,bool>           gt = (l, r) => (l > r);
-        public static Func<int,int,bool>       gt_int = (l, r) => (l > r);
-        public static Func<long,long,bool>    gt_long = (l, r) => (l > r);
-        public static Func<short,short,bool> gt_short = (l, r) => (l > r);
-
-        public static Func<int,int,bool>           gte = (l, r) => (l >= r);
-        public static Func<int,int,bool>       gte_int = (l, r) => (l >= r);
-        public static Func<long,long,bool>    gte_long = (l, r) => (l >= r);
-        public static Func<short,short,bool> gte_short = (l, r) => (l >= r);
-
-
-        public static Func<int,int,bool>           lt = (l, r) => (l < r);
-        public static Func<int,int,bool>       lt_int = (l, r) => (l < r);
-        public static Func<long,long,bool>    lt_long = (l, r) => (l < r);
-        public static Func<short,short,bool> lt_short = (l, r) => (l < r);
-
-
-        public static Func<int,int,bool>           lte = (l, r) => (l <= r); // this is one reason why operators suck
-        public static Func<int,int,bool>       lte_int = (l, r) => (l <= r);
-        public static Func<long,long,bool>    lte_long = (l, r) => (l <= r);
-        public static Func<short,short,bool> lte_short = (l, r) => (l <= r);
-
+        public static Func<float,float,bool>             close_float = (x, y) => (F.lt_float(Math.Abs(F.sub_float(x,y)),0.01f));
+        public static Func<double,double,bool>          close_double = (x, y) => (F.lt_double(Math.Abs(F.sub_double(x, y)), 0.01d));
+        public static Func<float,float,float,float>      clamp_float = (x,min,max) => (F.lt_float(x,min)) ? min : (F.gt_float(x,max)) ? max : x;
+        public static Func<double,double,double,double> clamp_double = (x,min,max) => (F.lt_double(x,min)) ? min : (F.gt_double(x,max)) ? max : x;
+
+        public static Func<int,int>               sqr = (x) => x * x;
+        public static Func<int,int>           sqr_int = (x) => x * x;
+        public static Func<long,long>        sqr_long = (x) => x * x;
+        public static Func<short, short>    sqr_short = (x) => (short)(x * x);
+        public static Func<float,float>     sqr_float = (x) => x * x;
+        public static Func<double,double>  sqr_double = (x) => x * x;
+        public static Func<float,float>    sqrt_float = (x) => { Validate.PositiveArgument(x, X); return (float)Math.Sqrt(x); };
+        public static Func<double,double> sqrt_double = (x) => { Validate.PositiveArgument(x, X); return (float)Math.Sqrt(x); };

-
-        public static Func<bool, bool, bool> or = (l, r) => l || r;
-        public static Func<bool, bool, bool> and = (l, r) => l && r;
-        public static Func<bool, bool, bool> xor = (l, r) => l != r;
-        public static Func<bool, bool> not = x => !x;
-        ///
-        /// A function given two strings, returns the combined string
-        ///
-        /// <returns>A combined string</returns>
-        public static Func<string, string, string> combine = (l, r) => l + r;
-        ///
-        /// A function given two strings, true if they are equal
-        ///
-        /// <returns>true if they are equal</returns>
-        public static Func<string, string, bool> sequ = (l, r) => l == r;
-        ///
-        /// A function given two strings, true if they are not equal
-        ///
-        /// <returns>true if they are not equal</returns>
-        public static Func<string, string, bool> sneq = (l, r) => l != r;
-        ///
-        /// A function given start, returns an infinite sequence of increasing integers. (warning: integer overflow)
-        ///
-        /// <returns>An infinite sequence of increasing integers</returns>
-        public static IEnumerable<int> infinite_range(int start) { for (int i = start; true; i++) yield return i; }
+        public static Func<int,int,bool>                gt = (left, right) => (left > right);
+        public static Func<int,int,bool>            gt_int = (left, right) => (left > right);
+        public static Func<long,long,bool>         gt_long = (left, right) => (left > right);
+        public static Func<short,short,bool>      gt_short = (left, right) => (left > right);
+        public static Func<float, float, bool>    gt_float = (left, right) => (left > right);
+        public static Func<double, double, bool> gt_double = (left, right) => (left > right);
+
+        public static Func<int,int,bool>           gte = (left, right) => (left >= right);
+        public static Func<int,int,bool>       gte_int = (left, right) => (left >= right);
+        public static Func<long,long,bool>    gte_long = (left, right) => (left >= right);
+        public static Func<short,short,bool> gte_short = (left, right) => (left >= right);
+
+
+        public static Func<int,int,bool>                lt = (left, right) => (left < right);
+        public static Func<int,int,bool>            lt_int = (left, right) => (left < right);
+        public static Func<long,long,bool>         lt_long = (left, right) => (left < right);
+        public static Func<short,short,bool>      lt_short = (left, right) => (left < right);
+        public static Func<float, float, bool>    lt_float = (left, right) => (left < right);
+        public static Func<double, double, bool> lt_double = (left, right) => (left < right);
+
+
+        public static Func<int,int,bool>           lte = (left, right) => (left <= right); // this is one reason why operators suck
+        public static Func<int,int,bool>       lte_int = (left, right) => (left <= right);
+        public static Func<long,long,bool>    lte_long = (left, right) => (left <= right);
+        public static Func<short,short,bool> lte_short = (left, right) => (left <= right);
+
+
+
+        public static Func<bool,bool,bool>  or = (left, right) => left || right;
+        public static Func<bool,bool,bool> and = (left, right) => left && right;
+        public static Func<bool,bool,bool> xor = (left, right) => left != right;
+        public static Func<bool,bool,bool> eqv = (left, right) => left == right;
+        public static Func<bool,bool> not = x => !x;
+        /// A function given two strings, returns the combined string<returns>A combined string</returns>
+        public static Func<string, string, string> add_string = (left, right) => {
+            Validate.NonNullArgument(left, LEFT);
+            Validate.NonNullArgument(right, RIGHT);
+            return left + right;
+        };
+        /// A function given two strings, true if they are equal<returns>true if they are equal</returns>
+        public static Func<string, string, bool> equ_string = (left, right) => {
+            Validate.NonNullArgument(left, LEFT);
+            Validate.NonNullArgument(right, RIGHT);
+            return left == right;
+        };
+        /// A function given two strings, true if they are not equal<returns>true if they are not equal</returns>
+        public static Func<string, string, bool> neq_string = (left, right) => {
+            Validate.NonNullArgument(left, LEFT);
+            Validate.NonNullArgument(right, RIGHT);
+            return left != right;
+        };
+        public static Func<string, char, string> add_char_to_string = (left, c) => {
+            Validate.NonNullArgument(left, LEFT);
+            return left + c;
+        };
+
+
+        public static Func<bool, IEnumerable<bool>> infinite_bool = (b) => F<bool>.forever(b);
+        public static Func<bool, IEnumerable<bool>> infinite_bool_toggle = (b) => F<bool>.forever(not, b);
+
+
+        /// A function given start, returns an infinite sequence of increasing integers. (warning: integer overflow)<returns>An infinite sequence of increasing integers</returns>
+        public static Func<int,IEnumerable<int>> infinite_range = (start) => F<int>.forever((n)=>n+1,start);
         public static IEnumerable<int> range(int start, int end) {
-            int step = ((end - start) > 0) ? 1 : -1;
-            for (int i = start; neq(i, end); i += step) yield return i;
+            int step = (F.gt(F.sub(end,start),0)) ? 1 : -1;
+            for (int i = start; F.neq(i, end); i=F.add(i,step)) yield return i;
         }
         public static IEnumerable<int> range(int start, int end, int step) {
-            int Step = ((end - start) > 0) ? Math.Abs(step) : -Math.Abs(step);
-            Func<int, int, bool> condition = ((end - start) > 0) ? lt : gt;
-            for (int i = start; condition(i, end); i += Step) yield return i;
+            int Step = (F.gt(F.sub(end,start),0)) ? Math.Abs(step) : -Math.Abs(step);
+            Func<int, int, bool> condition = (F.gt(F.sub(end,start),0)) ? F.lt : F.gt;
+            for (int i = start; condition(i, end); i = F.add(i,Step)) yield return i;
         }
         public static IEnumerable<int> range(int end) { return range(0, end); }
-        ///
-        /// A function given minimum, and maximum, that returns a sequence of random integers
-        ///
-        /// <returns>An infinite sequence of random integers between minimum and maximum</returns>
+        /// A function given minimum, and maximum, that returns a sequence of random integers<returns>An infinite sequence of random integers between minimum and maximum</returns>
         public static IEnumerable<int> random(int minimum, int maximum) {
             Random r = new Random(DateTime.Now.Millisecond);
             while (true) yield return r.Next(minimum, maximum);
         }
-        ///
-        /// A function given length, that returns a sequence of random integers
-        ///
-        /// <returns>A sequence of random integers</returns>
+        /// A function given length, that returns a sequence of random integers<returns>A sequence of random integers</returns>
         public static IEnumerator<int> random(int count) {
             Random r = new Random(DateTime.Now.Millisecond);
-            for (int i = 0; i < count; i++) yield return r.Next();
-        }
-        ///
-        /// A function given length, minimum, and maximum, that returns a sequence of random integers
-        ///
-        /// <returns>A sequence of random integers between minimum and maximum</returns>
+            for (int i = 0; lt(i,count); i=inc(i)) yield return r.Next();
+        }
+        /// A function given length, minimum, and maximum, that returns a sequence of random integers<returns>A sequence of random integers between minimum and maximum</returns>
         public static IEnumerable<int> random(int count, int minimum, int maximum) {
             Random r = new Random(DateTime.Now.Millisecond);
-            for (int i = 0; i < count; i++) yield return r.Next(minimum, maximum);
-        }
-
-        public static string toString<T>(T t) { return t.ToString(); }
-        public static Func<string, int> StringToInt = (s) => {
+            for (int i = 0; lt(i,count); i=inc(i)) yield return r.Next(minimum, maximum);
+        }
+        public static Func<string, int> string_to_int = (item) => {
+            Validate.NonNullArgument(item, ITEM);
             int result = 0;
-            int.TryParse(s, out result);
+            int.TryParse(item, out result);
             return result;
         };
-        public static Func<string,bool> StringToBool = (s) =>  ("TRUE" == s.ToUpper());
-        public static Action<Action<int>,int>          ApplyInt = Functional<int>.Apply;
-        public static Action<Action<long>,long>       ApplyLong = Functional<long>.Apply;
-        public static Action<Action<short>,short>    ApplyShort = Functional<short>.Apply;
-        public static Action<Action<bool>,bool>       ApplyBool = Functional<bool>.Apply;
-        public static Action<Action<string>,string> ApplyString = Functional<string>.Apply;
-        public static void Add<T>(IList<T> lst, T t) { lst.Add(t); }
-
-        public static IEnumerable<T> LoadTextFile<T>(string filename, Encoding encoding, Func<string,T> fn) {
-            using (StreamReader sr = new StreamReader(filename, encoding)) {
-                string line = sr.ReadLine();
-                while (!String.IsNullOrEmpty(line)) {
-                    yield return fn(line);
-                    line = sr.ReadLine();
-                }
-            }
-        }
-
-    }
-    public static class Functional<T>   {
-
-        public static void Apply(Action<T> fn, T n) { fn(n); }
-        ///
-        /// Given a function that takes a T and function that takes an T and returns a X, return a function that takes an X
-        ///
-        /// <returns>Function that takes an X</returns>
-        public static Action<T> transform<X>(Action<X> a, Func<T, X> fn) { return (n) => a(fn(n)); }
-        ///
-        /// from a sequence of dictionaries, get all the values that share the key
-        ///
-        /// <returns>sequence of items</returns>
-        public static IEnumerable<T> items(IEnumerable<IDictionary<string, T>> lst, string key) {
+        public static Func<string, long> string_to_long = (item) => {
+            Validate.NonNullArgument(item, ITEM);
+            long result = 0;
+            long.TryParse(item, out result);
+            return result;
+        };
+        public static Func<string, short> string_to_short = (item) => {
+            Validate.NonNullArgument(item, ITEM);
+            short result = 0;
+            short.TryParse(item, out result);
+            return result;
+        };
+        public static Func<string, float> string_to_float = (item) => {
+            Validate.NonNullArgument(item, ITEM);
+            float result = 0.0f;
+            float.TryParse(item, out result);
+            return result;
+        };
+        public static Func<string, double> string_to_double = (item) => {
+            Validate.NonNullArgument(item, ITEM);
+            double result = 0.0d;
+            double.TryParse(item, out result);
+            return result;
+        };
+
+        public static Func<string, bool> string_to_bool = (item) => {
+            Validate.NonNullArgument(item, ITEM);
+            return F.equ_string("TRUE", item.ToUpper());
+        };
+
+        public static Action<Action<int>,int>          InvokeInt = F<int>.invoke;
+        public static Action<Action<long>,long>       InvokeLong = F<long>.invoke;
+        public static Action<Action<short>,short>    InvokeShort = F<short>.invoke;
+        public static Action<Action<bool>,bool>       InvokeBool = F<bool>.invoke;
+        public static Action<Action<char>, char>      InvokeChar = F<char>.invoke;
+        public static Action<Action<string>,string> InvokeString = F<string>.invoke;
+
+        public static Func<Func<int,int>,int,int>                ApplyInt = F<int>.apply;
+        public static Func<Func<long,long>,long,long>           ApplyLong = F<long>.apply;
+        public static Func<Func<short,short>,short,short>      ApplyShort = F<short>.apply;
+        public static Func<Func<bool,bool>,bool,bool>           ApplyBool = F<bool>.apply;
+        public static Func<Func<char,char>,char,char>           ApplyChar = F<char>.apply;
+        public static Func<Func<string,string>,string,string> ApplyString = F<string>.apply;
+
+
+
+    }
+    public static class F<T>   {
+        private const string FILENAME = "filename";
+        private const string ITEM = "item";
+        private const string FN = "fn";
+        private const string ACC = "acc";
+        private const string ACTION = "action";
+        private const string PREDICATE = "predicate";
+        private const string LST = "lst";
+        private const string LST1 = "lst1";
+        private const string LST2 = "lst2";
+        private const string LST3 = "lst3";
+
+        public static Func<T, T> identity = (item) => item;
+
+        public static void invoke(Action<T> action,T t) {
+            Validate.NonNullArgument(action, ACTION);
+            action.Invoke(t);
+        }
+        public static void invoke(Action<T,T> action,T t1, T t2) {
+            Validate.NonNullArgument(action, ACTION);
+            action.Invoke(t1, t2);
+        }
+        public static void invoke(Action<T,T,T> action, T t1, T t2, T t3) {
+            Validate.NonNullArgument(action, ACTION);
+            action.Invoke(t1, t2, t3);
+        }
+        public static T apply(Func<T,T> fn, T t)  {
+            Validate.NonNullArgument(fn, FN);
+            return fn.Invoke(t);
+        }
+        public static T apply(Func<T, T, T> fn, T t1, T t2) {
+            Validate.NonNullArgument(fn, FN);
+            return fn.Invoke(t1, t2);
+        }
+        public static T apply(Func<T,T,T,T> fn, T t1, T t2, T t3) {
+            Validate.NonNullArgument(fn, FN);
+            return fn.Invoke(t1, t2, t3);
+        }
+        /// Given a function that takes a T and function that takes an T and returns a X, return a function that takes an X<returns>Function that takes an X</returns>
+        public static Action<T> transform<X>(Action<X> action, Func<T, X> fn) {
+            Validate.NonNullArgument(action, ACTION);
+            Validate.NonNullArgument(fn, FN);
+            return (n) => action(fn(n));
+        }
+        /// from a sequence of dictionaries, get all the values that share the key<returns>sequence of items</returns>
+        public static IEnumerable<T> items(IEnumerable<IDictionary<string, T>> lst, string item) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(item, ITEM);
             foreach (IDictionary<string, T> dictionary in lst) {
-                if (dictionary.Keys.Contains(key)) yield return dictionary[key];
-            }
-        }
-        ///
-        /// true if both sequences are the same. Not valid for sequences of functions.
-        ///
-        /// <returns>bool</returns>8832707
-        /// 8705 willows rd red 98052
+                if (dictionary.Keys.Contains(item)) yield return dictionary[item];
+            }
+        }
+        /// true if both sequences are the same. Not valid for sequences of functions.<returns>bool</returns>
         public static Func<IEnumerable<T>, IEnumerable<T>, Func<T, T, bool>, bool> same = (lst1, lst2, fn) => {
+            Validate.NonNullArgument(lst1, LST1);
+            Validate.NonNullArgument(lst2, LST2);
+            Validate.NonNullArgument(fn, FN);
             IEnumerator<T> i1 = lst1.GetEnumerator();
             IEnumerator<T> i2 = lst2.GetEnumerator();
             bool result = true;
             bool b1 = i1.MoveNext();
             bool b2 = i2.MoveNext();
-            while (result && (b1 && b2)) {
+            while (F.and(result,F.and(b1,b2))) {
                 result = fn(i1.Current, i2.Current);
                 b1 = i1.MoveNext();
                 b2 = i2.MoveNext();
             }
-            return (result && (b1 == b2));
-        };
-        ///
-        /// Given a sequence and a predicate, indicates if any elemnt passes the predicate
-        ///
-        /// <returns>true if any of the elements pass the predicate function</returns>
-        public static Func<IEnumerable<T>, Func<T, bool>, bool> any = (lst, fn) => lst.Any(fn);
-        ///
-        /// Given a sequence and a predicate, indicates if every elemnt passes the predicate
-        ///
-        /// <returns>true if all the elements pass the predicate function</returns>
-        public static Func<IEnumerable<T>, Func<T, bool>, bool> all = (lst, fn) => lst.All(fn);
-        ///
-        /// Given a sequence and a predicate, return the filtered sequence
-        ///
-        /// <returns>a sequence of T that meets the criteria of the predicate function</returns>
-        public static Func<IEnumerable<T>, Func<T, bool>, IEnumerable<T>> filter = (lst, fn) => lst.Where(fn);
-        ///
-        /// Given a predicate function fn(x) return !fn(x)
-        ///
-        /// <returns>The compliment if the predicate function</returns>
-        public static Func<T, bool> compliment(Func<T, bool> fn) { return (t) => { return !fn(t); }; }
-        ///
-        /// Swap the order of the parameters. compliment of f(a,b) is f(b,a)
-        ///
-        /// <returns>T, the result of the call</returns>
-        public static Func<T, T, T> compliment(Func<T, T, T> fn) { return (x, y) => { return fn(y, x); }; }
-
-        ///
-        /// get the first element of a sequence
-        ///
-        /// <returns>The first element of an IEnumerable</returns>
-        public static Func<IEnumerable<T>,T> first = (lst) => lst.First();
-        ///
-        /// get the sequence following the first element of a sequence
-        ///
-        /// <returns>an IEnermerable following the first element</returns>
-        public static Func<IEnumerable<T>,IEnumerable<T>> rest = (lst) => lst.Skip(1);
-        ///
-        /// find the first item that meets the condition function
-        /// throws System.InvalidOperationException if no match is found
-        ///
-        /// <returns>T or null</returns>
-        public static Func<IEnumerable<T>,Func<T,bool>,T> find = (lst,cond) => lst.First(cond);
-        ///
-        /// sorts a finite sequnce.
-        ///
-        /// <returns>a sequence</returns>
+            return (F.and(result,F.equ_bool(b1,b2)));
+        };
+        /// Given a sequence and a predicate, indicates if any elemnt passes the predicate<returns>true if any of the elements pass the predicate function</returns>
+        public static Func<IEnumerable<T>, Func<T, bool>, bool> any = (lst, predicate) => {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(predicate, PREDICATE);
+            return lst.Any(predicate);
+        };
+        /// Given a sequence and a predicate, indicates if every elemnt passes the predicate<returns>true if all the elements pass the predicate function</returns>
+        public static Func<IEnumerable<T>, Func<T, bool>, bool> all = (lst, predicate) => {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(predicate, PREDICATE);
+            return lst.All(predicate);
+        };
+        /// Given a sequence and a predicate, return the filtered sequence<returns>a sequence of T that meets the criteria of the predicate function</returns>
+        public static Func<IEnumerable<T>, Func<T, bool>, IEnumerable<T>> filter = (lst, predicate) => {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(predicate, PREDICATE);
+            return lst.Where(predicate);
+        };
+        /// Given a predicate function fn(x) return !fn(x)<returns>The compliment if the predicate function</returns>
+        public static Func<T, bool> compliment(Func<T, bool> fn) {
+            Validate.NonNullArgument(fn, FN);
+            return (t) => { return !fn(t); };
+        }
+        /// Swap the order of the parameters. compliment of f(a,b) is f(b,a)<returns>T, the result of the call</returns>
+        public static Func<T, T, T> compliment(Func<T, T, T> fn) {
+            Validate.NonNullArgument(fn, FN);
+            return (x, y) => { return fn(y, x); };
+        }
+        /// get the first element of a sequence<returns>The first element of an IEnumerable</returns>
+        public static Func<IEnumerable<T>, T> first = (lst) => {
+            Validate.NonNullArgument(lst, LST);
+            return lst.First();
+        };
+        /// get the sequence following the first element of a sequence<returns>an IEnermerable following the first element</returns>
+        public static Func<IEnumerable<T>, IEnumerable<T>> rest = (lst) => {
+            Validate.NonNullArgument(lst, LST);
+            return lst.Skip(1);
+        };
+        /// find the first item that meets the condition function throws System.InvalidOperationException if no match is found<returns>T or null</returns>
+        public static Func<IEnumerable<T>, Func<T, bool>, T> find = (lst, predicate) => {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(predicate, PREDICATE);
+            return lst.First(predicate);
+        };
+        /// sorts a finite sequnce.<returns>a sequence</returns>
         public static Func<IEnumerable<T>, Func<T, T, int>, IEnumerable<T>> sort = (lst, fn) => {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
             T[] x = lst.ToArray();
             Array.Sort(x, new Comparer<T>(fn));
             return x.ToList();
         };
-        ///
-        /// sorts a sequence (most of the time)
-        ///
-        /// <returns>a sorted sequence</returns>
-        public static Func<IEnumerable<T>,Func<T, T, int>,IEnumerable<T>> sort2 = (lst,fn) => lst.OrderBy(t=>t, new Comparer<T>(fn));
-        ///
-        /// Bubble sort a finite sequence.
-        ///
-        /// <returns>A sorted sequence</returns>
-        // bubble sort
-        public static Func<IEnumerable<T>, Func<T, T, int>, IEnumerable<T>> sort3 = (lst, fn) => {
+        /// sorts a sequence (most of the time)<returns>a sorted sequence</returns>
+        public static Func<IEnumerable<T>, Func<T, T, int>, IEnumerable<T>> sort_order_by = (lst, fn) => {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            return lst.OrderBy(F<T>.identity, new Comparer<T>(fn));
+        };
+        /// Bubble sort a finite sequence.<returns>A sorted sequence</returns>
+        public static Func<IEnumerable<T>, Func<T, T, int>, IEnumerable<T>> sort_bubble_sort = (lst, fn) => {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
             T[] array = lst.ToArray();
             bool swapped = true;
             while (swapped) {
                 swapped = false;
-                for (int i = 0; i < array.Length - 1; i++) {
-                    if (fn(array[i], array[1 + 1]) > 0) {
+                for (int i = 0; F.lt(i,array.Length - 1); i=F.inc(i)) {
+                    if (F.gt(fn(array[i], array[1 + 1]),0)) {
                         swapped = true;
                         T temp = array[i];
                         array[i] = array[i + 1];
@@ -311,76 +452,106 @@
             }
             return array;
         };
-        ///
-        /// Runs a function an each member of a sequence
-        ///
-        /// <returns>nothing</returns>
-        public static void each(IEnumerable<T> lst,Action<T> fn) { foreach (T t in lst) fn(t); }
-        public static void each(IEnumerable<T> lst, Action<T,U> fn, U u) { foreach (T t in lst) fn(t, u); }
-        public static void each(IEnumerable<T> lst, Action<T,U,V> fn, U u, V v) { foreach (T t in lst) fn(t, u, v); }
-        public static void each(IEnumerable<T> lst, Action<T,U,V,W> fn, U u, V v, W w) { foreach (T t in lst) fn(t, u, v, w); }
-        public static void each(IEnumerable<T> lst, Action<T,U,V,W,X> fn, U u, V v, W w, X x) { foreach (T t in lst) fn(t, u, v, w, x); }
-        ///
-        /// runs an accumulatr function as long as the check function is true
-        ///
-        /// <returns>a sequence of T</returns>
-        public static IEnumerable<T> iterateWhile(Func<T, T> fun, Func<T, bool> check, T init) {
+        /// Runs a function an each member of a sequence<returns>nothing</returns>
+        public static void each(IEnumerable<T> lst,Action<T> fn) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            foreach (T t in lst) fn(t);
+        }
+        public static void each(IEnumerable<T> lst, Action<T,U> fn, U u) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            foreach (T t in lst) fn(t, u);
+        }
+        public static void each(IEnumerable<T> lst, Action<T,U,V> fn, U u, V v) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            foreach (T t in lst) fn(t, u, v);
+        }
+        public static void each(IEnumerable<T> lst, Action<T,U,V,W> fn, U u, V v, W w) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            foreach (T t in lst) fn(t, u, v, w);
+        }
+        public static void each(IEnumerable<T> lst, Action<T,U,V,W,X> fn, U u, V v, W w, X x) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            foreach (T t in lst) fn(t, u, v, w, x);
+        }
+        public static void each(IEnumerable<T> lst, Action<T, U, V> fn, U u, Func<V, V> acc, V init) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            Validate.NonNullArgument(acc,ACC);
+            V current = init;
+            foreach (T t in lst) {
+                fn(t, u, current);
+                current = acc(current);
+            }
+        }
+
+        /// runs an accumulatr function as long as the check function is true<returns>a sequence of T</returns>
+        public static IEnumerable<T> iterate_while(Func<T, T> fn, Func<T, bool> predicate, T init) {
+            Validate.NonNullArgument(fn, FN);
+            Validate.NonNullArgument(predicate, PREDICATE);
             T result = init;
-            while (check(result)) {
+            while (predicate(result)) {
                 yield return result;
-                result = fun(result);
-            }
-        }
-        ///
-        /// returns a function that return the input
-        ///
-        /// <returns>a Function</returns>
+                result = fn(result);
+            }
+        }
+        /// returns a function that return the input<returns>a Function</returns>
         public static Func<T> always(T t) { return () => t; }
-        ///
-        /// returns a function that returns either true or false
-        ///
-        /// <returns>a Function that returns a bool</returns>
-        public static Func<bool> always(bool b) { return (b) ? alwaysTrue() : alwaysFalse(); }
-        ///
-        /// returns a function that returns true
-        ///
-        /// <returns>a Function that returns a bool</returns>
-        public static Func<Func<bool>> alwaysTrue = () => () => true;
-        ///
-        /// returns a function that returns false
-        ///
-        /// <returns>a Function that returns a bool</returns>
-        public static Func<Func<bool>> alwaysFalse = () => () => false;
-        ///
-        /// returns a sequence that is the result of a sequence transformed by a function
-        ///
-        /// <returns>A sequence of objects of type T</returns>
-        public static IEnumerable map(IEnumerable<T> lst, Func<T,U> fn) { return lst.Select(fn); }
+
+        public static IEnumerable<T> limit(IEnumerable<T> lst, int count) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.PositiveArgument(count, "count");
+            return lst.Take(count);
+        }
+        public static IEnumerable<T> forever(T t) { while (true) yield return t; }
+        public static IEnumerable<T> forever(Func<T, T> fn, T t) {
+            Validate.NonNullArgument(fn, FN);
+            T result = t;
+            while (true) {
+                yield return result;
+                result = fn(result);
+            }
+        }
+        /// returns a sequence that is the result of a sequence transformed by a function<returns>A sequence of objects of type T</returns>
+        public static IEnumerable map(IEnumerable<T> lst, Func<T,U> fn) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            return lst.Select(fn);
+        }
         public static IEnumerable map(IEnumerable<T> lst, Func<T,V,U> fn, V v) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
             foreach (T t in lst) yield return fn(t, v);
         }
         public static IEnumerable map(IEnumerable<T> lst, Func<T,V,W,U> fn, V v, W w) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
             foreach (T t in lst) yield return fn(t, v, w);
         }
         public static IEnumerable map(IEnumerable<T> lst, Func<T,V,W,X,U> fn, V v, W w, X x) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
             foreach (T t in lst) yield return fn(t, v, w, x);
         }
-        ///
-        /// returns a sequence that is fed by two other sequences and a combining function fn
-        ///
-        /// <returns>A sequence of objects of type T</returns>
-        public static IEnumerable map(IEnumerable<T> lst1, IEnumerable<T> lst2, Func<T, T, U> fn) {
+        /// returns a sequence that is fed by two other sequences and a combining function fn<returns>A sequence of objects of type T</returns>
+        public static IEnumerable map(IEnumerable<T> lst1, IEnumerable<T> lst2, Func<T, T, U> fn) {
+            Validate.NonNullArgument(lst1, LST1);
             IEnumerator<T> one = lst1.GetEnumerator();
             IEnumerator<T> two = lst2.GetEnumerator();
             while ((one.MoveNext()) && (two.MoveNext())) {
                 yield return fn(one.Current, two.Current);
             }
         }
-        ///
-        /// returns a sequence that is fed by three other sequences and a combining function fn
-        ///
-        /// <returns>A sequence of objects of type T</returns>
+        /// returns a sequence that is fed by three other sequences and a combining function fn<returns>A sequence of objects of type T</returns>
         public static IEnumerable map(IEnumerable<T> lst1, IEnumerable<T> lst2, IEnumerable<T> lst3, Func<T, T, T, U> fn) {
+            Validate.NonNullArgument(lst1, LST1);
+            Validate.NonNullArgument(lst2, LST2);
+            Validate.NonNullArgument(lst3, LST3);
+            Validate.NonNullArgument(fn, FN);
             IEnumerator<T> one = lst1.GetEnumerator();
             IEnumerator<T> two = lst2.GetEnumerator();
             IEnumerator<T> three = lst3.GetEnumerator();
@@ -388,97 +559,342 @@
                 yield return fn(one.Current, two.Current, three.Current);
             }
         }
-        ///
-        /// Takes a sequence of objects of type T and a map function that transforms an object of type T to a sequence of objects of type U
-        ///
-        /// <returns>A sequence of objects of type U</returns>
+        /// Takes a sequence of objects of type T and a map function that transforms an object of type T to a sequence of objects of type U<returns>A sequence of objects of type U</returns>
         public static IEnumerable flatten(IEnumerable<T> lst, Func<T, IEnumerable> fn) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
             foreach (T t in lst) {
                 foreach (U u in fn(t)) {
                     yield return u;
                 }
             }
         }
-        ///
-        /// Takes a sequence of T and an accumulation function
-        ///
-        /// <returns>the accumulation of the sequence</returns>
-        public static T reduce(IEnumerable<T> lst,Func<T, T, T> acc) { return lst.Aggregate(acc);}
-        ///
-        /// Takes an enumeration of T, an accumulation function, and an initial item, and applies the accumulation function acc to all the element.
-        ///
+        /// Takes a sequence of T and an accumulation function<returns>the accumulation of the sequence</returns>
+        public static T reduce(IEnumerable<T> lst,Func<T, T, T> fn) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            return lst.Aggregate(fn);
+        }
+        /// Takes an enumeration of T, an accumulation function, and an initial item, and applies the accumulation function acc to all the element.<returns>A U</returns>
+        public static T reduce(IEnumerable<T> lst, Func<T, T, T> fn, T item) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
+            Validate.NonNullArgument(item, ITEM);
+            return lst.Aggregate(item, fn);
+        }
+        /// Takes an enumeration of T, and applies the accumulation function acc to all the element.<returns>A U</returns>
+        public static U reduce(IEnumerable<T> lst, Func fn, U item) {
+            Validate.NonNullArgument(lst,LST);
+            Validate.NonNullArgument(fn,FN);
+            Validate.NonNullArgument(item, ITEM);
+            return lst.Aggregate<T, U, U>(item, fn, z => z);
+        }
+
+        /// Takes an enumeration of T, and applies the accumulation function acc to all the element.
+        /// <param name="initialItem">Initial value</param>
         /// <returns>A U</returns>
-        public static T reduce(IEnumerable<T> lst, Func<T, T, T> acc, T initialItem) { return lst.Aggregate(initialItem, acc); }
-        ///
-        /// Takes an enumeration of T, and applies the accumulation function acc to all the element.
-        ///
-        /// <returns>A U</returns>
-        public static U reduce(IEnumerable<T> lst, Func acc, U initialItem) {
-            return lst.Aggregate<T, U, U>(initialItem, acc, z => z);
-        }
-
-        ///
-        /// Takes an enumeration of T, and applies the accumulation function acc to all the element.
-        ///
-        /// <returns>A U</returns>
-        public static U reduce(IEnumerable<T> lst, Func acc, T initialItem, U initialResult) {
+        public static U reduce(IEnumerable<T> lst, Func fn, T initialItem, U initialResult) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(fn, FN);
             U runningResult = initialResult;
             T lastItem = initialItem;
             foreach (T currentItem in lst) {
-                runningResult = acc(runningResult, lastItem, currentItem);
+                runningResult = fn(runningResult, lastItem, currentItem);
                 lastItem = currentItem;
             }
             return runningResult;
         }
-        public static void AddNonNull(IList<T> lst, T t) { if (null != t) lst.Add(t); }
+        public static IEnumerable<KeyValuePair<T, U>> combination(IEnumerable<T> keys, IEnumerable values) {
+            foreach (T key in keys) {
+                foreach (U value in values) {
+                    yield return new KeyValuePair<T, U>(key, value);
+                }
+            }
+        }
+        public static Action<T, T[], int> set_array = (item, array, index) => {
+            Validate.NonNullArgument(array,"array");
+            Validate.PositiveArgument(index, "index");
+            if (index >= array.Length) throw new ArgumentOutOfRangeException("index");
+            array[index] = item;
+        };
+        public static Func<T[], int, T> get_array = (array, index) => {
+            Validate.NonNullArgument(array, "array");
+            Validate.PositiveArgument(index, "index");
+            if (index >= array.Length) throw new ArgumentOutOfRangeException("index");
+            return array[index];
+        };
+        public static IChain<T> Run(IChain<T> item, T t) {
+            Validate.NonNullArgument(item, ITEM);
+            return item.Run(t);
+        }
+        public static void AddNonNull(IList<T> lst, T t) {
+            Validate.NonNullArgument(lst, LST);
+            if (null != t) lst.Add(t);
+        }
+        public static void Add(IList<T> lst, T item) {
+            Validate.NonNullArgument(lst, LST);
+            Validate.NonNullArgument(item, ITEM);
+            lst.Add(item);
+        }
+        public static string toString(T item) {
+            Validate.NonNullArgument(item, ITEM);
+            return item.ToString();
+        }
+        public static IEnumerable<T> LoadTextFile(string filename, Encoding encoding, Func<string, T> fn) {
+            Validate.StringArgument(filename, FILENAME);
+            Validate.NonNullArgument(fn, FN);
+            using (TextReader sr = new StreamReader(filename, encoding)) {
+                string line = sr.ReadLine();
+                while (!String.IsNullOrEmpty(line)) {
+                    yield return fn(line);
+                    line = sr.ReadLine();
+                }
+            }
+        }
+        public static void StoreTextFile(string filename, Encoding encoding, IEnumerable<T> item, Func<T, string> fn) {
+            Validate.StringArgument(filename, FILENAME);
+            Validate.NonNullArgument(item, ITEM);
+            Validate.NonNullArgument(fn, FN);
+            using (TextWriter sw = new StreamWriter(filename, false, encoding)) {
+                F<string>.each(F<T>.map<string>(item, fn), (s) => sw.WriteLine(s));
+            }
+        }
+    }
+    public class Chain<T> : IChain<T> {
+        private Func<T, bool> fn = null;
+        private Chain(T t,Func<T, bool> predicate) {
+            this.Item = t;
+            this.fn = predicate;
+        }
+        public T Item { get; private set; }
+        public IChain<T> Run(T t) {
+            IChain<T> result = null;
+            if (this.fn(t)) result = this;
+            return result;
+        }
+        public static IChain<T> Create(T t, Func<T, bool> predicate) { return new Chain<T>(t, predicate); }
     }
     public class Listener<T, U> : IListener<T, U> {
-        private Func<T, U> fun;
-        public Listener(Func<T, U> fn) { this.fun = fn;  }
-        public U Handle(T m) { return this.fun(m); }
+        private const string FUN = "fun";
+        private Func<T, U> fn;
+        private Listener(Func<T, U> fun)
+        {
+            Validate.NonNullArgument(fun, FUN);
+            this.fn = fun;
+            this.Handle = (t)=>this.fn(t);
+        }
+        public Func<T,U> Handle { get; private set; }
+        public static IListener<T, U> Create(Func<T, U> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            return new Listener<T, U>(fun);
+        }
     }
     public class Default<T> : IDefault<T> where T : class {
-        public Default(T t) { this.d = t; }
+        private const string ITEM = "item";
+        public Default(T item) {
+            Validate.NonNullArgument(item, ITEM);
+            this.d = item;
+            this.orDefault = (x) =>  (null != x) ? x : this.d;
+        }
         private T d = null;
-        ///
-        /// Function that takes a potentially null object
-        ///
-        /// <returns>the original object, or the default object if the original object is null</returns>
-        public T orDefault(T t) {
-            if (null == this.d) throw new NullReferenceException("default value not set");
-            return (null != t) ? t : this.d;
-        }
+        /// Function that takes a potentially null object<returns>the original object, or the default object if the original object is null</returns>
+        public Func<T,T> orDefault { get; private set; }
     }

     public class Curry1<T, U> : ICurry1<T, U> {
+        private const string FUN = "fun";
         private Func<T, U> fn;
-        public Curry1(Func<T, U> fun) { this.fn = fun; }
-        ///
-        /// Creates a curry function object
-        ///
-        /// <returns>curry function object</returns>
-        public Func<T, U> Create() { return (x) => this.fn(x); }
+        public Curry1(Func<T, U> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.fn = fun;
+            this.Create = () => (x) => this.fn(x);
+        }
+        /// Creates a curry function object<returns>curry function object</returns>
+        public Func<Func<T, U>> Create { get; private set; }
     }
     public class Curry2<T, U> : ICurry2<T, U> {
+        private const string FUN = "fun";
         private Func<T, U, U> fn; // U fn(T t, U u)
-        public Curry2(Func<T, U, U> fun) { this.fn = fun; }
-        ///
-        /// Creates a curry function object
-        ///
-        /// <returns>curry function object</returns>
-        public Func Create(T t) { return (x) => this.fn(t, x); }
-    }
-
-
-    ///
-    /// A compare object requires by a sort function in the .NET framework
-    ///
-    /// <returns>System.Collections.Generic.Comparer<T></returns>
+        public Curry2(Func<T, U, U> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.fn = fun;
+            this.Create = (t) => (x) => this.fn(t, x);
+        }
+        /// Creates a curry function object<returns>curry function object</returns>
+        public Func<T,Func> Create { get; private set; }
+    }
+    public class Curry<T> : ICurry<T> { //TODO needs test coverage
+        private const string FUN = "fun";
+        private enum Which {
+            _fn_1_1,
+            _fn_2_1,
+            _fn_3_1,
+            _fn_4_1,
+            _fn_5_1,
+            _fn_6_1,
+            _fn_7_1
+        }
+        private Which which;
+
+        private Func<T,T> fn_1_1;
+        private Func<T,T,T> fn_2_1;
+        private Func<T,T,T,T> fn_3_1;
+        private Func<T,T,T,T,T> fn_4_1;
+        private Func<T,T,T,T,T,T> fn_5_1;
+        private Func<T,T,T,T,T,T,T> fn_6_1;
+        private Func<T, T,T,T,T,T,T,T> fn_7_1;
+        public Curry(Func<T,T> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.which = Which._fn_1_1;
+            this.fn_1_1 = fun;
+        }
+        public Curry(Func<T,T,T> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.which = Which._fn_2_1;
+            this.fn_2_1 = fun;
+        }
+        public Curry(Func<T,T,T,T> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.which = Which._fn_3_1;
+            this.fn_3_1 = fun;
+        }
+        public Curry(Func<T,T,T,T,T> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.which = Which._fn_4_1;
+            this.fn_4_1 = fun;
+        }
+        public Curry(Func<T,T,T,T,T,T> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.which = Which._fn_5_1;
+            this.fn_5_1 = fun;
+        }
+        public Curry(Func<T,T,T,T,T,T,T> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.which = Which._fn_6_1;
+            this.fn_6_1 = fun;
+        }
+        public Curry(Func<T,T,T,T,T,T,T,T> fun) {
+            Validate.NonNullArgument(fun, FUN);
+            this.which = Which._fn_7_1;
+            this.fn_7_1 = fun;
+        }
+        public Action<T> Create() {
+            if (this.which != Which._fn_1_1) throw new Exception("invalid");
+            return (t) => this.fn_1_1(t);
+        }
+        public Func<T,T> Create(T t1) {
+            if (this.which != Which._fn_2_1) throw new Exception("invalid");
+            return (t) => this.fn_2_1(t, t1);
+        }
+        public Func<T,T> Create(T t1, T t2) {
+            if (this.which != Which._fn_3_1) throw new Exception("invalid");
+            return (t) => this.fn_3_1(t, t1, t2);
+        }
+        public Func<T,T> Create(T t1, T t2, T t3) {
+            if (this.which != Which._fn_4_1) throw new Exception("invalid");
+            return (t) => this.fn_4_1(t, t1, t2, t3);
+        }
+        public Func<T, T> Create(T t1, T t2, T t3, T t4) {
+            if (this.which != Which._fn_5_1) throw new Exception("invalid");
+            return (t) => this.fn_5_1(t, t1, t2, t3, t4);
+        }
+        public Func<T, T> Create(T t1, T t2, T t3,T t4,T t5) {
+            if (this.which != Which._fn_6_1) throw new Exception("invalid");
+            return (t) => this.fn_6_1(t, t1, t2, t3,t4,t5);
+        }
+        public Func<T, T> Create(T t1, T t2, T t3,T t4,T t5,T t6) {
+            if (this.which != Which._fn_7_1) throw new Exception("invalid");
+            return (t) => this.fn_7_1(t, t1, t2, t3, t4, t5, t6);
+        }
+    }
+
+    /// A compare object requires by a sort function in the .NET framework<returns>System.Collections.Generic.Comparer<T></returns>
     public class Comparer<T> : System.Collections.Generic.Comparer<T> {
+        private const string X = "x";
+        private const string Y = "y";
+        private const string FN = "fn";
         private Func<T, T, int> compare;
-        public Comparer(Func<T, T, int> fn) { this.compare = fn; }
+        public Comparer(Func<T, T, int> fn) {
+            Validate.NonNullArgument(fn, FN);
+            this.compare = fn;
+        }
         public override int Compare(T x, T y) {
+            Validate.NonNullArgument(x, X);
+            Validate.NonNullArgument(y, Y);
             return this.compare.Invoke(x, y);
         }
     }
+    public static class Validate {
+        public static void NonNullArgument(object item, string name) { if (null == item) throw new ArgumentNullException(name); }
+        public static void PositiveArgument(int n, string name) { if (n < 0) throw new ArgumentOutOfRangeException(name); }
+        public static void PositiveArgument(float f,string name) { if (f<0.0f) throw new ArgumentOutOfRangeException(name); }
+        public static void PositiveArgument(double d,string name) { if (d<0.0d) throw new ArgumentOutOfRangeException(name); }
+        public static void StringArgument(string s, string name) { if (String.IsNullOrEmpty(s)) throw new ArgumentNullException(name); }
+    }
+    public static class Utility {
+        public static int char_to_digit(char c) {
+            int result = 0;
+            switch (c) {
+                case '0': result = 0; break;
+                case '1': result = 1; break;
+                case '2': result = 2; break;
+                case '3': result = 3; break;
+                case '4': result = 4; break;
+                case '5': result = 5; break;
+                case '6': result = 6; break;
+                case '7': result = 7; break;
+                case '8': result = 8; break;
+                case '9': result = 9; break;
+            }
+            return result;
+        }
+        public static char digit_to_char(int d) {
+            char result = '0';
+            switch (d) {
+                case 0: result = '0'; break;
+                case 1: result = '1'; break;
+                case 2: result = '2'; break;
+                case 3: result = '3'; break;
+                case 4: result = '4'; break;
+                case 5: result = '5'; break;
+                case 6: result = '6'; break;
+                case 7: result = '7'; break;
+                case 8: result = '8'; break;
+                case 9: result = '9'; break;
+            }
+            return result;
+        }
+    }
+    public class ServiceProvider : IServiceProvider {
+
+        private const string TYPE = "type";
+        private const string SERVICE = "service";
+        private readonly IDictionary<Type, object> services = new Dictionary<Type, object>();
+        public void AddService(Type type, object service) {
+            Validate.NonNullArgument(type, TYPE);
+            Validate.NonNullArgument(service, SERVICE);
+            if (!type.IsAssignableFrom(service.GetType())) throw new ArgumentException("the service is not the type");
+            // TODO: check for collision
+            this.services.Add(type, service);
+        }
+        public object GetService(Type type) {
+            Validate.NonNullArgument(type,TYPE);
+            return this.services[type]; // TODO verify that it's there first, throw if it isn't
+        }
+        public void RemoveService(Type type) {
+            Validate.NonNullArgument(type, TYPE);
+            this.services.Remove(type); // TODO verify that it's there first, throw if it isn't
+        }
+    }
+    public class Singleton<T> {
+        private static Singleton<T> instance;
+        private static Singleton<T> Instance {
+            get {
+                if (null == instance) instance = new Singleton<T>();
+                return instance;
+            }
+        }
+        private Singleton(){}
+    }
+
 }