context: using System.Web.Security;
  using N2.Collections;
  using N2.Edit;
  using N2.Engine;
  using N2.Security;
  using N2.Web;
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Security.Principal;
  using System.Diagnostics;
  using N2.Plugin;
  using System.IO;
  using N2.Web.Parts;
  using N2.Edit.Api;
  using N2.Edit.Versioning;
  
  namespace N2.Management.Api
  {
  	[DebuggerDisplay("Node: {Current}")]
  	public class Node<T>
  	{
  		public Node()
  		{
  			Children = new Node<T>[0];
  		}
  
  		public Node(T current)
  			: this()
  		{
  			Current = current;
  		}
  
  		public T Current { get; set; }
  
  		public IEnumerable<Node<T>> Children { get; set; }
  
  		public int Count
  		{
  			get { return Children != null ? Children.Count() : 0; }
  		}
  
  		public bool HasChildren { get; set; }
  
  		public bool Expanded { get; set; }
  	}
  
  	[DebuggerDisplay("InterfaceMenuItem: {Name}")]
  	public class InterfaceMenuItem
  	{
  		public InterfaceMenuItem()
  		{
  			Target = Targets.Preview;
  			RequiredPermission = Permission.Read;
  		}
  
  		public string Title { get; set; }
  
  		public string Url { get; set; }
  
  		public string Target { get; set; }
  
  		public string IconClass { get; set; }
  
  		public string Description { get; set; }
  
  		public string ToolTip { get; set; }
  
  		public string IconUrl { get; set; }
  
  		public string Name { get; set; }
  
  		public bool IsDivider { get; set; }
  
  		public string TemplateUrl { get; set; }
  
  		public Permission RequiredPermission { get; set; }
  
  		public string HiddenBy { get; set; }
  
  		public string DisplayedBy { get; set; }
  
  		public string SelectedBy { get; set; }
  
  		public string Alignment { get; set; }
  
  		public string ClientAction { get; set; }
  
  		public bool Divider { get; set; }
  
  		public static implicit operator Node<InterfaceMenuItem>(InterfaceMenuItem item)
  		{
  			return new Node<InterfaceMenuItem>(item);
  		}
  
  		public override string ToString()
  		{
  			return "InterfaceMenuItem " + Name;
  		}
  	}
  
  	public class InterfaceDefinition
  	{
  		public Node<InterfaceMenuItem> MainMenu { get; set; }
  
  		public Node<InterfaceMenuItem> ActionMenu { get; set; }
  
  		public Node<TreeNode> Content { get; set; }
  
  		public Site Site { get; set; }
  
  		public string Authority { get; set; }
  
  		public ProfileUser User { get; set; }
  
  		public InterfacePaths Paths { get; set; }
  
  		public Node<InterfaceMenuItem> ContextMenu { get; set; }
  
  		public InterfacePartials Partials { get; set; }
  	}
  
  	public class ControlPanelDefinition
  	{
  		public TreeNode CurrentItem { get; set; }
  		public Node<InterfaceMenuItem> Menu { get; set; }
  		public InterfacePaths Paths { get; set; }
  		public ActivityTrackingConfiguration ActivityTracking { get; set; }
  		public List<TemplateInfo> Templates { get; internal set; }
  		public DraftInfo Draft { get; internal set; }
  		public string[] Dependencies { get; internal set; }
  	}
  	public class ActivityTrackingConfiguration
  	{
  		public int Interval { get; internal set; }
  		public string Path { get; internal set; }
  	}
  	public class InterfacePaths
  	{
  		public string Management { get; set; }
  
  		public string Create { get; set; }
  
  		public string Delete { get; set; }
  
  		public string Edit { get; set; }
  
  		public string SelectedQueryKey { get; set; }
  
  		public string ItemQueryKey { get; set; }
  
  		public string PreviewUrl { get; set; }
  
  		public string PageQueryKey { get; set; }
  	}
  
  	public class InterfacePartials
  	{
  		public string Management { get; set; }
  
  		public string Menu { get; set; }
  
  		public string Preview { get; set; }
  
  		public string Main { get; set; }
  
  		public string Tree { get; set; }
  
  		public string Footer { get; set; }
  
  		public string ContextMenu { get; set; }
  	}
  
  	public class InterfaceBuiltEventArgs : InterfaceventArgs<InterfaceDefinition>
  	{
  	}
  
  	public class InterfaceventArgs<T> : EventArgs
  	{
  		public T Data { get; internal set; }
  	}
  
  	[Service]
  	public class InterfaceBuilder
  	{
  		private readonly IEngine engine;
  
  		public InterfaceBuilder(IEngine engine)
  		{
  			this.engine = engine;
  		}
  
  		public event EventHandler<InterfaceBuiltEventArgs> InterfaceBuilt;
  
  		public event EventHandler<InterfaceventArgs<ControlPanelDefinition>> ControlPanelBuilt;
  
  		public virtual InterfaceDefinition GetInterfaceDefinition(HttpContextBase context, SelectionUtility selection)
  		{
  			var profile = GetUser(context);
  			var selectedItem = GetSelectedItem(selection, profile);
  
  			var data = new InterfaceDefinition
  			{
  				MainMenu = GetMainMenu(),
  				ActionMenu = GetActionMenu(context),
  				ContextMenu = GetContextMenu(context),
  				Content = GetContent(context, selection, selectedItem),
  				Site = engine.Host.GetSite(selectedItem),
  				Authority = context.Request.Url.Authority,
  				User = profile,
  				Paths = GetUrls(context, selectedItem),
  				Partials = GetPartials(context)
  			};
  
  			PostProcess(data);
  
  			if (InterfaceBuilt != null)
  				InterfaceBuilt(this, new InterfaceBuiltEventArgs { Data = data });
  
  			return data;
  		}
  
  		public virtual ControlPanelDefinition GetControlPanelDefinition(HttpContextBase context, ContentItem item)
  		{
  			var state = Web.UI.WebControls.ControlPanel.GetState(engine);
  			var templates = new List<TemplateInfo>();
  			if (state.IsFlagSet(Web.UI.WebControls.ControlPanelState.DragDrop))
  			{
  				var a = engine.ResolveAdapter<PartsAdapter>(item);
  				foreach (var d in Web.UI.WebControls.ControlPanel.GetPartDefinitions(a, item, null, context.User))
  				{
  					foreach (var t in a.GetTemplates(item, d))
  					{
  						templates.Add(new TemplateInfo(t) { EditUrl = engine.ManagementPaths.GetEditNewPageUrl(item, t.Definition) });
  					}
  				}
  			}
  
  			var angularRoot = engine.Config.Sections.Web.PreviewResources.AngularJsRoot;
  			var data = new ControlPanelDefinition
  			{
  				Menu = GetControlPanelMenu(context, item),
  				Paths = GetUrls(context, item),
  				CurrentItem = engine.GetContentAdapter<NodeAdapter>(item).GetTreeNode(item),
  				ActivityTracking = new ActivityTrackingConfiguration
  				{
  					Interval = engine.Config.Sections.Management.Collaboration.PingInterval,
  					Path = engine.Config.Sections.Management.Collaboration.ActivityTrackingEnabled ? engine.Config.Sections.Management.Collaboration.PingPath.ResolveUrlTokens() : null
  				},
  				Templates = templates,
  				Draft = engine.Resolve<DraftRepository>().GetDraftInfo(item),
  				Dependencies = 
  				(string.IsNullOrEmpty(angularRoot) ? new string[0] : new[] { angularRoot + "angular.js", angularRoot + "angular-resource.js" })
  				.Concat(new[]
  				{
  					"{ManagementUrl}/App/i18n/en.js.ashx",
  					"{ManagementUrl}/App/Js/Directives.js",
  					"{ManagementUrl}/App/Js/Services.js",
  					"{ManagementUrl}/App/Preview/Preview.js"
  				}).Select(p => p.ResolveUrlTokens()).ToArray()
  			};
  
  			PostProcess(data);
  
  			if (ControlPanelBuilt != null)
  				ControlPanelBuilt(this, new InterfaceventArgs<ControlPanelDefinition> { Data = data });
  
  			return data;
  		}
  
  		private Node<InterfaceMenuItem> GetControlPanelMenu(HttpContextBase context, ContentItem item)
  		{
  
gt: 			var state = N2.Web.UI.WebControls.ControlPanel.GetState(engine);