/// <summary>
        /// The returned matrix can be used to transform coordinates from this Visual to
        /// the specified Visual.
        /// Returns null if no such transform exists due to a non-invertible Transform.
        /// </summary>
        /// <exception cref="ArgumentNullException">If visual is null.</exception>
        /// <exception cref="InvalidOperationException">If the Visuals are not connected.</exception>
        public GeneralTransform TransformToVisual(Visual visual)
        {
            DependencyObject ancestor = FindCommonVisualAncestor(visual);
            Visual ancestorAsVisual = ancestor as Visual;

            if (ancestorAsVisual == null)
            {
                throw new System.InvalidOperationException(SR.Get(SRID.Visual_NoCommonAncestor));
            }

            GeneralTransform g0;
            Matrix m0;

            bool isSimple0 = this.TrySimpleTransformToAncestor(ancestorAsVisual,
                                                               false,
                                                               out g0,
                                                               out m0);

            GeneralTransform g1;
            Matrix m1;

            bool isSimple1 = visual.TrySimpleTransformToAncestor(ancestorAsVisual,
                                                                 true,
                                                                 out g1,
                                                                 out m1);

            // combine the transforms
            // if both transforms are simple Matrix transforms, just multiply them and
            // return the result.
            if (isSimple0 && isSimple1)
            {
                MatrixUtil.MultiplyMatrix(ref m0, ref m1);
                MatrixTransform m = new MatrixTransform(m0);
                m.Freeze();
                return m;
            }

            // Handle the case where 0 is simple and 1 is complex.
            if (isSimple0)
            {
                g0 = new MatrixTransform(m0);
                g0.Freeze();
            }
            else if (isSimple1)
            {
                g1 = new MatrixTransform(m1);
                g1.Freeze();
            }

            // If inverse was requested, TrySimpleTransformToAncestor can return null
            // add the transform only if it is not null
            if (g1 != null)
            {
                GeneralTransformGroup group = new GeneralTransformGroup();
                group.Children.Add(g0);
                group.Children.Add(g1);
                group.Freeze();
                return group;
            }

            return g0;
        }