private static void WriteShapes(XmlWriter writer, GraphAbstract g)
        {
            writer.WriteStartElement("g");
            for (int k = 0; k < g.Shapes.Count; k++)        //<rect x="1140" y="30" width="100" height="20" style="fill: url(#two_hues); stroke: black;"/>
            {
                writer.WriteStartElement("rect");
                writer.WriteAttributeString("x", g.Shapes[k].X.ToString());
                writer.WriteAttributeString("y", g.Shapes[k].Y.ToString());
                writer.WriteAttributeString("width", g.Shapes[k].Width.ToString());
                writer.WriteAttributeString("height", g.Shapes[k].Height.ToString());
                writer.WriteAttributeString("rx", "2");                //rounded rectangle

                //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;");
                writer.WriteAttributeString("fill", string.Concat("#", (g.Shapes[k].ShapeColor.ToArgb() & 0x00FFFFFF).ToString("X6")));
                writer.WriteEndElement();

                //<text text-anchor="middle" x="{$x+50}" y="{$y+15}">
                writer.WriteStartElement("text");
                writer.WriteAttributeString("x", Convert.ToString(g.Shapes[k].X + 10));
                writer.WriteAttributeString("y", Convert.ToString(g.Shapes[k].Y + 15));
                writer.WriteAttributeString("text-anchor", "start");
                writer.WriteAttributeString("font-size", "9");
                writer.WriteString(g.Shapes[k].Text);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
		private static void WriteShapes(XmlWriter writer, GraphAbstract g)
		{
			writer.WriteStartElement("g");
			for(int k=0; k<g.Shapes.Count; k++) //<rect x="1140" y="30" width="100" height="20" style="fill: url(#two_hues); stroke: black;"/>
			{
				writer.WriteStartElement("rect");
				writer.WriteAttributeString("x", g.Shapes[k].X.ToString());
				writer.WriteAttributeString("y", g.Shapes[k].Y.ToString());
				writer.WriteAttributeString("width", g.Shapes[k].Width.ToString());
				writer.WriteAttributeString("height", g.Shapes[k].Height.ToString());
				writer.WriteAttributeString("rx", "2");//rounded rectangle				

				//writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;");
				writer.WriteAttributeString("fill",  string.Concat("#", (g.Shapes[k].ShapeColor.ToArgb() & 0x00FFFFFF).ToString("X6")) );
				writer.WriteEndElement();
				
				//<text text-anchor="middle" x="{$x+50}" y="{$y+15}">
				writer.WriteStartElement("text");
				writer.WriteAttributeString("x", Convert.ToString(g.Shapes[k].X + 10));
				writer.WriteAttributeString("y", Convert.ToString(g.Shapes[k].Y + 15));
				writer.WriteAttributeString("text-anchor", "start");			
				writer.WriteAttributeString("font-size", "9");
				writer.WriteString(g.Shapes[k].Text);
				writer.WriteEndElement();
				
			}
			writer.WriteEndElement();
		}
        public void Serialize(XmlWriter writer, GraphAbstract g	)
        {
            GraphMLType graphml = new GraphMLType();

            graphml.Key.Add(BuildKeyType(nodeShapeTypeKeyName));
            graphml.Key.Add(BuildKeyType(edgeConnectionTypeKeyName));

            GraphType graph = new GraphType();
            graphml.Items.Add(graph);

            foreach ( Shape s in g.Shapes )
            {
                graph.Items.Add(SerializeNode(s));
            }

            foreach(Connection c in g.Connections)
            {
                graph.Items.Add(SerializeEdge(c));
            }

            foreach(DictionaryEntry de in KeyList)
            {
                graphml.Key.Add(BuildKeyType((String)de.Key));
            }

            // serialize
            XmlSerializer ser = new XmlSerializer(typeof(GraphMLType));
            ser.Serialize(writer,graphml);
        }
        protected BinaryCapsule(SerializationInfo info, StreamingContext context)
        {
            try
            {
                this.mBinaryAmbiance = info.GetValue("mBinaryAmbiance", typeof(BinaryAmbiance)) as BinaryAmbiance;
            }
            catch (Exception exc)
            {
                Trace.WriteLine(exc.Message, "BinaryCapsule.DeserializationConstructor");
                //trying to recover the old binaries
                this.mBinaryAmbiance = info.GetValue("mBinaryAmbience", typeof(BinaryAmbiance)) as BinaryAmbiance;
            }
            this.mGraphAbstract = info.GetValue("mGraphAbstract", typeof(GraphAbstract)) as GraphAbstract;

            if (mGraphAbstract != null && mGraphAbstract.Layers != null)
            {
                foreach (GraphLayer tLayer in mGraphAbstract.Layers)
                {
                    if (tLayer.Name != "Default" && tLayer.Visible)
                    {
                        mGraphAbstract.ActiveLayer(tLayer.Name);
                        break;
                    }
                }

                if (mGraphAbstract.CurrentLayer == null)
                {
                    mGraphAbstract.ActiveLayer("Default");
                }
            }

            this.mThumbnail = info.GetValue("mThumbnail", typeof(Image)) as Image;
        }
 private static void WriteMetadata(XmlWriter writer, GraphAbstract g)
 {
     writer.WriteStartElement("title");
     writer.WriteString(g.GraphInformation.Title);
     writer.WriteEndElement();
     writer.WriteStartElement("desc");
     writer.WriteString(g.GraphInformation.Description);
     writer.WriteEndElement();
 }
Beispiel #6
0
 public void LoadWork(GraphAbstract site, GraphControl graph)
 {
     for (int i = 0; i < this.mGraphList.Count; i++)
     {
         if (this.mGraphList[i] == site)
         {
             graph.Abstract = site;
         }
     }
 }
        /// <summary>
        /// Serializes the given graph abstract to XML with the given XmlWriter
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="g"></param>
        public static void Serialize(XmlWriter writer, GraphAbstract g)
        {
            writer.WriteStartElement("svg");
            writer.WriteAttributeString("xmlns", "http://www.w3.org/2000/svg");
            WriteDefinitions(writer);
            WriteFilters(writer);
            WriteMetadata(writer, g);

            WriteConnections(writer, g);
            WriteShapes(writer, g);

            writer.WriteEndElement();
        }
		/// <summary>
		/// Serializes the given graph abstract to XML with the given XmlWriter
		/// </summary>
		/// <param name="writer"></param>
		/// <param name="g"></param>
		public static void Serialize(XmlWriter writer, GraphAbstract g	)
		{
			writer.WriteStartElement("svg");
			writer.WriteAttributeString("xmlns","http://www.w3.org/2000/svg");
			WriteDefinitions(writer);
			WriteFilters(writer);
			WriteMetadata(writer, g);
			
			WriteConnections(writer, g);
			WriteShapes(writer, g);

			writer.WriteEndElement();
		}
Beispiel #9
0
        public DockContent CreateWorkForm(string Title, float width, float height, GraphAbstract site)
        {
            lastAdded = tabFactory.GetTab(new TabCodon("W" + GUIDTo16.GuidToLongID(), Title, TabTypes.WorkArea)
            {
                MapHeight = height, MapWidth = width
            }) as WorkForm;
            WorkForm work = lastAdded as WorkForm;

            work.GraphControl.Abstract = site;
            lastAdded.TabText          = Title;
            lastAdded.Text             = Title;
            OnShowTab(lastAdded);
            return(lastAdded);
        }
Beispiel #10
0
 private void 粘贴视图ToolStripMenuItem1_Click(object sender, EventArgs e)
 {
     try
     {
         if (this.treeView.SelectedNode is FlowProjectNode)
         {
             GraphAbstract data       = null;
             IDataObject   dataObject = Clipboard.GetDataObject();
             if (dataObject.GetDataPresent("Scada.FlowGraphEngine.GraphicsMap.GraphSite.Copy"))
             {
                 data = dataObject.GetData("Scada.FlowGraphEngine.GraphicsMap.GraphSite.Copy") as GraphAbstract;
             }
             if (data != null)
             {
                 FlowProjectNode  selectedNode = this.treeView.SelectedNode as FlowProjectNode;
                 CreateViewDialog dialog       = new CreateViewDialog();
                 if (dialog.ShowDialog(this) == DialogResult.OK)
                 {
                     data.GID = "V_" + GUIDTo16.GuidToLongID();
                     SCADAViewNode node = new SCADAViewNode
                     {
                         Text             = dialog.ViewName,
                         ContextMenuStrip = this.contextMenuView,
                         View             = (WorkForm)this.mediator.CreateWorkForm(dialog.ViewName, (float)dialog.PageWidth, (float)dialog.PageHeight)
                     };
                     node.View.GraphControl.Abstract       = data;
                     node.View.GraphControl.Abstract.Site  = node.View.GraphControl;
                     node.View.GraphControl.BasicLayer     = data.Layers[0];
                     node.View.GraphControl.SaveViewResult = delegate(bool res, string msg) {
                         if (res)
                         {
                             this.LoadTreeViewTemplate();
                         }
                         else
                         {
                             MessageBox.Show(this, msg);
                         }
                     };
                     selectedNode.Nodes.Add(node);
                     selectedNode.Project.GraphList.Add(node.View.GraphControl.Abstract);
                 }
                 Clipboard.Clear();
             }
         }
     }
     catch (Exception exception1)
     {
         MessageBox.Show(exception1.Message);
     }
 }
Beispiel #11
0
        public void LoadTempViewToProject(string tempFile)
        {
            FlowProjectNode selectedNode = null;

            if (this.treeView.SelectedNode != null)
            {
                if (this.treeView.SelectedNode is FlowProjectNode)
                {
                    selectedNode = this.treeView.SelectedNode as FlowProjectNode;
                }
                else if (this.treeView.SelectedNode is SCADAViewNode)
                {
                    selectedNode = this.treeView.SelectedNode.Parent as FlowProjectNode;
                }
                CreateViewDialog dialog = new CreateViewDialog();
                if (dialog.ShowDialog(this) == DialogResult.OK)
                {
                    SCADAViewNode node2 = new SCADAViewNode
                    {
                        Text             = dialog.ViewName,
                        ContextMenuStrip = this.contextMenuView,
                        View             = (WorkForm)this.mediator.CreateWorkForm(dialog.ViewName, (float)dialog.PageWidth, (float)dialog.PageHeight)
                    };
                    GraphAbstract @abstract = node2.View.GraphControl.LoadView(tempFile);
                    node2.View.GraphControl.Abstract.MapHeight = @abstract.MapHeight;
                    node2.View.GraphControl.Abstract.MapWidth  = @abstract.MapWidth;
                    node2.View.GraphControl.Abstract.ViewTitle = dialog.ViewName;
                    node2.View.GraphControl.Layers.Clear();
                    node2.View.GraphControl.AddLayer(@abstract.Layers[0]);
                    node2.View.GraphControl.BasicLayer = @abstract.Layers[0];
                    for (int i = 0; i < @abstract.Shapes.Count; i++)
                    {
                        node2.View.GraphControl.AddShape(@abstract.Shapes[i], AddShapeType.Create, null, -1);
                    }
                    node2.View.GraphControl.SaveViewResult = delegate(bool res, string msg) {
                        if (res)
                        {
                            this.LoadTreeViewTemplate();
                        }
                        else
                        {
                            MessageBox.Show(this, msg);
                        }
                    };
                    node2.View.GraphControl.LoadViewResult = (res, msg) => MessageBox.Show(this, msg);
                    selectedNode.Nodes.Add(node2);
                    selectedNode.Project.GraphList.Add(node2.View.GraphControl.Abstract);
                }
            }
        }
        /// <summary>
        /// Starts the serialization process. Takes the abstract of the graph and
        /// constructs a NMLType proxy-like object which will be serialized via the
        /// standard .Net XmlSerializer process.
        /// </summary>
        /// <param name="writer">An XmlWriter</param>
        /// <param name="g">The GraphAbstract object to be serialized</param>
        public void Serialize(XmlWriter writer, GraphAbstract g)
        {
            try
            {
                //the root of the NML
                NMLType nml = new NMLType();
                //add the version node
                nml.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
                //the graph node
                GraphType graph = new GraphType();
                nml.Graph = graph;
                //add the graph information
                graph.GraphInformation = new GraphInformationType(g.GraphInformation);
                //serialize the shapes
                foreach (Shape s in g.Shapes)
                {
                    graph.Items.Add(SerializeNode(s));
                }
                //serialize the connections
                foreach (Connection c in g.Connections)
                {
                    graph.Items.Add(SerializeEdge(c));
                }

                //			foreach(DictionaryEntry de in keyList)
                //			{
                //				nml.Key.Add(BuildKeyType((String)de.Key));
                //			}


                // serialize
                XmlSerializer ser = new XmlSerializer(typeof(NMLType));

                ser.Serialize(writer, nml);
            }


            catch (Exception exc)
            {
                site.OutputInfo(exc.Message, "NMLSerializer.Serialize", OutputInfoLevels.Exception);
            }
            catch
            {
                site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Serialize", OutputInfoLevels.Exception);
            }
            finally
            {
            }
        }
		protected  BinaryCapsule(SerializationInfo info, StreamingContext context) 
		{
			try
			{
				this.mBinaryAmbiance = info.GetValue("mBinaryAmbiance", typeof(BinaryAmbiance)) as BinaryAmbiance;
			}
			catch(Exception exc)
			{
				Trace.WriteLine(exc.Message, "BinaryCapsule.DeserializationConstructor");
				//trying to recover the old binaries
				this.mBinaryAmbiance = info.GetValue("mBinaryAmbience", typeof(BinaryAmbiance)) as BinaryAmbiance;
			}
			this.mGraphAbstract = info.GetValue("mGraphAbstract", typeof(GraphAbstract)) as GraphAbstract;
			this.mThumbnail = info.GetValue("mThumbnail", typeof(Image)) as Image;
		}
 protected BinaryCapsule(SerializationInfo info, StreamingContext context)
 {
     try
     {
         this.mBinaryAmbiance = info.GetValue("mBinaryAmbiance", typeof(BinaryAmbiance)) as BinaryAmbiance;
     }
     catch (Exception exc)
     {
         Trace.WriteLine(exc.Message, "BinaryCapsule.DeserializationConstructor");
         //trying to recover the old binaries
         this.mBinaryAmbiance = info.GetValue("mBinaryAmbience", typeof(BinaryAmbiance)) as BinaryAmbiance;
     }
     this.mGraphAbstract = info.GetValue("mGraphAbstract", typeof(GraphAbstract)) as GraphAbstract;
     this.mThumbnail     = info.GetValue("mThumbnail", typeof(Image)) as Image;
 }
        /// <summary>
        /// Returns the NML representation of the given GraphAbstract
        /// </summary>
        /// <returns></returns>
        public string Serialize()
        {
            try
            {
                GraphAbstract             g             = this.site.Abstract;
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();

                MemoryStream  stream = new MemoryStream();
                XmlTextWriter writer = new XmlTextWriter(stream, System.Text.ASCIIEncoding.ASCII);
                writer.Formatting = System.Xml.Formatting.Indented;
                this.Serialize(writer, g);


                //StringReader reader = new StringReader();
                int count = 0;
                stream.Seek(0, SeekOrigin.Begin);

                byte[] byteArray = new byte[stream.Length];

                while (count < stream.Length)
                {
                    byteArray[count++] = Convert.ToByte(stream.ReadByte());
                }

                // Decode the byte array into a char array
                // and write it to the console.
                char[] charArray = new char[asciiEncoding.GetCharCount(byteArray, 0, count)];
                asciiEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0);

                string s = new string(charArray);


                writer.Close();

                stream.Close();
                return(s);
            }
            catch (Exception exc)
            {
                Trace.WriteLine(exc.Message, "NMLSerializer.Serialize");
                return(string.Empty);
            }
        }
 private static void WriteConnections(XmlWriter writer, GraphAbstract g)
 {
     /*
      *      <line class="edge" x1="{$x1}" y1="{$y1}" x2="{$x}" y2="{$y+50}">
      *      <xsl:attribute name="style">marker-end:url(#arrow)</xsl:attribute>
      *      </line>
      */
     writer.WriteStartElement("g");
     for (int k = 0; k < g.Connections.Count; k++)
     {
         writer.WriteStartElement("line");
         writer.WriteAttributeString("x1", g.Connections[k].From.Location.X.ToString());
         writer.WriteAttributeString("y1", g.Connections[k].From.Location.Y.ToString());
         writer.WriteAttributeString("x2", g.Connections[k].To.Location.X.ToString());
         writer.WriteAttributeString("y2", g.Connections[k].To.Location.Y.ToString());
         //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;");
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
 }
		private static void WriteConnections(XmlWriter writer, GraphAbstract g)
		{
			/*
				<line class="edge" x1="{$x1}" y1="{$y1}" x2="{$x}" y2="{$y+50}">
				<xsl:attribute name="style">marker-end:url(#arrow)</xsl:attribute>
				</line>
			 */
			writer.WriteStartElement("g");
			for(int k=0; k<g.Connections.Count; k++) 
			{
				writer.WriteStartElement("line");
				writer.WriteAttributeString("x1", g.Connections[k].From.Location.X.ToString());
				writer.WriteAttributeString("y1", g.Connections[k].From.Location.Y.ToString());
				writer.WriteAttributeString("x2", g.Connections[k].To.Location.X.ToString());
				writer.WriteAttributeString("y2", g.Connections[k].To.Location.Y.ToString());				
				//writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;");				
				writer.WriteEndElement();
			}
			writer.WriteEndElement();
		}
Beispiel #18
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="extract"></param>
        /// <param name="discardFixed">whether to discard the ixed shapes in the analysis</param>
        public GraphAnalyzer(GraphAbstract extract, bool discardFixed) : base(extract.Shapes.Count)
        {
            this.extract = extract;


            shapeGluon      = new Shape[extract.Shapes.Count];
            connectionGluon = new Connection[extract.Shapes.Count, extract.Shapes.Count];
            //we assign the index in the Shapes collection to the vertex
            int m = 0;

            foreach (Shape shape in extract.Shapes)
            {
                if (shape.IsFixed && discardFixed)
                {
                    continue;
                }
                else
                {
                    AddVertex(m);
                    shapeGluon[m]         = extract.Shapes[m];
                    extract.Shapes[m].Tag = m;
                    m++;
                }
            }
            mCount = extract.Shapes.Count;
            int v, w;

            for (int k = 0; k < extract.Connections.Count; k++)
            {
                try
                {
                    v = (int)extract.Connections[k].From.BelongsTo.Tag;
                    w = (int)extract.Connections[k].To.BelongsTo.Tag;

                    this.AddConnection(v, w);
                    connectionGluon[v, w] = extract.Connections[k];
                    connectionGluon[w, v] = extract.Connections[k];
                }
                catch { continue; }
            }
        }
		/// <summary>
		/// Starts the serialization process. Takes the abstract of the graph and
		/// constructs a NMLType proxy-like object which will be serialized via the 
		/// standard .Net XmlSerializer process.
		/// </summary>
		/// <param name="writer">An XmlWriter</param>
		/// <param name="g">The GraphAbstract object to be serialized</param>
		public void Serialize(XmlWriter writer, GraphAbstract g	)
		{
			try
			{
				//the root of the NML
				NMLType nml = new NMLType(); 
				//add the version node
				nml.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
				//the graph node 
				GraphType graph = new GraphType();	
				nml.Graph = graph;				
				//add the graph information				
				graph.GraphInformation = new GraphInformationType(g.GraphInformation);
				//serialize the shapes
				foreach ( Shape s in g.Shapes )				
					graph.Items.Add(SerializeNode(s));				
				//serialize the connections
				foreach(Connection c in g.Connections)
					graph.Items.Add(SerializeEdge(c));
				
				//			foreach(DictionaryEntry de in keyList)
				//			{
				//				nml.Key.Add(BuildKeyType((String)de.Key));
				//			}

			
				// serialize
				XmlSerializer ser = new XmlSerializer(typeof(NMLType));
				
				ser.Serialize(writer,nml);
	
			}

			
			catch(Exception exc)
			{
				site.OutputInfo(exc.Message, "NMLSerializer.Serialize", OutputInfoLevels.Exception);
			}
			catch
			{
				site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Serialize", OutputInfoLevels.Exception);
			}
			finally
			{
						
			}
		}
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="graphAbstract"></param>
 /// <param name="ambiance"></param>
 public BinaryCapsule(GraphAbstract graphAbstract, BinaryAmbiance ambiance)
 {
     this.mGraphAbstract  = graphAbstract;
     this.mBinaryAmbiance = ambiance;
 }
        /// <summary>
        /// Opens the binary-saved diagram
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="site"></param>
        public static void Open(string fileName, GraphControl site)
        {
            FileStream fs = null;

            try
            {
                fs = File.OpenRead(fileName);
            }
            catch (System.IO.DirectoryNotFoundException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch (System.IO.FileLoadException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch (System.IO.FileNotFoundException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch
            {
                site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.SaveAs", OutputInfoLevels.Exception);
            }
            //donnot open anything if filestream is not there
            if (fs == null)
            {
                return;
            }
            try
            {
                BinaryFormatter f = new BinaryFormatter();

                //this added for temporarily solving the open file issue
                //of different namespace of customed shapes: SequenceShape, IfShape etc.
                //if save flowchart data file using one version, open with another version,
                //exception raised: "无法找到程序集..."
                //TODO: remove below statement for release version
                f.Binder = new UBinder();

                BinaryCapsule capsule = (BinaryCapsule)f.Deserialize(fs);  //so simple, so powerful

                GraphAbstract tmp = capsule.Abstract;

                SetControlAmbiance(site, capsule.Ambiance);

                tmp.Site = site;
                //site.extract = new GraphAbstract();
                site.extract = tmp;


                //the paintables are not serialized and need to be filled
                site.extract.paintables.AddRange(site.extract.Shapes);
                site.extract.paintables.AddRange(site.extract.Connections);
                site.extract.SortPaintables();


                UnwrapBundle(tmp, site);
            }
            catch (SerializationException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch (System.Reflection.TargetInvocationException exc)
            {
                site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception);
            }
            catch (Exception exc)
            {
                site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception);
            }
            catch
            {
                site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Open", OutputInfoLevels.Exception);
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }
        /// <summary>
        /// Opens the binary-saved diagram
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="site"></param>
        public static void Open(string fileName, GraphControl site)
        {
            FileStream fs = null;

            try
            {
                fs = File.OpenRead(fileName);
            }
            catch (System.IO.DirectoryNotFoundException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch (System.IO.FileLoadException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch (System.IO.FileNotFoundException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch
            {
                site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.SaveAs", OutputInfoLevels.Exception);
            }
            //donnot open anything if filestream is not there
            if (fs == null)
            {
                return;
            }
            try
            {
                BinaryFormatter f = new BinaryFormatter();

                BinaryCapsule capsule = (BinaryCapsule)f.Deserialize(fs);                  //so simple, so powerful

                GraphAbstract tmp = capsule.Abstract;

                SetControlAmbiance(site, capsule.Ambiance);

                tmp.Site = site;
                //site.extract = new GraphAbstract();
                site.extract = tmp;


                //the paintables are not serialized and need to be filled
                site.extract.paintables.AddRange(site.extract.Shapes);
                site.extract.paintables.AddRange(site.extract.Connections);
                site.extract.SortPaintables();


                UnwrapBundle(tmp, site);
            }
            catch (SerializationException exc)
            {
                System.Windows.Forms.MessageBox.Show(exc.Message);
            }
            catch (System.Reflection.TargetInvocationException exc)
            {
                site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception);
            }
            catch (Exception exc)
            {
                site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception);
            }
            catch
            {
                site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Open", OutputInfoLevels.Exception);
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="graphAbstract"></param>
		/// <param name="ambiance"></param>
		public BinaryCapsule(GraphAbstract graphAbstract, BinaryAmbiance ambiance)
		{
			this.mGraphAbstract = graphAbstract;
			this.mBinaryAmbiance = ambiance;
		}
        /// <summary>
        /// Deserializes the graphtype, here's where all the smart stuff happens
        /// </summary>
        /// <param name="gml">the graphtype which acts as an intermediate storage between XML and the GraphAbstract
        /// </param>
        /// <returns></returns>
        private GraphAbstract Deserialize(NMLType gml)
        {
            GraphAbstract abs = new GraphAbstract();

            #region Load the graph information
            GraphType g = gml.Graph;

            abs.GraphInformation = g.GraphInformation.ToGraphInformation();

            #endregion
            Shape          shape = null;
            ShapeType      node;
            DataType       dt;
            ConnectorType  ct;
            Connection     con = null;
            ConnectionType et;
            string         linePath = string.Empty;               //see the split deserialization of the connection

            FromToCollection ftc        = new FromToCollection(); //temporary store for from-to relations of connections
            Hashtable        connectors = new Hashtable();        //temporary collection of connector
            #region Loop over all items



            for (int k = 0; k < g.Items.Count; k++)        //loop over all serialized items
            {
                try
                {
                    if (g.Items[k] is ShapeType)
                    {
                        Trace.WriteLine("Node: " + (g.Items[k] as ShapeType).UID, "NMLSerializer.Deserialize");
                        node = g.Items[k] as ShapeType;

                        #region find out which type of shape needs to be instantiated
                        if (node != null && node.InstanceKey != string.Empty)
                        {
                            shape = GetShape(node.InstanceKey);
                        }
                        if (shape == null)
                        {
                            Trace.WriteLine("...but failed to instantiate the appropriate shape (missing or not loaded library?", "NMLSerializer.Deserialize");
                            continue;
                        }

                        #endregion
                        #region use the attribs again to reconstruct the props
                        for (int m = 0; m < node.Data.Count; m++)                   //loop over the serialized data
                        {
                            if (node.Data[m] is DataType)
                            {
                                #region Handle data node
                                dt = node.Data[m] as DataType;
                                if (dt == null)
                                {
                                    continue;
                                }

                                foreach (PropertyInfo pi in shape.GetType().GetProperties())
                                {
                                    if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute)))
                                    {
                                        try
                                        {
                                            if (pi.Name == dt.Name)
                                            {
                                                if (pi.GetIndexParameters().Length == 0)
                                                {
                                                    if (pi.PropertyType.Equals(typeof(int)))
                                                    {
                                                        pi.SetValue(shape, Convert.ToInt32(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(Color)))                                                    //Color is stored as an integer
                                                    {
                                                        pi.SetValue(shape, Color.FromArgb(int.Parse(dt.Value[0].ToString())), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(string)))
                                                    {
                                                        pi.SetValue(shape, (string)(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(bool)))
                                                    {
                                                        pi.SetValue(shape, Convert.ToBoolean(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(Guid)))
                                                    {
                                                        pi.SetValue(shape, new Guid((string)dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(float)))
                                                    {
                                                        pi.SetValue(shape, Convert.ToSingle(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.BaseType.Equals(typeof(Enum)))                                                   //yesyes, you can imp/exp enum types too
                                                    {
                                                        pi.SetValue(shape, Enum.Parse(pi.PropertyType, dt.Value[0].ToString()), null);
                                                    }
                                                    else if (dt.IsCollection)
                                                    {
                                                        #region Some explanations

                                                        /* OK, here's the deal.
                                                         * This part is related to the possibility to imp/exp property-collections from/to NML.
                                                         * However, since (see more specifically the ClassShape) the collections will usually be defined
                                                         * where the shapes is defined, i.e. in an external assembly, the collection-type is unknown.
                                                         * Importing/exporting collections to NML is itsel a problem and in this part of the code the data is reflected again.
                                                         * To bypass the problem that the collection-type is unknown I hereby assume that the collection can be built up again via
                                                         * a public constructor of the collection with argument 'ArrayList'. In the ArrayList the collection-elements are of type string[]
                                                         * whereby the order of the strings reflect the order of the GraphMLData-tagged properties of the collection elements.
                                                         * For example, the ClassPropertiesCollection has the required constructor and the ClassProperty object is instantiated via the string[] elements in the
                                                         * ArrayList.
                                                         * Of course, this brings some restriction but it's for the moment the most flexible way I have found.
                                                         * If the ClassProperty would itself have a property inheriting from CollectionBase this will not work...one has to draw a line somewhere.
                                                         * It's the price to pay for using reflection and external assemblies. The whole story can be forgotten if you link the shape-classes at compile-time.
                                                         * Remember; the Netron graphlib is more a toolkit than a all-in solution to all situations.
                                                         * However, the current implementation will cover, I beleive, 90% of the needs.
                                                         */
                                                        #endregion

                                                        ArrayList list = new ArrayList();
                                                        for (int p = 0; p < dt.Value.Count; p++)                                                //loop over the collection elements
                                                        {
                                                            DataType dat = dt.Value[p] as DataType;                                             //take a collection element
                                                            if (dat.IsCollection)                                                               //is it itself a collection?
                                                            {
                                                                string[] str = new string[dat.Value.Count];
                                                                for (int l = 0; l < dat.Value.Count; l++)
                                                                {
                                                                    if ((dat.Value[l] as DataType).Value.Count > 0)
                                                                    {
                                                                        str[l] = (string)(dat.Value[l] as DataType).Value[0];
                                                                    }
                                                                    else
                                                                    {
                                                                        str[l] = string.Empty;
                                                                    }
                                                                }
                                                                list.Add(str);
                                                            }
                                                            else
                                                            {
                                                                list.Add(new string[] { (string)dat.Value[0] });
                                                            }
                                                        }
                                                        object o;
                                                        o = pi.PropertyType.GetConstructor(new Type[] { typeof(ArrayList) }).Invoke(new Object[] { list });
                                                        pi.SetValue(shape, o, null);
                                                        Trace.WriteLine("'" + dt.Name + "' is an array type", "NMLSeriliazer.Deserialize");
                                                    }
                                                }
                                                else
                                                {
                                                    pi.SetValue(shape, dt.Value, null);
                                                }
                                                Trace.WriteLine("'" + dt.Name + "' deserialized.", "NMLSeriliazer.Deserialize");
                                                break;
                                            }
                                        }
                                        catch (Exception exc)
                                        {
                                            Trace.WriteLine("Failed '" + dt.Name + "': " + exc.Message, "NMLSeriliazer.Deserialize");
                                            continue;                                            //just try to make the best out of it
                                        }
                                    }
                                }
                                #endregion
                            }
                            else if (node.Data[m] is ConnectorType)
                            {
                                #region Handle connector data
                                ct = node.Data[m] as ConnectorType;
                                foreach (Connector c in shape.Connectors)
                                {
                                    if (c.Name == ct.Name)
                                    {
                                        c.UID = new Guid(ct.UID);
                                        break;
                                    }
                                }
                                #endregion
                            }
                        }
                        #endregion
                        //at this point the shape is fully deserialized
                        //but we still need to assign the ambient properties,
                        //i.e. the properties associated to the current hosting of the control
                        if (shape != null)
                        {
                            shape.Site = site;
                            shape.PostDeserialization();
                            shape.Font = site.Font;
                            //shape.FitSize(false);
                            abs.Shapes.Add(shape);
                            //keep the references to the connectors, to be used when creating the connections
                            foreach (Connector cor in shape.Connectors)
                            {
                                connectors.Add(cor.UID.ToString(), cor);
                            }
                        }
                    }
                    else if (g.Items[k] is ConnectionType)
                    {
                        #region  handle the edge
                        //we cannot create the connection here since not all shapes have been instantiated yet
                        //keep the edges in temp collection, treated in next loop
                        et       = g.Items[k] as ConnectionType;
                        con      = new Connection(site);
                        con.Font = site.Font;
                        con.UID  = new Guid(et.ID);
                        Trace.WriteLine("Connection: " + et.ID, "NMLSeriliazer.Deserialize");
                        #region use the attribs to reconstruct the props


                        for (int m = 0; m < et.Data.Count; m++)                   //loop over the serialized data
                        {
                            if (et.Data[m] is DataType)
                            {
                                #region Handle data node, same as the shape
                                dt = et.Data[m] as DataType;
                                if (dt == null)
                                {
                                    continue;
                                }

                                foreach (PropertyInfo pi in con.GetType().GetProperties())
                                {
                                    if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute)))
                                    {
                                        try
                                        {
                                            if (pi.Name == dt.Name)
                                            {
                                                if (dt.Name == "LinePath")
                                                {
                                                    //the LinePath will not work without non-null From and To, so set it afterwards
                                                    linePath = dt.Value[0].ToString();
                                                }
                                                else if (pi.GetIndexParameters().Length == 0)
                                                {
                                                    if (pi.PropertyType.Equals(typeof(int)))
                                                    {
                                                        pi.SetValue(con, Convert.ToInt32(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(Color)))                                                    //Color is stored as an integer
                                                    {
                                                        pi.SetValue(con, Color.FromArgb(int.Parse(dt.Value[0].ToString())), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(string)))
                                                    {
                                                        pi.SetValue(con, (string)(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(bool)))
                                                    {
                                                        pi.SetValue(con, Convert.ToBoolean(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(Guid)))
                                                    {
                                                        pi.SetValue(con, new Guid((string)dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(float)))
                                                    {
                                                        pi.SetValue(con, Convert.ToSingle(dt.Value[0]), null);
                                                    }
                                                    else if (pi.PropertyType.Equals(typeof(ConnectionWeight)))
                                                    {
                                                        pi.SetValue(con, Enum.Parse(typeof(ConnectionWeight), dt.Value[0].ToString()), null);
                                                    }
                                                }
                                                else
                                                {
                                                    pi.SetValue(con, dt.Value, null);
                                                }
                                                Trace.WriteLine("'" + dt.Name + "' deserialized.", "NMLSeriliazer.Deserialize");
                                                break;
                                            }
                                        }
                                        catch (Exception exc)
                                        {
                                            Trace.WriteLine("Failed '" + dt.Name + "': " + exc.Message, "NMLSeriliazer.Deserialize");
                                            continue;                                            //just try to make the best out of it
                                        }
                                    }
                                }
                                #endregion
                            }
                        }

                        #endregion
                        ftc.Add(new FromTo(et.Sourceport, et.Targetport, con));
                        #endregion
                    }
                }
                catch (Exception exc)
                {
                    Trace.WriteLine(exc.Message, "NMLSeriliazer.Deserialize");
                    continue;
                }
            }            //loop over items in the graph-XML
            #endregion

            #region now for the edges;
            //loop over the FromTo collections and pick up the corresponding connectors
            for (int k = 0; k < ftc.Count; k++)
            {
                try
                {
                    con      = ftc[k].Connection;
                    con.From = connectors[ftc[k].From] as Connector;
                    con.To   = connectors[ftc[k].To] as Connector;
                    con.From.Connections.Add(con);               //if From is null we'll fail in the catch and continue
                    con.LinePath = linePath;                     //only setable after the From and To are found
                    con.To.Connections.Add(con);
                    abs.Insert(con);
                    Trace.WriteLine("Connection '" + con.UID + "' added.", "NMLSeriliazer.Deserialize");
                }
                catch (Exception exc)
                {
                    Trace.WriteLine("Connection failed: " + exc.Message, "NMLSeriliazer.Deserialize");
                    continue;                     //make the best of it
                }
            }
            #endregion


            //			for(int n=0; n<pcs.Count; n++)
            //			{
            //				from = pcs[n].ChildShape;
            //				to = abs.Shapes[pcs[n].Parent];
            //				con = new Connection(from, to );
            //				abs.Connections.Add(con);
            //				con.site = site;
            //				if(pcs[n].ChildShape.visible)
            //					con.visible = true;
            //				from.connection = con;	//a lot of crossing...to make life easy really
            //				from.parentNode =to;
            //				to.childNodes.Add(from);
            //
            //
            //			}

            return(abs);
        }
		/// <summary>
		/// Deserializes the graphtype, here's where all the smart stuff happens
		/// </summary>
		/// <param name="gml">the graphtype which acts as an intermediate storage between XML and the GraphAbstract
		/// </param>
		/// <returns></returns>
		private GraphAbstract Deserialize(NMLType gml)
		{
			GraphAbstract abs = new GraphAbstract();
			
			#region Load the graph information
			GraphType g = gml.Graph;
			
			abs.GraphInformation = g.GraphInformation.ToGraphInformation();		

			#endregion
			Shape shape = null;
			ShapeType node;
			DataType dt;				
			ConnectorType ct;
			Connection con = null;
			ConnectionType et;
			string linePath = string.Empty; //see the split deserialization of the connection
			
			FromToCollection ftc = new FromToCollection(); //temporary store for from-to relations of connections
			Hashtable connectors = new Hashtable(); //temporary collection of connector
			#region Loop over all items

			

			for(int k =0; k<g.Items.Count;k++) //loop over all serialized items
			{
				try
				{
					if(g.Items[k] is ShapeType)
					{
						Trace.WriteLine("Node: " + (g.Items[k] as ShapeType).UID,"NMLSerializer.Deserialize");
						node = g.Items[k] as ShapeType;

						#region find out which type of shape needs to be instantiated
						if(node!=null && node.InstanceKey!=string.Empty)
							shape = GetShape(node.InstanceKey);	
						if(shape==null)
						{
							Trace.WriteLine("...but failed to instantiate the appropriate shape (missing or not loaded library?", "NMLSerializer.Deserialize");
							continue;
						}

						#endregion
						#region use the attribs again to reconstruct the props				
						for(int m=0; m<node.Data.Count;m++) //loop over the serialized data
						{
							if(node.Data[m] is DataType)
							{
								#region Handle data node
								dt = node.Data[m] as DataType;												
								if(dt==null) continue;

								foreach (PropertyInfo pi in shape.GetType().GetProperties()) 
								{	
									if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute))) 
									{
										try
										{
											if(pi.Name==dt.Name)
											{
															
												if(pi.GetIndexParameters().Length==0)
												{
													if(pi.PropertyType.Equals(typeof(int)))
														pi.SetValue(shape,Convert.ToInt32(dt.Value[0]),null);
													else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer
														pi.SetValue(shape,Color.FromArgb(int.Parse(dt.Value[0].ToString())),null);
													else if(pi.PropertyType.Equals(typeof(string)))
														pi.SetValue(shape,(string)(dt.Value[0]),null);
													else if(pi.PropertyType.Equals(typeof(bool)))
														pi.SetValue(shape,Convert.ToBoolean(dt.Value[0]),null);	
													else if(pi.PropertyType.Equals(typeof(Guid)))
														pi.SetValue(shape,new Guid((string) dt.Value[0]),null);	
													else if(pi.PropertyType.Equals(typeof(float)))
														pi.SetValue(shape, Convert.ToSingle(dt.Value[0]),null);
													else if(pi.PropertyType.BaseType.Equals(typeof(Enum)))//yesyes, you can imp/exp enum types too
														pi.SetValue(shape, Enum.Parse(pi.PropertyType,dt.Value[0].ToString()),null);													
													else if(dt.IsCollection)
													{
														#region Some explanations
														/* OK, here's the deal. 
														 * This part is related to the possibility to imp/exp property-collections from/to NML.
														 * However, since (see more specifically the ClassShape) the collections will usually be defined
														 * where the shapes is defined, i.e. in an external assembly, the collection-type is unknown.
														 * Importing/exporting collections to NML is itsel a problem and in this part of the code the data is reflected again.
														 * To bypass the problem that the collection-type is unknown I hereby assume that the collection can be built up again via
														 * a public constructor of the collection with argument 'ArrayList'. In the ArrayList the collection-elements are of type string[]
														 * whereby the order of the strings reflect the order of the GraphMLData-tagged properties of the collection elements.
														 * For example, the ClassPropertiesCollection has the required constructor and the ClassProperty object is instantiated via the string[] elements in the
														 * ArrayList.
														 * Of course, this brings some restriction but it's for the moment the most flexible way I have found.
														 * If the ClassProperty would itself have a property inheriting from CollectionBase this will not work...one has to draw a line somewhere.
														 * It's the price to pay for using reflection and external assemblies. The whole story can be forgotten if you link the shape-classes at compile-time.
														 * Remember; the Netron graphlib is more a toolkit than a all-in solution to all situations. 
														 * However, the current implementation will cover, I beleive, 90% of the needs.
														 */
														#endregion
														
														ArrayList list = new ArrayList();
														for(int p =0; p<dt.Value.Count; p++) //loop over the collection elements
														{
															DataType dat = dt.Value[p] as DataType; //take a collection element
															if(dat.IsCollection)	//is it itself a collection?
															{
																string[] str = new string[dat.Value.Count];
																for(int l=0;l<dat.Value.Count;l++)
																{
																	if((dat.Value[l] as DataType).Value.Count>0)
																		str[l] = (string) (dat.Value[l] as DataType).Value[0];
																	else
																		str[l] = string.Empty;
																}
																list.Add(str); 
															}
															else
															{
																list.Add(new string[]{(string) dat.Value[0]}); 
															}
															
														}
														object o;
														o = pi.PropertyType.GetConstructor(new Type[]{typeof(ArrayList)}).Invoke(new Object[]{list});
														pi.SetValue(shape,o,null);
														Trace.WriteLine("'" + dt.Name + "' is an array type","NMLSeriliazer.Deserialize");
													}

												}
												else
													pi.SetValue(shape,dt.Value,null);
												Trace.WriteLine("'" + dt.Name + "' deserialized.","NMLSeriliazer.Deserialize");
												break;
											}
										}
										catch(Exception exc)
										{
											Trace.WriteLine("Failed '" + dt.Name +"': " + exc.Message,"NMLSeriliazer.Deserialize");
											continue;//just try to make the best out of it
										}
														
									}
								
								}
								#endregion
							}
							else if (node.Data[m] is ConnectorType)
							{
								#region Handle connector data
								ct = node.Data[m] as ConnectorType;
								foreach(Connector c in shape.Connectors)
									if(c.Name==ct.Name)
									{
										c.UID = new Guid(ct.UID);
										break;
									}
								#endregion
							}
						
						}
						#endregion
						//at this point the shape is fully deserialized
						//but we still need to assign the ambient properties,
						//i.e. the properties associated to the current hosting of the control
						if(shape !=null)
						{
							shape.Site = site;
							shape.PostDeserialization();
							shape.Font = site.Font;
							//shape.FitSize(false);
							abs.Shapes.Add(shape);
							//keep the references to the connectors, to be used when creating the connections
							foreach(Connector cor in shape.Connectors)
								connectors.Add(cor.UID.ToString(),cor);
						}
					}
					else if(g.Items[k] is ConnectionType)
					{
						#region  handle the edge
						//we cannot create the connection here since not all shapes have been instantiated yet
						//keep the edges in temp collection, treated in next loop
						et = g.Items[k] as ConnectionType;
						con = new Connection(site);
						con.Font = site.Font;
						con.UID = new Guid(et.ID);
						Trace.WriteLine("Connection: " + et.ID,"NMLSeriliazer.Deserialize");
						#region use the attribs to reconstruct the props


						for(int m=0; m<et.Data.Count;m++) //loop over the serialized data
						{
							if(et.Data[m] is DataType)
							{
								#region Handle data node, same as the shape
								dt = et.Data[m] as DataType;												
								if(dt==null) continue;

								foreach (PropertyInfo pi in con.GetType().GetProperties()) 
								{	
									if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute))) 
									{
										try
										{
											if(pi.Name==dt.Name)
											{
												if(dt.Name=="LinePath")
												{
													//the LinePath will not work without non-null From and To, so set it afterwards
													linePath = dt.Value[0].ToString();
												}
												else if(pi.GetIndexParameters().Length==0)
												{
													if(pi.PropertyType.Equals(typeof(int)))
														pi.SetValue(con,Convert.ToInt32(dt.Value[0]),null);
													else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer
														pi.SetValue(con,Color.FromArgb(int.Parse(dt.Value[0].ToString())),null);
													else if(pi.PropertyType.Equals(typeof(string)))
														pi.SetValue(con,(string)(dt.Value[0]),null);
													else if(pi.PropertyType.Equals(typeof(bool)))
														pi.SetValue(con,Convert.ToBoolean(dt.Value[0]),null);	
													else if(pi.PropertyType.Equals(typeof(Guid)))
														pi.SetValue(con,new Guid((string) dt.Value[0]),null);	
													else if(pi.PropertyType.Equals(typeof(float)))
														pi.SetValue(con, Convert.ToSingle(dt.Value[0]),null);
													else if (pi.PropertyType.Equals(typeof(ConnectionWeight)))
														pi.SetValue(con, Enum.Parse(typeof(ConnectionWeight),dt.Value[0].ToString()),null);
													else if (pi.PropertyType.Equals(typeof(System.Drawing.Drawing2D.DashStyle)))
														pi.SetValue(con, Enum.Parse(typeof(System.Drawing.Drawing2D.DashStyle),dt.Value[0].ToString()),null);

												}
												else
													pi.SetValue(con,dt.Value,null);
												Trace.WriteLine("'" + dt.Name + "' deserialized.","NMLSeriliazer.Deserialize");
												break;
											}
										}
										catch(Exception exc)
										{
											Trace.WriteLine("Failed '" + dt.Name +"': " + exc.Message,"NMLSeriliazer.Deserialize");
											continue;//just try to make the best out of it
										}
														
									}
								
								}
								#endregion
							}
						}

						#endregion
						ftc.Add(new FromTo(et.Sourceport,et.Targetport, con));
						#endregion
					}
				}
				catch(Exception exc)
				{
					Trace.WriteLine(exc.Message,"NMLSeriliazer.Deserialize");
					continue;
				}

			}//loop over items in the graph-XML
			#endregion

			#region now for the edges;
			//loop over the FromTo collections and pick up the corresponding connectors
			for(int k=0; k<ftc.Count; k++)
			{
				try
				{
					con = ftc[k].Connection;
					con.From = connectors[ftc[k].From] as Connector;
					con.To = connectors[ftc[k].To] as Connector;					
					con.From.Connections.Add(con);//if From is null we'll fail in the catch and continue
					con.LinePath = linePath; //only setable after the From and To are found
					con.To.Connections.Add(con);				
					abs.Insert(con);
					Trace.WriteLine("Connection '" + con.UID + "' added.","NMLSeriliazer.Deserialize");
				}
				catch(Exception exc)
				{
					Trace.WriteLine("Connection failed: " + exc.Message,"NMLSeriliazer.Deserialize");
					continue; //make the best of it
				}
			}
			#endregion
			

			//			for(int n=0; n<pcs.Count; n++)
			//			{	
			//				from = pcs[n].ChildShape;
			//				to = abs.Shapes[pcs[n].Parent];
			//				con = new Connection(from, to );
			//				abs.Connections.Add(con);
			//				con.site = site;
			//				if(pcs[n].ChildShape.visible)
			//					con.visible = true;
			//				from.connection = con;	//a lot of crossing...to make life easy really
			//				from.parentNode =to;
			//				to.childNodes.Add(from);
			//				
			//				
			//			}

			return abs;

		}
		private static void WriteMetadata(XmlWriter writer, GraphAbstract g)
		{
			writer.WriteStartElement("title");
			writer.WriteString(g.GraphInformation.Title);
			writer.WriteEndElement();
			writer.WriteStartElement("desc");
			writer.WriteString(g.GraphInformation.Description);
			writer.WriteEndElement();
		}