context: /******************************************************************************
  *
  * Copyright Saab AB, 2005-2013 (http://safirsdkcore.com)
  *
  * Created by: Joel Ottosson / stjoot
  *
  *******************************************************************************
  *
  * This file is part of Safir SDK Core.
  *
  * Safir SDK Core is free software: you can redistribute it and/or modify
  * it under the terms of version 3 of the GNU General Public License as
  * published by the Free Software Foundation.
  *
  * Safir SDK Core is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with Safir SDK Core.  If not, see <http://www.gnu.org/licenses/>.
  *
  ******************************************************************************/
  
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Diagnostics;
  using System.Drawing;
  using System.IO;
  using System.Windows.Forms;
  using Safir.Dob;
  using Safir.Dob.Typesystem;
  using Safir.Dob.Typesystem.Internal;
  using Exception = System.Exception;
  using Message = Safir.Dob.Message;
  using Object = Safir.Dob.Typesystem.Object;
  
  namespace Sate
  {
      /// <summary>
      ///     Summary description for ClassViewPanel.
      /// </summary>
      public class ExplorerPanel : Panel
      {
          private static TreeViewImageHandler _imageHandler;
  
          private static ExplorerPanel _instance;
          private readonly MenuItem _changeImageMenuItem;
  
          // context menus
          private readonly MenuItem _deleteRequestMenuItem;
          private readonly MenuItem _dobUnitInfoMenuItem;
          private readonly MenuItem _iterateClassMenuItem;
          private readonly MenuItem _openMenuItem;
          private readonly MenuItem _registerMenuItem;
          private readonly MenuItem _registerOptionsMenuItem;
          private readonly MenuItem _separator1MenuItem;
          private readonly MenuItem _separator2MenuItem;
          private readonly MenuItem _separator3MenuItem;
          private readonly MenuItem _subscribeMenuItem;
          private readonly MenuItem _subscribeOptionsMenuItem;
          private readonly MenuItem _subscribeRegistrationMenuItem;
          private readonly MenuItem _subscribeRegistrationOptionsMenuItem;
          private readonly TabControl _tabControl = new TabControl();
          private readonly TabPage _tabInheritance = new TabPage("Inheritance");
          private readonly TabPage _tabNamespace = new TabPage("Namespace");
          private readonly TreeView _treeViewClassHierarchy;
          private readonly TreeView _treeViewNsHierarchy;
          private readonly MenuItem _unregisterMenuItem;
          private readonly MenuItem _unsubscribeMenuItem;
          private readonly MenuItem _unsubscribeRegistrationMenuItem;
          private readonly MenuItem _viewDouFileMenuItem;
          private readonly MenuItem _openInExternalMenuItem;
          private Hashtable _clTypeIdHt;
          private IContainer components;
          private ImageList _defaultImagesList;
          private Hashtable _dobTypeHt;
          private Panel _fillpanel;
          private ImageList _imageList;
          private Hashtable _nsHt;
          private Hashtable _nsTypeIdHt;
          private Panel _toppanel;
  
  
          private ExplorerPanel()
          {
              //
              // Required for Windows Form Designer support
              //
              InitializeComponent();
  
              SuspendLayout();
  
              //Load images for the treeview
              _imageHandler = new TreeViewImageHandler(_imageList, _defaultImagesList);
              _imageHandler.RefreshImageCollection();
  
              //context menu setup
              _openMenuItem = new MenuItem("Open");
              _registerMenuItem = new MenuItem("Register handler");
              _registerOptionsMenuItem = new MenuItem("Register handler with options...");
              _unregisterMenuItem = new MenuItem("Unregister handler");
              _separator1MenuItem = new MenuItem("-");
              _subscribeMenuItem = new MenuItem("Subscribe");
              _subscribeOptionsMenuItem = new MenuItem("Subscribe with options...");
              _unsubscribeMenuItem = new MenuItem("Unsubscribe");
              _subscribeRegistrationMenuItem = new MenuItem("Subscribe for registrations");
              _subscribeRegistrationOptionsMenuItem = new MenuItem("Subscribe for registrations with options...");
              _unsubscribeRegistrationMenuItem = new MenuItem("Unsubscribe registrations");
              _separator2MenuItem = new MenuItem("-");
              _deleteRequestMenuItem = new MenuItem("Send delete request");
              _separator3MenuItem = new MenuItem("-");
              _iterateClassMenuItem = new MenuItem("Iterate class...");
              _changeImageMenuItem = new MenuItem("Change image...");
              _dobUnitInfoMenuItem = new MenuItem("View details...");
              _viewDouFileMenuItem = new MenuItem("View dou-file...");
  
              _openInExternalMenuItem = new MenuItem("Open in external program");
              UpdateExternalProgramsSubmenu();
              _openMenuItem.Click += openMenuItem_Click;
  
              _registerMenuItem.Click += registerMenuItem_Click;
              _registerOptionsMenuItem.Click += registerOptionsMenuItem_Click;
              _unregisterMenuItem.Click += unregisterMenuItem_Click;
  
              _subscribeMenuItem.Click += subscribeMenuItem_Click;
              _subscribeOptionsMenuItem.Click += subscribeOptionsMenuItem_Click;
              _unsubscribeMenuItem.Click += unsubscribeMenuItem_Click;
  
              _subscribeRegistrationMenuItem.Click += subscribeRegistrationMenuItem_Click;
              _subscribeRegistrationOptionsMenuItem.Click += subscribeRegistrationOptionsMenuItem_Click;
              _unsubscribeRegistrationMenuItem.Click += unsubscribeRegistrationMenuItem_Click;
  
              _deleteRequestMenuItem.Click += deleteRequestMenuItem_Click;
  
              _iterateClassMenuItem.Click += iterateClassMenuItem_Click;
  
              _changeImageMenuItem.Click += changeImageMenuItem_Click;
              _dobUnitInfoMenuItem.Click += dobUnitInfoMenuItem_Click;
              _viewDouFileMenuItem.Click += viewDouFileMenuItem_Click;
  
              var contextMenu = new ContextMenu(new[]
              {
                  _openMenuItem,
                  _registerMenuItem,
                  _registerOptionsMenuItem,
                  _unregisterMenuItem,
                  _separator1MenuItem,
                  _subscribeMenuItem,
                  _subscribeOptionsMenuItem,
                  _unsubscribeMenuItem,
                  _subscribeRegistrationMenuItem,
                  _subscribeRegistrationOptionsMenuItem,
                  _unsubscribeRegistrationMenuItem,
                  _separator2MenuItem,
                  _deleteRequestMenuItem,
                  _separator3MenuItem,
                  _iterateClassMenuItem,
                  _dobUnitInfoMenuItem,
                  _viewDouFileMenuItem,
                  _openInExternalMenuItem,
                  _changeImageMenuItem
              });
  
              contextMenu.Popup += contextMenu_Popup;
  
              //treeViewClassHierarchy
              _treeViewClassHierarchy = new TreeView();
              _treeViewClassHierarchy.ContextMenu = contextMenu;
              _treeViewClassHierarchy.Location = new Point(0, 40);
              _treeViewClassHierarchy.Dock = DockStyle.Fill;
              _treeViewClassHierarchy.ImageList = _imageList;
  
              _treeViewClassHierarchy.DoubleClick += treeViewClassHierarchy_DoubleClick;
              _treeViewClassHierarchy.MouseDown += treeViewClassHierarchy_MouseDown;
              _treeViewClassHierarchy.ItemDrag += treeViewClassHierarchy_ItemDrag;
              _treeViewClassHierarchy.TreeViewNodeSorter = new TreeSorter();
  
              //treeViewNsHierarchy
              _treeViewNsHierarchy = new TreeView();
              _treeViewNsHierarchy.ContextMenu = contextMenu;
              _treeViewNsHierarchy.Location = new Point(0, 40);
              _treeViewNsHierarchy.Dock = DockStyle.Fill;
              _treeViewNsHierarchy.ImageList = _imageList;
              _treeViewNsHierarchy.DoubleClick += treeViewNsHierarchy_DoubleClick;
              _treeViewNsHierarchy.MouseDown += treeViewNsHierarchy_MouseDown;
              _treeViewNsHierarchy.ItemDrag += treeViewNsHierarchy_ItemDrag;
              _treeViewNsHierarchy.TreeViewNodeSorter = new TreeSorter();
  
              //Tabs
              _tabControl.Dock = DockStyle.Fill;
              _tabInheritance.Controls.Add(_treeViewClassHierarchy);
              _tabNamespace.Controls.Add(_treeViewNsHierarchy);
              _fillpanel.Controls.Add(_tabControl);
              _tabControl.TabPages.AddRange(new[] { _tabInheritance, _tabNamespace });
              if (Settings.Sate.DefaultExplorerView)
                  _tabControl.SelectedIndex = 0;
              else
                  _tabControl.SelectedIndex = 1;
              _tabControl.SelectedIndex = 0;
  
              //TitleBar
              var titleLabel = new PanelLabelControl("Explorer");
              titleLabel.CloseEvent += titleLabel_CloseEvent;
              titleLabel.Height = 15;
              titleLabel.Dock = DockStyle.Top;
              _toppanel.Controls.Add(titleLabel);
  
              ResumeLayout(false);
          }
          
  
          public static ExplorerPanel Instance
          {
              get
              {
                  if (_instance == null)
                      _instance = new ExplorerPanel();
                  return _instance;
              }
          }
  
  
          private void dobUnitInfoMenuItem_Click(object sender, EventArgs e)
          {
              var node = (DobUnit) GetSelectedNode();
              var detailsForm = new DobUnitDetailsForm(node.TypeId); //, node.InstanceId);
              detailsForm.ShowDialog();
          }
  
          private void changeImageMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
  
              string mappingName;
  
              if (node is DobUnit)
              {
                  var du = node as DobUnit;
                  var tid = du.TypeId;
                  mappingName = tid.ToString();
              }
              else if (node is NamespaceNode)
              {
                  var nn = node as NamespaceNode;
                  mappingName = nn.FullName;
              }
              else
              {
                  return;
              }
  
              var customImageForm = new CustomImageForm(_imageHandler, mappingName);
              customImageForm.ShowDialog();
              if (customImageForm.IsDirty)
              {
                  UpdateAllImageIndices();
              }
          }
  
          private void UpdateAllImageIndices()
          {
              _imageHandler.RefreshImageCollection();
  
              //always go through every node is not the most efficient way but it's a simple
              //way to get correct image indices.
              foreach (DictionaryEntry de in _clTypeIdHt)
              {
                  var tmp = de.Value as DobUnit;
                  tmp.ImageIndex = _imageHandler.GetImageIndex(tmp.TypeId, tmp.ImageType);
                  tmp.SelectedImageIndex = tmp.ImageIndex;
              }
  
              foreach (DictionaryEntry de in _nsTypeIdHt)
              {
                  var tmp = de.Value as DobUnit;
                  tmp.ImageIndex = _imageHandler.GetImageIndex(tmp.TypeId, tmp.ImageType);
                  tmp.SelectedImageIndex = tmp.ImageIndex;
              }
          }
  
          private void treeViewNsHierarchy_ItemDrag(object sender, ItemDragEventArgs e)
          {
              var n = (DobUnit) e.Item;
              DoDragDrop(n.TypeId, DragDropEffects.Move);
          }
  
          private void treeViewClassHierarchy_ItemDrag(object sender, ItemDragEventArgs e)
          {
              var n = (DobUnit) e.Item;
              DoDragDrop(n.TypeId, DragDropEffects.Move);
          }
  
          private void titleLabel_CloseEvent(object sender, EventArgs e)
          {
              MainForm.Instance.ShowHideExplorer(false);
          }
  
          /// <summary>
          ///     Clean up any resources being used.
          /// </summary>
          protected override void Dispose(bool disposing)
          {
              if (disposing && components != null)
              {
                  components.Dispose();
              }
              base.Dispose(disposing);
          }
  
          #region Windows Form Designer generated code
  
          /// <summary>
          ///     Required method for Designer support - do not modify
          ///     the contents of this method with the code editor.
          /// </summary>
          private void InitializeComponent()
          {
              this.components = new System.ComponentModel.Container();
              var resources = new System.ComponentModel.ComponentResourceManager(typeof(ExplorerPanel));
              this._imageList = new System.Windows.Forms.ImageList(this.components);
              this._toppanel = new System.Windows.Forms.Panel();
              this._fillpanel = new System.Windows.Forms.Panel();
              this._defaultImagesList = new System.Windows.Forms.ImageList(this.components);
              this.SuspendLayout();
              //
              // imageList
              //
              this._imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
              this._imageList.ImageSize = new System.Drawing.Size(16, 16);
              this._imageList.TransparentColor = System.Drawing.Color.Transparent;
              //
              // toppanel
              //
              this._toppanel.BackColor = System.Drawing.SystemColors.ActiveCaption;
              this._toppanel.Dock = System.Windows.Forms.DockStyle.Top;
              this._toppanel.Location = new System.Drawing.Point(0, 0);
              this._toppanel.Name = "_toppanel";
              this._toppanel.Size = new System.Drawing.Size(224, 15);
              this._toppanel.TabIndex = 0;
              //
              // fillpanel
              //
              this._fillpanel.BackColor = System.Drawing.SystemColors.Control;
              this._fillpanel.Dock = System.Windows.Forms.DockStyle.Fill;
              this._fillpanel.ForeColor = System.Drawing.SystemColors.Control;
              this._fillpanel.Location = new System.Drawing.Point(0, 0);
              this._fillpanel.Name = "_fillpanel";
              this._fillpanel.Padding = new System.Windows.Forms.Padding(0, 20, 0, 0);
              this._fillpanel.Size = new System.Drawing.Size(224, 504);
              this._fillpanel.TabIndex = 0;
              //
              // defaultImagesList
              //
              this._defaultImagesList.ImageStream =
                  ((System.Windows.Forms.ImageListStreamer) (resources.GetObject("_defaultImagesList.ImageStream")));
              this._defaultImagesList.TransparentColor = System.Drawing.Color.Transparent;
              this._defaultImagesList.Images.SetKeyName(0, "package.bmp");
              this._defaultImagesList.Images.SetKeyName(1, "entity_default.bmp");
              this._defaultImagesList.Images.SetKeyName(2, "service_default.bmp");
              this._defaultImagesList.Images.SetKeyName(3, "object_default.bmp");
              this._defaultImagesList.Images.SetKeyName(4, "message_default.bmp");
              this._defaultImagesList.Images.SetKeyName(5, "response.bmp");
              this._defaultImagesList.Images.SetKeyName(6, "item.bmp");
              this._defaultImagesList.Images.SetKeyName(7, "struct.bmp");
              this._defaultImagesList.Images.SetKeyName(8, "parameters.bmp");
              this._defaultImagesList.Images.SetKeyName(9, "class_default.bmp");
              //
              // ExplorerPanel
              //
              this.Controls.Add(this._toppanel);
              this.Controls.Add(this._fillpanel);
              this.Size = new System.Drawing.Size(224, 504);
              this.Text = "Class Explorer";
              this.ResumeLayout(false);
          }
  
          #endregion
  
          public void LoadClassHierarchy()
          {
              _treeViewClassHierarchy.BeginUpdate();
              _treeViewNsHierarchy.BeginUpdate();
  
              _treeViewClassHierarchy.Nodes.Clear();
              _treeViewNsHierarchy.Nodes.Clear();
  
              var objType = typeof(Object);
              var objNode = new ClassNode(objType, Object.ClassTypeId, true);
              objNode.Expand();
              _dobTypeHt = new Hashtable();
              _dobTypeHt[objType] = objNode;
              _clTypeIdHt = new Hashtable();
              _clTypeIdHt[GetTypeId(objType)] = objNode;
              _nsTypeIdHt = new Hashtable();
              _nsHt = new Hashtable();
  
              InsertClassInNsHierarchy(objType, Object.ClassTypeId);
              foreach (var tid in Operations.GetAllTypeIds())
              {
                  if (!Operations.IsClass(tid))
                  {
                      continue;
                  }
  
                  Type type;
                  try
                  {
                      type = MainForm.Instance.GetType(tid);
                  }
                  catch (Safir.Dob.Typesystem.IllegalValueException)
                  {
                      /* this is to handle the case where a type is in dots_kernel, but has
                         not been built. I.e. a parameter class */
                      continue;
                  }
                  if (type.IsSubclassOf(objType))
                  {
                      ClassNode node = null;
                      while (type != objType && _dobTypeHt[type] == null)
                      {
                          var typeId = GetTypeId(type);
                          if (node == null)
                          {
                              node = new ClassNode(type, typeId, true);
                          }
                          else
                          {
                              var child = node;
                              node = new ClassNode(type, typeId, true);
                              node.Nodes.Add(child);
                          }
  
                          InsertClassInNsHierarchy(type, typeId);
  
                          _clTypeIdHt[typeId] = node;
                          _dobTypeHt[type] = node;
                          type = type.BaseType;
                      }
  
                      if (node != null)
                      {
                          ((ClassNode) _dobTypeHt[node.DobType.BaseType]).Nodes.Add(node);
                      }
                  }
              }
  
              _treeViewClassHierarchy.Nodes.Add(objNode);
  
              _treeViewClassHierarchy.Sort();
              _treeViewNsHierarchy.Sort();
  
              _treeViewNsHierarchy.EndUpdate();
              _treeViewClassHierarchy.EndUpdate();
              _treeViewNsHierarchy.HideSelection = false;
              _treeViewClassHierarchy.HideSelection = false;
          }
  
          private void InsertNamespace(Type type)
          {
              NamespaceNode node = null;
              var ns = type.Namespace.Split('.');
              var rest = type.Namespace + ".";
              for (var i = ns.Length - 1; i >= 0; i--)
              {
                  rest = rest.Substring(0, rest.LastIndexOf('.'));
                  if (_nsHt[rest] == null)
                  {
                      if (node == null)
                      {
                          node = new NamespaceNode(ns[i], type.Namespace);
                      }
                      else
                      {
                          var child = node;
                          node = new NamespaceNode(ns[i], type.Namespace);
                          node.Nodes.Add(child);
                      }
                      _nsHt[rest] = node;
                  }
                  else
                  {
                      if (node != null)
                      {
                          var parent = (NamespaceNode) _nsHt[rest];
  
                          var inserted = false;
                          for (var nix = 0; nix < parent.Nodes.Count; nix++)
                          {
                              if (!(parent.Nodes[nix] is NamespaceNode))
                              {
                                  parent.Nodes.Insert(nix, node);
                                  inserted = true;
                                  break;
                              }
                          }
  
                          if (!inserted)
                              parent.Nodes.Add(node);
                      }
                      return;
                  }
              }
              _nsHt[rest] = node;
              _treeViewNsHierarchy.Nodes.Add(node);
          }
  
          private void InsertClassInNsHierarchy(Type type, long typeId)
          {
              InsertNamespace(type);
              var classNode = new ClassNode(type, typeId, false);
              _nsTypeIdHt[typeId] = classNode;
              ((NamespaceNode) _nsHt[type.Namespace]).Nodes.Add(classNode);
          }
  
          private void treeViewClassHierarchy_MouseDown(object sender, MouseEventArgs e)
          {
              if (e.Button == MouseButtons.Right)
              {
                  var clickedNode = _treeViewClassHierarchy.GetNodeAt(e.X, e.Y);
                  if (clickedNode != null)
                  {
                      _treeViewClassHierarchy.SelectedNode = clickedNode;
                  }
              }
          }
  
  
          private void treeViewClassHierarchy_DoubleClick(object sender, EventArgs e)
          {
              Cursor = Cursors.WaitCursor;
              if (_treeViewClassHierarchy.SelectedNode is ObjectNode)
              {
                  var n = (ObjectNode) _treeViewClassHierarchy.SelectedNode;
  
                  try
                  {
                      using (var entityProxy = MainForm.Instance.Dose.Read(n.EntityId))
                      {
                          var entityInfo = new EntityInfo();
                          entityInfo.Obj = entityProxy.Entity;
                          entityInfo.SetInstanceId(entityProxy.InstanceId);
                          entityInfo.setHandlerId(entityProxy.OwnerWithStringRepresentation);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(entityInfo));
                      }
                  }
                  catch
                  {
                  }
              }
              else if (_treeViewClassHierarchy.SelectedNode is ClassNode)
              {
                  var n = (ClassNode) _treeViewClassHierarchy.SelectedNode;
                  var objInfo = new ObjectInfo();
                  if (n == _treeViewClassHierarchy.Nodes[0]) //root node is object
                  {
                      objInfo.Obj = new Object();
                  }
                  else
                  {
                      var dobType = MainForm.Instance.GetType(n.TypeId);
  
                      if (dobType.IsSubclassOf(typeof(Message)))
                      {
                          var msgInfo = new MessageInfo();
  
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          msgInfo.Obj = (Object) constr.Invoke(null);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(msgInfo));
                      }
                      else if (dobType.IsSubclassOf(typeof(Service)))
                      {
                          var srvInfo = new ServiceHandlerInfo();
  
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          srvInfo.Obj = (Object) constr.Invoke(null);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(srvInfo));
                      }
                      else if (dobType.IsSubclassOf(typeof(Entity)))
                      {
                          var entityInfo = new EntityInfo();
  
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          entityInfo.Obj = (Object) constr.Invoke(null);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(entityInfo));
                      }
                      else
                      {
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          objInfo.Obj = (Object) constr.Invoke(null);
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(objInfo));
                      }
                  }
              }
  
              Cursor = Cursors.Default;
          }
  
          private void treeViewNsHierarchy_MouseDown(object sender, MouseEventArgs e)
          {
              if (e.Button == MouseButtons.Right)
              {
                  var clickedNode = _treeViewNsHierarchy.GetNodeAt(e.X, e.Y);
                  if (clickedNode != null)
                  {
                      _treeViewNsHierarchy.SelectedNode = clickedNode;
                  }
              }
          }
  
          private void treeViewNsHierarchy_DoubleClick(object sender, EventArgs e)
          {
              Cursor = Cursors.WaitCursor;
              if (_treeViewNsHierarchy.SelectedNode is ObjectNode)
              {
                  var n = (ObjectNode) _treeViewNsHierarchy.SelectedNode;
  
                  try
                  {
                      var entityInfo = new EntityInfo();
                      using (var entityProxy = MainForm.Instance.Dose.Read(n.EntityId))
                      {
                          entityInfo.Obj = entityProxy.Entity;
                          entityInfo.SetInstanceId(entityProxy.InstanceId);
                          entityInfo.setHandlerId(entityProxy.OwnerWithStringRepresentation);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(entityInfo));
                      }
                  }
                  catch
                  {
                  }
              }
              else if (_treeViewNsHierarchy.SelectedNode is ClassNode)
              {
                  var n = (ClassNode) _treeViewNsHierarchy.SelectedNode;
                  var objInfo = new ObjectInfo();
  
                  if (n == _treeViewNsHierarchy.Nodes[0])
                  {
                      objInfo.Obj = new Object();
                  }
                  else
                  {
                      var dobType = MainForm.Instance.GetType(n.TypeId);
  
                      if (dobType.IsSubclassOf(typeof(Message)))
                      {
                          var msgInfo = new MessageInfo();
  
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          msgInfo.Obj = (Object) constr.Invoke(null);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(msgInfo));
                      }
                      else if (dobType.IsSubclassOf(typeof(Service)))
                      {
                          var srvInfo = new ServiceHandlerInfo();
  
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          srvInfo.Obj = (Object) constr.Invoke(null);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(srvInfo));
                      }
                      else if (dobType.IsSubclassOf(typeof(Entity)))
                      {
                          var entityInfo = new EntityInfo();
  
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          entityInfo.Obj = (Object) constr.Invoke(null);
  
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(entityInfo));
                      }
                      else
                      {
                          var constr = dobType.GetConstructor(Type.EmptyTypes);
                          objInfo.Obj = (Object) constr.Invoke(null);
                          MainForm.Instance.AddTabPage(new ObjectEditTabPage(objInfo));
                      }
                  }
              }
              Cursor = Cursors.Default;
          }
  
          private long GetTypeId(Type type)
          {
              return (long) type.GetField("ClassTypeId").GetValue(null);
          }
  
          private void subscribeOptionsMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
              long typeId;
              if (node is DobUnit)
              {
                  typeId = ((DobUnit) node).TypeId;
  
                  if (Operations.IsOfType(typeId, Entity.ClassTypeId))
                  {
                      var sf = new SubscribeForm(typeId);
                      sf.InitEntitySubForm();
                      if (sf.ShowDialog() == DialogResult.OK)
                      {
                          if (sf.AllInstancesSub)
                          {
                              var subInfo = new SubInfo(typeId, null, null, sf.DataUpdSub, sf.SubClassesSub, sf.RestartSub);
                              SubscribeEntity(subInfo);
  
                              if (sf.PermanentSub)
                              {
                                  //Subscriptions
                                  Settings.Sate.AddSubscription(subInfo);
                                  Settings.Save();
                              }
                          }
                          else
                          {
                              var entityId = new EntityId(((DobUnit) node).TypeId, sf.Instance);
                              var subInfo = new SubInfo(0, new EntityIdSerializeable(entityId), null, sf.DataUpdSub,
                                  sf.SubClassesSub, sf.RestartSub);
                              SubscribeEntity(subInfo);
  
                              if (sf.PermanentSub)
                              {
                                  //Subscriptions
                                  Settings.Sate.AddSubscription(subInfo);
                                  Settings.Save();
                              }
                          }
                      }
                  }
                  else if (Operations.IsOfType(typeId, Message.ClassTypeId))
                  {
                      var smf = new SubscribeMessageForm(typeId);
                      smf.InitMessageSubForm();
  
                      if (smf.ShowDialog() == DialogResult.OK)
                      {
                          ChannelId channelId;
  
                          if (smf.AllChannels)
                          {
                              channelId = ChannelId.ALL_CHANNELS;
                          }
                          else
                          {
                              /* try to parse as an long. O/w use the string representation */
                              try
                              {
                                  var val = long.Parse(smf.ChannelTextBox);
                                  channelId = new ChannelId(val);
                              }
                              catch
                              {
                                  if (smf.ChannelTextBox != "")
                                  {
                                      channelId = new ChannelId(smf.ChannelTextBox);
                                  }
                                  else
                                  {
                                      channelId = new ChannelId();
                                  }
                              }
                          }
                          var subInfo = new SubInfo
                          {
                              typeId = typeId,
                              channelIdSer = new ChannelIdSerializable(channelId)
                          };
                          SubscribeMessage(subInfo);
                          if (smf.PermanentSub)
                          {
                              //Subscriptions
                              //  Settings.Sate.AddSubscription(new SubInfo(typeId, null, channelId, false, false, false));
                              Settings.Sate.AddSubscription(subInfo);
                              Settings.Save();
                          }
                      }
                  }
              }
          }
  
          private void subscribeMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
              long typeId;
  
              if (node is DobUnit)
              {
                  typeId = ((DobUnit) node).TypeId;
              }
              else
              {
                  return;
              }
  
              if (Operations.IsOfType(typeId, Entity.ClassTypeId))
              {
                  SubscribeEntity(new SubInfo(typeId, null, null, true, true, true));
              }
              else if (Operations.IsOfType(typeId, Message.ClassTypeId))
              {
                  var subInfo = new SubInfo();
                  subInfo.typeId = typeId;
                  subInfo.channelIdSer = new ChannelIdSerializable(ChannelId.ALL_CHANNELS);
                  SubscribeMessage(subInfo);
                  //SubscribeMessage(typeId, Safir.Dob.Typesystem.ChannelId.ALL_CHANNELS);
              }
          }
  
          private void subscribeRegistrationMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
              long typeId;
  
              if (node is DobUnit)
              {
                  typeId = ((DobUnit) node).TypeId;
              }
              else
              {
                  return;
              }
  
              var handlerId = HandlerId.ALL_HANDLERS;
  
              if (Operations.IsOfType(typeId, Entity.ClassTypeId))
              {
                  var subRegInfo = new SubRegInfo();
                  subRegInfo.typeId = typeId;
                  subRegInfo.handlerIdSer = new HandlerIdSerializeable(handlerId);
                  subRegInfo.includeSubClasses = true;
                  subRegInfo.restartSubscription = true;
                  SubscribeRegistration(subRegInfo);
                  // save handlerid in node
                  ((DobUnit) node).HandlerId = handlerId;
              }
              else if (Operations.IsOfType(typeId, Service.ClassTypeId))
              {
                  var subRegInfo = new SubRegInfo();
                  subRegInfo.typeId = typeId;
                  subRegInfo.handlerIdSer = new HandlerIdSerializeable(handlerId);
                  subRegInfo.includeSubClasses = true;
                  subRegInfo.restartSubscription = true;
                  SubscribeRegistration(subRegInfo);
                  // save handlerid in node
                  ((DobUnit) node).HandlerId = handlerId;
              }
          }
  
  
          private void subscribeRegistrationOptionsMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
              long typeId;
  
              if (node is DobUnit)
              {
                  typeId = ((DobUnit) node).TypeId;
  
                  var srf = new SubscribeRegistrationForm(typeId);
                  srf.InitSubForm();
  
                  if (Operations.IsOfType(typeId, Entity.ClassTypeId) ||
                      Operations.IsOfType(typeId, Service.ClassTypeId))
                  {
                      if (srf.ShowDialog() == DialogResult.OK)
                      {
                          HandlerId handlerId;
                          // try to parse as an long. O/w use the string representation
                          try
                          {
                              var val = long.Parse(srf.HandlerIdTextBox);
                              handlerId = new HandlerId(val);
                          }
                          catch
                          {
                              if (srf.HandlerIdTextBox != "")
                              {
                                  handlerId = new HandlerId(srf.HandlerIdTextBox);
                              }
                              else
                              {
                                  handlerId = new HandlerId();
                              }
                          }
                          var subRegInfo = new SubRegInfo();
                          subRegInfo.typeId = typeId;
                          subRegInfo.handlerIdSer = new HandlerIdSerializeable(handlerId);
                          subRegInfo.includeSubClasses = true;
                          subRegInfo.restartSubscription = true;
                          SubscribeRegistration(subRegInfo);
                          // save handlerid in node
                          ((DobUnit) node).HandlerId = handlerId;
  
                          if (srf.PermanentSub)
                          {
                              //Subscriptions
                              Settings.Sate.AddSubscriptionReg(new SubRegInfo(typeId,
                                  new HandlerIdSerializeable(handlerId), srf.IncludeSubClassesSub, srf.RestartSub));
                              Settings.Save();
                          }
                      }
                  }
              }
          }
  
  
          private void registerMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
              long typeId;
              if (node is DobUnit)
              {
                  typeId = ((DobUnit) node).TypeId;
              }
              else
              {
                  return;
              }
              var handlerId = new HandlerId();
              // save handlerid in node
              ((DobUnit) node).HandlerId = handlerId;
  
              if (Operations.IsOfType(typeId, Entity.ClassTypeId))
              {
                  var regInfo = new RegInfo();
                  regInfo.handlerIdSer = new HandlerIdSerializeable(handlerId);
                  regInfo.typeId = typeId;
                  regInfo.pending = false;
                  regInfo.injection = false;
                  regInfo.requestorDecides = false;
                  RegisterEntity(regInfo);
              }
              else if (Operations.IsOfType(typeId, Service.ClassTypeId))
              {
                  var regInfo = new RegInfo();
                  regInfo.typeId = typeId;
                  regInfo.handlerIdSer = new HandlerIdSerializeable(handlerId);
                  regInfo.pending = false;
                  RegisterService(regInfo);
              }
          }
  
          private void unregisterMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
              long typeId;
              HandlerId handlerId;
              if (node is DobUnit)
              {
                  typeId = ((DobUnit) node).TypeId;
                  handlerId = ((DobUnit) node).HandlerId;
                  if (handlerId == null)
                  {
                      handlerId = new HandlerId();
                  }
              }
              else
              {
                  return;
              }
              var regInfo = new RegInfo();
              regInfo.handlerIdSer = new HandlerIdSerializeable(handlerId);
              regInfo.typeId = typeId;
              Unregister(regInfo);
          }
  
          private void registerOptionsMenuItem_Click(object sender, EventArgs e)
          {
              var node = GetSelectedNode();
              long typeId;
              if (node is DobUnit)
              {
                  typeId = ((DobUnit) node).TypeId;
                  var rf = new RegisterForm(typeId);
                  if (Operations.IsOfType(typeId, Entity.ClassTypeId))
                  {
                      rf.InitEntitySubForm();
                  }
                  else
                  {
                      rf.InitServiceSubForm();
                  }
  
                  if (rf.ShowDialog() == DialogResult.OK)
                  {
                      HandlerId handlerId;
                      /* try to parse as an long. O/w use the string representation */
                      try
                      {
                          var val = long.Parse(rf.HandlerId);
                          handlerId = new HandlerId(val);
                      }
                      catch
                      {
                          if (rf.HandlerId != "")
                          {
                              handlerId = new HandlerId(rf.HandlerId);
                          }
                          else
                          {
                              handlerId = new HandlerId();
                          }
                      }
  
                      if (Operations.IsOfType(typeId, Entity.ClassTypeId))
                      {
                          var regInfo = new RegInfo();
                          regInfo.typeId = typeId;
  
gt:                         regInfo.handlerIdSer = new HandlerIdSerializeable(handlerId);