<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    I don't know if you really meant Error, as in java.lang.Error, but
    it would need to be a subclass of RuntimeException.
    IllegalArgumentException seems the natural choice (a case could
    possibly be made for IllegalStateException). Throwing an Error is
    not the right thing for a library to do in response to an
    application passing in an illegal or unexpected argument to a method
    or constructor. It is for truly exceptional things that a programmer
    cannot anticipate (like running out of memory).<br>
    <br>
    -- Kevin<br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 7/22/2022 12:37 PM, Andy Goryachev
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:BL0PR10MB2948B6AB77BDF2EBD61E4BFFE5909@BL0PR10MB2948.namprd10.prod.outlook.com">
      
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style>@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;}@font-face
        {font-family:"Courier New \,serif";
        panose-1:2 7 3 9 2 2 5 2 4 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.EmailStyle20
        {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">I would rather throw an Error in
            Skinnable.setSkin() when mismatch is detected.  This is a
            design error that should be caught early in development
            rather than a run time exception.<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">-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">openjfx-dev
              <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev-retn@openjdk.org"><openjfx-dev-retn@openjdk.org></a> on behalf of Kevin
              Rushforth <a class="moz-txt-link-rfc2396E" href="mailto:kevin.rushforth@oracle.com"><kevin.rushforth@oracle.com></a><br>
              <b>Date: </b>Friday, 2022/07/22 at 12:33<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><br>
              <b>Subject: </b>Re: [External] : Aw: Proposal: Add
              Skin.install() method<o:p></o:p></span></p>
        </div>
        <p class="MsoNormal"><span style="font-size:11.0pt">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>
            <br>
            <o:p></o:p></span></p>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><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><span style="font-size:11.0pt"><o:p></o:p></span></p>
        </blockquote>
        <p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:11.0pt"><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>
          </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
        <div>
          <p class="MsoNormal"><span style="font-size:11.0pt">On
              7/22/2022 9:13 AM, Andy Goryachev wrote:<o:p></o:p></span></p>
        </div>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <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. 
            </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif""> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif"">I think Swing got it right, clearly
              separating</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif""> </span><o:p></o:p></p>
          <ol style="margin-top:0in" type="1" start="1">
            <li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3"><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)</span><o:p></o:p></li>
            <li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3"><span style="font-size:11.0pt;font-family:"Courier New
                \,serif"">configuration (optional step, possibly
                widely separated in time and space)</span><o:p></o:p></li>
            <li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3"><span style="font-size:11.0pt;font-family:"Courier New
                \,serif"">uninstallation of the old skin</span><o:p></o:p></li>
            <li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3"><span style="font-size:11.0pt;font-family:"Courier New
                \,serif"">installation of the new skin</span><o:p></o:p></li>
          </ol>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif""> </span><o:p></o:p></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.  </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif""> </span><o:p></o:p></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().</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif""> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif"">Thank you</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif"">-andy</span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif""> </span><o:p></o:p></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
              \,serif""> </span><o:p></o:p></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 href="mailto:mariushanl@web.de" moz-do-not-send="true">
                  <mariushanl@web.de></a><br>
                <b>Date: </b>Friday, 2022/07/22 at 05:06<br>
                <b>To: </b><a href="mailto:openjfx-dev@openjdk.org" moz-do-not-send="true" class="moz-txt-link-freetext">openjfx-dev@openjdk.org</a>
                <a href="mailto:openjfx-dev@openjdk.org" moz-do-not-send="true">
                  <openjfx-dev@openjdk.org></a>, Andy Goryachev <a href="mailto:andy.goryachev@oracle.com" moz-do-not-send="true">
                  <andy.goryachev@oracle.com></a><br>
                <b>Subject: </b>[External] : Aw: Proposal: Add
                Skin.install() method</span><o:p></o:p></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</span><o:p></o:p></p>
          </div>
          <div>
            <p class="MsoNormal"><span style="font-size:11.0pt">Am
                20.07.22, 23:40 schrieb Andy Goryachev
                <a href="mailto:andy.goryachev@oracle.com" moz-do-not-send="true"><andy.goryachev@oracle.com></a>:</span><o:p></o:p></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;margin-bottom:5.0pt">
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">Hi,</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">Thank you,</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">-andy</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">Summary</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">-------</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">Problem</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">-------</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">This creates two problems:</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8245145 Spinner: throws
                  IllegalArgumentException when replacing skin</span><o:p></o:p></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><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8236840 Memory leak when switching
                  ButtonSkin</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8240506 TextFieldSkin/Behavior:
                  misbehavior on switching skin</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8242621 TabPane: Memory leak when
                  switching skin</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8244657 ChoiceBox/ToolBarSkin:
                  misbehavior on switching skin
                </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8246195 ListViewSkin/Behavior:
                  misbehavior on switching skin</span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8246745 ListCell/Skin: misbehavior
                  on switching skin</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8247576 Labeled/SkinBase:
                  misbehavior on switching skin</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8253634 TreeCell/Skin: misbehavior
                  on switching skin</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8256821 TreeViewSkin/Behavior:
                  misbehavior on switching skin</span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8273071 SeparatorSkin: must remove
                  child on dispose</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8274061 Tree-/TableRowSkin:
                  misbehavior on switching skin</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">JDK-8244419 TextAreaSkin: throws
                  UnsupportedOperation on dispose</span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">Solution</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">--------</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></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><o:p></o:p></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><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">Impact Analysis</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif"">-------------</span><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></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><o:p></o:p></p>
              <p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Courier New
                  \,serif""> </span><o:p></o:p></p>
            </blockquote>
          </div>
        </blockquote>
        <p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
      </div>
    </blockquote>
    <br>
  </body>
</html>