internal static AttributeValuePair CreateFromsStrings(string attr, string val) {
            var av = new AttributeValuePair();

            string name = attr.ToLower();

            switch (name) {
                case "uri":
                    av.attributeTypeEnum = AttributeTypeEnum.Uri;
                    av.val = val;
                    break;
                case "constraint":
                    av.attributeTypeEnum = AttributeTypeEnum.Constraint;
                    av.val = val != "false";
                    break;
                case "label":
                    av.attributeTypeEnum = AttributeTypeEnum.Label;
                    av.val = val;
                    break;
                case "size":
                    av.attributeTypeEnum = AttributeTypeEnum.Size;
                    av.val = ParseP2(val);
                    break;
                case "style":
                    {
                        Styles styles = new Styles();
                        av.val = styles;
                        string[] vals = Split(val);
                        av.attributeTypeEnum = AttributeTypeEnum.Style;
                        for (int i = 0; i < vals.Length; ++i)
                        {
                            switch (vals[i])
                            {
                                case "filled": styles.Add(Style.Filled); break;
                                case "dashed": styles.Add(Style.Dashed); break;
                                case "solid": styles.Add(Style.Solid); break;
                                case "invis":
                                case "inviz":
                                case "hidden": styles.Add(Style.Invis); break;
                                case "bold": styles.Add(Style.Bold); break;
                                case "diagonals": styles.Add(Style.Diagonals); break;
                                case "dotted": styles.Add(Style.Dotted); break;
                                case "rounded": styles.Add(Style.Rounded); break;                                
                                default:
                                    int lw;
                                    if (ParseLineWidth(vals[i], out lw)) {
                                        styles.lineWidth = lw;
                                        break; 
                                    }
                                    throw new Exception(String.Format("unexpected style '{0}'", val));
                            }
                        }
                        break;
                    }
                case "color":
                    av.attributeTypeEnum = AttributeTypeEnum.Color;
                    av.val = val;
                    break;
                case "pos":
                    av.attributeTypeEnum = AttributeTypeEnum.Pos;
                    av.val = CreatePosData(val);
                    break;
                case "lp":
                    av.attributeTypeEnum = AttributeTypeEnum.LabelLocation;
                    av.val = CreatePosData(val);
                    break;
                case "fontname":
                    av.attributeTypeEnum = AttributeTypeEnum.Fontname;
                    av.val = val;
                    break;
                case "fontsize":
                    av.attributeTypeEnum = AttributeTypeEnum.FontSize;
                    av.val = (int)TryParseDouble(val, name);
                    break;
                case "rankdir":
                    av.attributeTypeEnum = AttributeTypeEnum.LayerDirection;
		            switch(val) {
		            case "LR": av.val = LayerDirection.LR; break;
		            case "TB":
		            case "TD": av.val = LayerDirection.TB; break;
		            case "RL": av.val = LayerDirection.RL; break;
		            case "BT": av.val = LayerDirection.BT; break;
		            default:
                        throw new Exception("layerdir value \"" + val + "\" is not supported");
		            }
                    break;
                case "labeldouble":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "bb":
                    av.attributeTypeEnum = AttributeTypeEnum.BBox;
                    av.val = CreateBBoxFromString(val);
                    break;
                case "fontcolor":
                    av.attributeTypeEnum = AttributeTypeEnum.Fontcolor;
                    av.val = val;
                    break;
                case "margin":
                    {
                        // a pair x,y (inches)
                        av.attributeTypeEnum = AttributeTypeEnum.Margin;
                        string[] vals = Split(val);
                        av.val = TryParseDouble(Get(vals, 0), name);
                        break;
                    }
                case "width":
                    av.attributeTypeEnum = AttributeTypeEnum.Width;
                    av.val = TryParseDouble(val, name); 
                    break;
                case "height":
                    av.attributeTypeEnum = AttributeTypeEnum.Height;
                    av.val = TryParseDouble(val, name); 
                    break;
                case "shape":
                    av.attributeTypeEnum = AttributeTypeEnum.Shape;
                    val = val.ToLower();
		            switch(val) {
		            case "box":           av.val = Shape.Box; break;
		            case "circle":        av.val = Shape.Circle; break;
		            case "ellipse":       av.val = Shape.Ellipse; break;
		            case "plaintext":     av.val = Shape.Plaintext; break;
		            case "point":         av.val = Shape.Point; break;
		            case "record":        av.val = Shape.Record; break;
		            case "mdiamond":      av.val = Shape.Mdiamond; break;
		            case "polygon":       av.val = Shape.Polygon; break;
		            case "doublecircle":  av.val = Shape.DoubleCircle; break;
		            case "house":         av.val = Shape.House; break;
		            case "invhouse":      av.val = Shape.InvHouse; break;
		            case "parallelogram": av.val = Shape.Parallelogram; break;
		            case "octagon":       av.val = Shape.Octagon; break;
		            case "tripleoctagon": av.val = Shape.TripleOctagon; break;
                    case "triangle":      av.val = Shape.Triangle; break;
                    case "trapezium":     av.val = Shape.Trapezium; break;
                    case "msquare":       av.val = Shape.Msquare; break;
                    case "diamond":       av.val = Shape.Diamond; break;
                    case "hexagon":       av.val = Shape.Hexagon;break;

                    default:              av.val = Shape.Ellipse; break;
		            }
                    break;
                case "ordering":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "rects": {
                    av.attributeTypeEnum = AttributeTypeEnum.Rects;
                    var al = new ArrayList();
                    av.val = al;

                    var points = Split(val);
                    var leftbottom = new P2();
                    var righttop = new P2();
                    for (int i = 0; i < points.Length-3; i += 4) {
                        leftbottom.X = (int)GetNumber(points[i]);
                        leftbottom.Y = (int)GetNumber(points[i+1]);
                        righttop.X = (int)GetNumber(points[i+2]);
                        righttop.Y = (int)GetNumber(points[i+3]);
                        al.Add(new Rectangle(leftbottom, righttop));
                    }
                    }
                    break;
                case "sides":
                    av.attributeTypeEnum = AttributeTypeEnum.Sides;
                    av.val = Int32.Parse(val);
                    break;
                case "distortion":
                    av.attributeTypeEnum = AttributeTypeEnum.Distortion;
                    av.val = val == "" ? 0.0 : TryParseDouble(val, name); 
                    break;
                case "orientation":
                    av.attributeTypeEnum = AttributeTypeEnum.Orientation;
                    av.val = val;
                    break;
                case "skew":
                    av.attributeTypeEnum = AttributeTypeEnum.Skew;
                    av.val = TryParseDouble(val, name); 
                    break;
                case "layer":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "nodesep":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "layersep":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "taillabel":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "ratio":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "minlen":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "splines":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "overlap":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "labeldistance":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "peripheries":
                case "fname":
                case "subkind":
                case "kind":
                case "pname":
                case "headlabel":
                case "samearrowhead":
                case "sametail":
                case "samehead":
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
                case "arrowtail":
                    av.attributeTypeEnum =AttributeTypeEnum.ArrowTail;
                    av.val = ParseArrowStyle(val);
                    break;
                case "arrowhead":
                    av.attributeTypeEnum = AttributeTypeEnum.Arrowhead;
                    av.val = ParseArrowStyle(val);
                    break;
                case "dir":
                    av.attributeTypeEnum = AttributeTypeEnum.EdgeDirection;
                    if (val == "back")
                        av.val = EdgeDirection.Back;
                    else if (val == "forward")
                        av.val = EdgeDirection.Forward;
                    else if (val == "both")
                        av.val = EdgeDirection.Both;
                    else if (val == "none")
                        av.val = EdgeDirection.None;
                    else
                        throw new Exception("unexpected edge direction '" + val + "'");
                    break;
                case "page":
                    av.attributeTypeEnum = AttributeTypeEnum.Page;
                    av.val = ParseP2(val);
                    break;
                case "regular":
                    av.attributeTypeEnum = AttributeTypeEnum.Regular;
                    av.val = val == "1";
                    break;
                case "center":
                    av.attributeTypeEnum = AttributeTypeEnum.Center;
                    av.val = val == "true";
                    break;
                case "wt":
                    av.attributeTypeEnum = AttributeTypeEnum.Weight;
                    av.val = Int32.Parse(val);
                    break;
                case "id":
                    av.attributeTypeEnum = AttributeTypeEnum.Id;
                    av.val = val;
                    break;
                case "labelfontsize":
                    av.attributeTypeEnum = AttributeTypeEnum.LabelFontSize;
                    av.val = val;
                    break;
                case "arrowsize":
                    av.attributeTypeEnum = AttributeTypeEnum.ArrowSize;
                    av.val = val;
                    break;
                case "labelangle":
                    av.attributeTypeEnum = AttributeTypeEnum.ArrowSize;
                    av.val = val;
                    break;
                case "weight":
                    av.attributeTypeEnum = AttributeTypeEnum.Weight;
                    av.val = val;
                    break;
                case "bgcolor":
                    av.attributeTypeEnum = AttributeTypeEnum.BGColor;
                    av.val = val;
                    break;
                case "fillcolor":
                    av.attributeTypeEnum = AttributeTypeEnum.FillColor;
                    av.val = val;
                    break;
                case "cellpadding":
                    av.attributeTypeEnum = AttributeTypeEnum.CELLPADDING;
                    av.val = Int32.Parse(val, AttributeBase.USCultureInfo);
                    break;
                case "border":
                    av.attributeTypeEnum = AttributeTypeEnum.Border;
                    av.val = Int32.Parse(val, AttributeBase.USCultureInfo);
                    break;
                case "xrad":
                    av.attributeTypeEnum = AttributeTypeEnum.XRad;
                    av.val = float.Parse(val, CultureInfo.InvariantCulture);
                    break;
                case "yrad":
                    av.attributeTypeEnum = AttributeTypeEnum.YRad;
                    av.val = float.Parse(val, CultureInfo.InvariantCulture);
                    break;
                case "padding":
                    av.attributeTypeEnum = AttributeTypeEnum.Padding;
                    av.val = float.Parse(val, CultureInfo.InvariantCulture);
                    break;
                default:
                    av.attributeTypeEnum = AttributeTypeEnum.Ignore;
                    break;
            }
            //throw new Exception("attribute \""+ attr +"\" is not supported");


            return av;
        }
        internal static void AddAttributeValuePair(CoupleLabelGraphAttr couple, AttributeValuePair attrVal) {
            if (AddAttributeKeyVal(new CoupleLabelBaseAttr(couple.Item1, couple.Item2), attrVal)) return;

            switch (attrVal.attributeTypeEnum) {
                case AttributeTypeEnum.Center:
                    // a.Center = (bool)attrVal.val;
                    break;
                case AttributeTypeEnum.BGColor:
                    couple.Item2.BackgroundColor = StringToMsaglColor((string) attrVal.val);
                    break;
                case AttributeTypeEnum.Page:
                    // a.Page = (P2)attrVal.val;        
                    break;
                case AttributeTypeEnum.BBox:
                    // a.BoundingBox = (Rectangle)attrVal.val;
                    break;
                case AttributeTypeEnum.Style: 
                    AddStyles(couple.Item2, attrVal.val);
                    break;                   
                case AttributeTypeEnum.Size: {
                    // P2 p = (P2)attrVal.val;
                    //a.size = p;
                }
                    break;
                case AttributeTypeEnum.Orientation: {
                    var s = attrVal.val as String;
                    //if (s == "portrait")
                    //    ;//  a.Orientation = Orientation.Portrait;
                    //else if (s.StartsWith("land"))
                    //    ;// a.Orientation = Orientation.Landscape;
                    //else
                    //    throw new Exception("unexpected \"" + attrVal.attributeTypeEnum.ToString() + "\"");
                }
                    break;
                case AttributeTypeEnum.LayerDirection:
                    couple.Item2.LayerDirection = (LayerDirection) attrVal.val;
                    break;
                case AttributeTypeEnum.CELLPADDING:
                    //a.CellPadding = (int)attrVal.val;
                    break;
                case AttributeTypeEnum.Border:
                    couple.Item2.Border = (int) attrVal.val;
                    break;
                case AttributeTypeEnum.Height: {
                    //              Rectangle r = a.BoundingBox;
                    //              r.Height = (int)attrVal.val;
                    //              a.BoundingBox = r;
                }
                    break;
                case AttributeTypeEnum.Width: {
                    //  Rectangle r = a.BoundingBox;
                    //  r.Width = (int)attrVal.val;
                    //  a.BoundingBox = r;
                    break;
                }
            }
        }
        internal static bool AddAttributeKeyVal(CoupleLabelBaseAttr couple, AttributeValuePair attrVal) {
            Label label = couple.Item1;
            AttributeBase attributeBase = couple.Item2;
            switch (attrVal.attributeTypeEnum) {
                case AttributeTypeEnum.Uri:
                    attributeBase.Uri = (string) attrVal.val;
                    break;
                case AttributeTypeEnum.Ignore:
                    break;
                case AttributeTypeEnum.Color:
                    attributeBase.Color = StringToMsaglColor((string) attrVal.val);
                    break;
                case AttributeTypeEnum.LabelFontSize:
                    label.FontSize = Int32.Parse(attrVal.val as String);
                    break;
                case AttributeTypeEnum.Fontcolor:
                    label.FontColor = StringToMsaglColor((string) attrVal.val);
                    break;

                case AttributeTypeEnum.Label:

                    label.Text = attrVal.val as String;
                    break;

                case AttributeTypeEnum.LabelLocation:
                    SetGeomLabelCenter(label, ((List<P2>) ((PosData) attrVal.val).ControlPoints)[0]);
                    break;


                case AttributeTypeEnum.Style:
                    AddStyles(attributeBase, attrVal.val);
                    break;


                case AttributeTypeEnum.RGBColor: {
                    attributeBase.Color = StringToMsaglColor((string) attrVal.val);
                    break;
                }
                case AttributeTypeEnum.FontSize: {
                    label.FontSize = (int) attrVal.val;
                    break;
                }
                case AttributeTypeEnum.Fontname: {
                    label.FontName = attrVal.val as String;
                    break;
                }

                default:
                    return false; //not handled
            }
            return true;
        }