+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using Pithos.Client.WPF.SelectiveSynch;
+using Pithos.Interfaces;
+
+namespace Pithos.Client.WPF.Utils
+{
+ public static class EnumerableExtensions
+ {
+ public static IEnumerable<T> Slice<T>(this IEnumerable<T> collection, int start, int end)
+ {
+ int index = 0;
+ int count = 0;
+
+ if (collection == null)
+ throw new ArgumentNullException("collection");
+
+ // Optimise item count for ICollection interfaces.
+ if (collection is ICollection<T>)
+ count = ((ICollection<T>)collection).Count;
+ else if (collection is ICollection)
+ count = ((ICollection)collection).Count;
+ else
+ {
+ count = collection.Count();
+ }
+
+ // Get start/end indexes, negative numbers start at the end of the collection.
+ if (start < 0)
+ start += count;
+
+ if (end < 0)
+ end += count;
+
+ foreach (var item in collection)
+ {
+ if (index >= end)
+ yield break;
+
+ if (index >= start)
+ yield return item;
+
+ ++index;
+ }
+ }
+
+ public static IEnumerable<Node<T>> ToTree<TSource,T>(this IEnumerable<TSource> enumerable,Func<TSource,string> pathFunc,Func<TSource,T> valueFunc,string delimiter="/")
+ {
+ var orderedItems=enumerable.OrderBy(pathFunc);
+ var lookups = new Dictionary<string,Node<T>>();
+ var nodes = new List<Node<T>>();
+ foreach (var item in orderedItems)
+ {
+ var path = pathFunc(item);
+ var value = valueFunc(item);
+ var newNode = new Node<T> { Path = path,Data=value };
+ lookups[path] = newNode;
+
+ var lastIndex = path.LastIndexOf(delimiter, StringComparison.Ordinal);
+ var upTo = lastIndex < 0 ? path.Length - 1 : lastIndex;
+ var parentPath = path.Substring(0, upTo);
+
+ Node<T> parent;
+ if (lookups.TryGetValue(parentPath, out parent))
+ {
+ parent.Children.Add(newNode);
+ parent.Children.Sort((x,y)=>String.CompareOrdinal(x.Path, y.Path));
+ }
+ else
+ nodes.Add(newNode);
+
+ }
+ return nodes;
+ }
+
+ public static List<DirectoryRecord> ToTree(this IEnumerable<ObjectInfo> enumerable)
+ {
+ var orderedItems=enumerable.OrderBy(o=>o.Uri.ToString());
+ var lookups = new Dictionary<string,DirectoryRecord>();
+ var nodes = new List<DirectoryRecord>();
+ foreach (var item in orderedItems)
+ {
+ var path = item.Uri.ToString();
+ var newNode = new DirectoryRecord{ DisplayName=item.Name,ObjectInfo=item};
+ lookups[path] = newNode;
+
+ var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal);
+ var upTo = lastIndex < 0 ? path.Length - 1 : lastIndex;
+ var parentPath = path.Substring(0, upTo);
+
+ DirectoryRecord parent;
+ if (lookups.TryGetValue(parentPath, out parent))
+ {
+ parent.Directories.Add(newNode);
+ parent.Directories.Sort((x,y)=>String.CompareOrdinal(x.Uri.ToString(), y.Uri.ToString()));
+ }
+ else
+ nodes.Add(newNode);
+
+ }
+ return nodes;
+ }
+ }
+}