<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    I would not be in favor of adding a no-arg constructor to SkinBase,
    for the reasons Andy gave. Additionally, there would be no way to
    avoid braking the contract of Skin::getSkinnable which says:<br>
    <br>
    "This value will only ever go from a non-null to null value when the
    Skin is removed from the Skinnable, and only as a consequence of a
    call to dispose()."<br>
    <br>
    <blockquote type="cite">
      <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
          New",serif">At the very minimum, we should explain in
          Skin javadoc that creating a skin for one control and setting
          it in the other is a no-no.  Or, perhaps we should explicitly
          check for this condition in setSkin().</span></p>
    </blockquote>
    <br>
    I agree completely. At a minimum this enhancement should change the
    docs for setSkin to say that a skin created for one control should
    not (must not?) be used in another control. And unless there is a
    legitimate use case I haven't thought of, I think we could consider
    an explicit check, and either throw an Exception (this seems the
    best choice, unless there are compatibility concerns), or else log a
    warning and treat it as a no-op.<br>
    <br>
    -- Kevin<br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 7/22/2022 9:13 AM, Andy Goryachev
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:BL0PR10MB29485243D0DD4145D8C4714DE5909@BL0PR10MB2948.namprd10.prod.outlook.com">
      
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style>@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}@font-face
        {font-family:"Apple Color Emoji";
        panose-1:0 0 0 0 0 0 0 0 0 0;}@font-face
        {font-family:"Times New Roman \(Body CS\)";
        panose-1:2 11 6 4 2 2 2 2 2 4;}p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0in;
        margin-right:0in;
        margin-bottom:0in;
        margin-left:.5in;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Courier New",serif;
        color:windowtext;}.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}div.WordSection1
        {page:WordSection1;}ol
        {margin-bottom:0in;}ul
        {margin-bottom:0in;}</style>
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">You do bring a good point!  I don't know
            the rationale behind passing control pointer to the Skin
            constructor. 
            <o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">I think Swing got it right, clearly
            separating<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <ul style="margin-top:0in" type="disc">
          <li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo1"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">instantiation (using either a no-arg
              constructor, or any other constructor that does not
              require component pointer)<o:p></o:p></span></li>
          <li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo1"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">configuration (optional step, possibly
              widely separated in time and space)<o:p></o:p></span></li>
          <li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo1"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">uninstallation of the old skin<o:p></o:p></span></li>
          <li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo1"><span style="font-size:11.0pt;font-family:"Courier
              New",serif">installation of the new skin<o:p></o:p></span></li>
        </ul>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">What you are proposing - moving to a
            default constructor makes the most sense.  It comes with a
            high price though - everyone with a custom skin
            implementation would need to change their code.  <o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">At the very minimum, we should explain in
            Skin javadoc that creating a skin for one control and
            setting it in the other is a no-no.  Or, perhaps we should
            explicitly check for this condition in setSkin().<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">Thank you<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif">-andy<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
            New",serif"><o:p> </o:p></span></p>
        <div style="border:none;border-top:solid #B5C4DF
          1.0pt;padding:3.0pt 0in 0in 0in">
          <p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
              </span></b><span style="font-size:12.0pt;color:black">Marius
              Hanl <a class="moz-txt-link-rfc2396E" href="mailto:mariushanl@web.de"><mariushanl@web.de></a><br>
              <b>Date: </b>Friday, 2022/07/22 at 05:06<br>
              <b>To: </b><a class="moz-txt-link-abbreviated" href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a>
              <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"><openjfx-dev@openjdk.org></a>, Andy Goryachev
              <a class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com"><andy.goryachev@oracle.com></a><br>
              <b>Subject: </b>[External] : Aw: Proposal: Add
              Skin.install() method<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:11.0pt">I had a
              similar idea in the past and like the idea.<br>
              Ideally, setting/switching a skin is a one step process.
              Currently you can construct a skin for a control and set
              it after to a different control.<br>
              <br>
              Your approach sounds good, if you can set a skin by
              creating a new skin (with a default constructor) and then
              the setSkin() method will actually trigger the install
              process on the control (this), this will work and solve
              the problem above. But for backward compatibilty we still
              need to keep the skin constructor with the control as
              parameter and think about deprecating it.<br>
              <br>
              -- Marius<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:11.0pt">Am
              20.07.22, 23:40 schrieb Andy Goryachev
              <a class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com"><andy.goryachev@oracle.com></a>:<o:p></o:p></span></p>
          <blockquote style="border:none;border-left:solid #CCCCCC
            1.0pt;padding:0in 0in 0in
            6.0pt;margin-left:4.8pt;margin-top:4.8pt;margin-right:0in">
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Hi,</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">I'd like to propose an API change in
                Skin interface (details below).  Your feedback will be
                greatly appreciated!</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Thank you,</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">-andy</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Summary</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">-------</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Introduce a new Skin.install() method
                with an empty default implementation.  Modify
                Control.setSkin(Skin) implementation to invoke install()
                on the new skin after the old skin has been removed with
                dispose().</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Problem</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">-------</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Presently, switching skins is a
                two-step process: first, a new skin is constructed
                against the target Control instance, and is attached
                (i.s. listeners added, child nodes added) to that
                instance in the constructor.  Then, Control.setSkin() is
                invoked with a new skin - and inside, the old skin is
                detached via its dispose() method.  </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">This creates two problems:</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> 1. if the new skin instance is
                discarded before setSkin(), it remains attached, leaving
                the control in a weird state with two skins attached,
                causing memory leaks and performance degradation.</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> 2. if, in addition to adding listeners
                and child nodes, the skin sets a property, such as an
                event listener, or a handler, it overwrites the current
                value irreversibly.  As a result, either the old skin
                would not be able to cleanly remove itself, or the new
                skin would not be able to set the new values, as it does
                not know whether it should overwrite or keep a handler
                installed earlier (possibly by design).  Unsurprisingly,
                this also might cause memory leaks.</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">We can see the damage caused by looking
                at
                <a href="https://bugs.openjdk.org/browse/JDK-8241364" moz-do-not-send="true">JDK-8241364</a> </span><span style="font-size:11.0pt;font-family:"Apple Color
                Emoji"">☂</span><span style="font-size:11.0pt;font-family:"Courier
                New",serif">
                <i>Cleanup skin implementations to allow switching</i>,
                which refers a number of bugs:</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8245145 Spinner: throws
                IllegalArgumentException when replacing skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8245303 InputMap: memory leak due
                to incomplete cleanup on remove mapping</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8268877 TextInputControlSkin:
                incorrect inputMethod event handler after switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8236840 Memory leak when switching
                ButtonSkin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8240506 TextFieldSkin/Behavior:
                misbehavior on switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8242621 TabPane: Memory leak when
                switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8244657 ChoiceBox/ToolBarSkin:
                misbehavior on switching skin
              </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8245282 Button/Combo Behavior:
                memory leak on dispose</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8246195 ListViewSkin/Behavior:
                misbehavior on switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8246202 ChoiceBoxSkin: misbehavior
                on switching skin, part 2</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8246745 ListCell/Skin: misbehavior
                on switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8247576 Labeled/SkinBase:
                misbehavior on switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8253634 TreeCell/Skin: misbehavior
                on switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8256821 TreeViewSkin/Behavior:
                misbehavior on switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8269081 Tree/ListViewSkin: must
                remove flow on dispose</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8273071 SeparatorSkin: must remove
                child on dispose</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8274061 Tree-/TableRowSkin:
                misbehavior on switching skin</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8244419 TextAreaSkin: throws
                UnsupportedOperation on dispose</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">JDK-8244531 Tests: add support to
                identify recurring issues with controls et al</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Solution</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">--------</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">This problem does not exist in e.g.
                Swing because the steps of instantiation, uninstalling
                the old ComponentUI ("skin"), and installing a new skin
                are cleanly separated.  ComponentUI constructor does not
                alter the component itself,
                ComponentUI.uninstallUI(JComponent) cleanly removes the
                old skin, ComponentUI.installUI(JComponent) installs the
                new skin.  We should follow the same model in javafx.</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Specifically, I'd like to propose the
                following changes:</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> 1. Add Skin.install() with a default
                no-op implementation.</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> 2. Clarify skin
                creation-attachment-detachment sequence in Skin and
                Skin.install() javadoc</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> 3. Modify Control.setSkin(Skin) method
                (== invalidate listener in skin property) to call
                oldSkin.dispose() followed by newSkin.install()</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> 4. Many existing skins that do not set
                properties in the corresponding control may remain
                unchanged.  The skins that do, such as
                TextInputControlSkin (JDK-8268877), must be refactored
                to utilize the new install() method.  I think the
                refactoring would simply move all the code that accesses
                its control instance away from the constructor to
                install().</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">Impact Analysis</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">-------------</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">The changes should be fairly trivial. 
                Only a subset of skins needs to be refactored, and the
                refactoring itself is trivial.  </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">The new API is backwards compatible
                with the existing code, the customer-developed skins can
                remain unchanged (thanks to default implementation).  In
                case where customers could benefit from the new API, the
                change is trivial.</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif">The change will require CSR as it
                modifies a public API.</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier
                New",serif"> </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>