/// <summary>
        /// Deserializes the graphtype
        /// </summary>
        /// <param name="g">the graphtype which acts as an intermediate storage between XML and the GraphAbstract
        /// </param>
        /// <returns></returns>
        private GraphAbstract Deserialize(GraphType g)
        {
            GraphAbstract abs = new GraphAbstract();

            abs.Description = g.Description;
            ShapeBase shape = null, from = null, to = null;
            NodeType node;
            DataType dt;

            Connection con;

            ParentChildCollection pcs = new ParentChildCollection(); //temporary store for parent-child relations

            #region Load the nodes
            for(int k =0; k<g.Nodes.Count;k++) //loop over all serialized nodes
            {
                try
                {
                    #region find out which type of shape needs to be instantiated

                    node = g.Nodes[k] as NodeType;

                    Type shapeType = Type.GetType(node.Type);

                    if (shapeType != null)
                    {
                        object[] args = {this.site};
                        shape = Activator.CreateInstance(shapeType, args) as ShapeBase;
                    }

                    #endregion

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

                        if(dt.Key=="ParentNode")
                        {
                            //forget the parenting, it's done in a separate loop to be sure all shapes are loaded
                            if(dt.Text.Count>0) //could be if the shape is the root
                                pcs.Add(new ParentChild(shape, dt.Text[0].ToString()));
                            else
                            {
                                shape.IsRoot = true;
                                abs.Root = shape;
                            }

                            continue;
                        }
                        foreach (PropertyInfo pi in shape.GetType().GetProperties())
                        {
                            if (Attribute.IsDefined(pi, typeof(GraphDataAttribute)))
                            {
                                if(pi.Name==dt.Key)
                                {

                                    if(pi.GetIndexParameters().Length==0)
                                    {
                                        if(pi.PropertyType.Equals(typeof(int)))
                                            pi.SetValue(shape,Convert.ToInt32(dt.Text[0]),null);
                                        else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer
                                            pi.SetValue(shape,Color.FromArgb(int.Parse(dt.Text[0].ToString())),null);
                                        else if(pi.PropertyType.Equals(typeof(string)))
                                            pi.SetValue(shape,(string)(dt.Text[0]),null);
                                        else if(pi.PropertyType.Equals(typeof(bool)))
                                            pi.SetValue(shape,Convert.ToBoolean(dt.Text[0]),null);
                                        else if(pi.PropertyType.Equals(typeof(Guid)))
                                            pi.SetValue(shape,new Guid((string) dt.Text[0]),null);
                                    }
                                    else
                                        pi.SetValue(shape,dt.Text,null);
                                    break;
                                }

                            }
                        }

                    }
                    #endregion
                    shape.Font = site.Font;
                    shape.Fit();
                    abs.Shapes.Add(shape);
                }
                catch(Exception exc)
                {
                    Trace.WriteLine(exc.Message);
                    continue;
                }

            }//loop over nodes
            #endregion

            //now for the edges;
            //every node has precisely one parent and one connection to it, unless it's the root

            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;
        }