FLEX-35306 Addd unit test. Fails when reverting the fix, passes with the fix.
diff --git a/frameworks/projects/spark/tests/spark/components/List_FLEX_35306_Tests.as b/frameworks/projects/spark/tests/spark/components/List_FLEX_35306_Tests.as
new file mode 100644
index 0000000..1780240
--- /dev/null
+++ b/frameworks/projects/spark/tests/spark/components/List_FLEX_35306_Tests.as
@@ -0,0 +1,274 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.components {
+    import flash.events.Event;
+    import flash.events.EventDispatcher;
+
+    import mx.collections.ArrayCollection;
+    import mx.collections.IList;
+    import mx.core.mx_internal;
+
+    import org.flexunit.asserts.assertEquals;
+    import org.flexunit.asserts.assertFalse;
+    import org.flexunit.asserts.assertNotNull;
+    import org.flexunit.async.Async;
+    import org.flexunit.runners.Parameterized;
+    import org.fluint.uiImpersonation.UIImpersonator;
+
+    import spark.skins.spark.ListSkin;
+
+    use namespace mx_internal;
+
+    [RunWith("org.flexunit.runners.Parameterized")]
+    public class List_FLEX_35306_Tests
+    {
+        private static var foo:Parameterized;
+
+        private static const NO_ENTER_FRAMES_TO_ALLOW:int = 4;
+        private static var noEnterFramesRemaining:int = NaN;
+        private static const _finishNotifier:EventDispatcher = new EventDispatcher();
+
+        private static var _sut:_ListWithMXMLBinding;
+
+        private static var _hqRedmond:_HeadquarterVO;
+        private static var _hqSantaClara:_HeadquarterVO;
+        private static var _hqBerlin:_HeadquarterVO;
+        private static var _hqMunchen:_HeadquarterVO;
+        private static var _hqNewYork:_HeadquarterVO;
+        private static var _hqSantaMaria:_HeadquarterVO;
+        private static var _hqSantaDolores:_HeadquarterVO;
+
+        [Bindable]
+        public var selectedCompany:_CompanyVO;
+        [Bindable]
+        public var potentialHeadquarters:IList;
+
+        public static var models:Array;
+        {
+            models = [[createListOfCompaniesWithOnePotentialAddressEach()], [createListOfCompaniesWithMultiplePotentialAddresses()]];
+        }
+
+        [AfterClass]
+        public static function tearDownStatic():void
+        {
+            models = null;
+        }
+
+        [Before]
+        public function setUp():void
+        {
+            _sut = new _ListWithMXMLBinding();
+            _sut.container = this;
+            _sut.setStyle("skinClass", ListSkin);
+            _sut.requireSelection = true;
+        }
+
+        [After]
+        public function tearDown():void
+        {
+            UIImpersonator.removeAllChildren();
+            _sut = null;
+        }
+
+        [Test(order=2, async, timeout=1000, dataProvider="models", description="this should run after the main test because it rewrites the model")]
+        public function test_double_binding(companies:IList):void
+        {
+            //given
+            const firstCompany:_CompanyVO = companies.getItemAt(0) as _CompanyVO;
+            const secondCompany:_CompanyVO = companies.getItemAt(1) as _CompanyVO;
+            const secondCompanyHQ:_HeadquarterVO = secondCompany.originalHeadquarter;
+            selectedCompany = firstCompany;
+
+            UIImpersonator.addElement(_sut);
+
+            //when 1
+            selectedCompany = secondCompany;
+            potentialHeadquarters = secondCompany.potentialHeadquarters;
+
+            //then 1 - wait some frames until there's a selection
+            noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW;
+            UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame);
+            Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_check_binding_from_bindable_var_to_list, 400, {companies:companies, expectedHQ:secondCompanyHQ});
+        }
+
+        private function then_check_binding_from_bindable_var_to_list(event:Event, passThroughData:Object):void
+        {
+            //given
+            const companies:IList = passThroughData.companies;
+            const expectedHQ:_HeadquarterVO = passThroughData.expectedHQ as _HeadquarterVO;
+            const thirdCompany:_CompanyVO = companies.getItemAt(2) as _CompanyVO;
+
+            //then
+            assertEquals("The list's selected item didn't change (correctly?) when we changed the associated bindable variable!", expectedHQ, _sut.selectedItem);
+
+            //given 2
+            var extraHQ:_HeadquarterVO = new _HeadquarterVO("hello", "address");
+
+            //when 2
+            thirdCompany.potentialHeadquarters.addItem(extraHQ);
+            potentialHeadquarters = thirdCompany.potentialHeadquarters;
+            selectedCompany = thirdCompany;
+            _sut.selectedItem = extraHQ;
+
+            //then 2 - wait some frames until there's a selection
+            noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW;
+            UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame);
+            Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_check_binding_from_list_to_bindable_var, 400, {companies:companies, expectedHQ:extraHQ});
+        }
+
+        private function then_check_binding_from_list_to_bindable_var(event:Event, passThroughData:Object):void
+        {
+            //given
+            const companies:IList = passThroughData.companies as IList;
+            const expectedHQ:_HeadquarterVO = passThroughData.expectedHQ as _HeadquarterVO;
+
+            //then 2
+            assertEquals("The binding destination didn't change (correctly?) when we changed the list's selectedItem!", expectedHQ, selectedCompany.headquarter);
+
+            //cleanup
+            const thirdCompany:_CompanyVO = companies.getItemAt(2) as _CompanyVO;
+            thirdCompany.potentialHeadquarters.removeItem(expectedHQ);
+        }
+
+
+
+
+
+        [Test(order=1, async, timeout=1000, dataProvider="models")]
+        public function test_list_doesnt_rewrite_model(companies:IList):void
+        {
+            //given
+            const secondCompany:_CompanyVO = companies.getItemAt(1) as _CompanyVO;
+
+            //when
+            selectedCompany = secondCompany;
+            potentialHeadquarters = secondCompany.potentialHeadquarters;
+
+            UIImpersonator.addElement(_sut);
+
+            //then - wait some frames until there's a selection
+            noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW;
+            UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame);
+            Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_change_dp_and_selected_item, 400, companies);
+        }
+
+        private function then_change_dp_and_selected_item(event:Event, passThroughData:Object):void
+        {
+            //given
+            const model:IList = passThroughData as IList;
+            const secondCompany:_CompanyVO = model.getItemAt(1) as _CompanyVO;
+            const thirdCompany:_CompanyVO = model.getItemAt(2) as _CompanyVO;
+
+            //then
+            assertNotNull(secondCompany.headquarter); //HUH?
+            assertEquals("The selection should be " + secondCompany.headquarter.name + "!", secondCompany.originalHeadquarter, _sut.selectedItem);
+
+            //when
+            selectedCompany = thirdCompany;
+            potentialHeadquarters = thirdCompany.potentialHeadquarters;
+
+            //then - wait some frames until the selection has changed
+            noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW;
+            UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame);
+            Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_check_if_model_has_been_rewritten, 400, model);
+        }
+
+        private static function then_check_if_model_has_been_rewritten(event:Event, passThroughData:Object):void
+        {
+            //given
+            const model:IList = passThroughData as IList;
+            const thirdCompany:_CompanyVO = model.getItemAt(2) as _CompanyVO;
+            const expectedHQ:_HeadquarterVO = thirdCompany.originalHeadquarter;
+
+            //then
+            assertEquals("The selection should be " + expectedHQ.name + "!", expectedHQ, _sut.selectedItem);
+
+            assertCompaniesHaveCorrectHQ(model);
+            assertNoCompanyHQWasRewritten(model);
+        }
+
+        private static function assertCompaniesHaveCorrectHQ(companiesList:IList):void
+        {
+            for each(var company:_CompanyVO in companiesList)
+            {
+                assertEquals("The headquarter of " + company.name + " has been changed to an invalid value!", company.originalHeadquarter, company.headquarter);
+            }
+        }
+
+        private static function assertNoCompanyHQWasRewritten(companiesList:IList):void
+        {
+            for each(var company:_CompanyVO in companiesList)
+            {
+                assertFalse("The headquarter of " + company.name + " has been rewritten, although with the correct value in the end", company.headquarterRewritten);
+            }
+        }
+
+        private static function onEnterFrame(event:Event):void
+        {
+            if(!--noEnterFramesRemaining)
+            {
+                UIImpersonator.testDisplay.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
+                _finishNotifier.dispatchEvent(new Event(Event.COMPLETE));
+            }
+        }
+
+        //--------------------------------------------------------------------------
+        //
+        //  Set up methods
+        //
+        //--------------------------------------------------------------------------
+
+        private static function createListOfCompaniesWithMultiplePotentialAddresses():IList
+        {
+            createHeadquartersIfNeeded();
+
+            var microsoft:_CompanyVO = new _CompanyVO("Microsoft", _hqRedmond, new ArrayCollection([_hqRedmond, _hqNewYork]));
+            var intel:_CompanyVO = new _CompanyVO("Intel", _hqSantaClara, new ArrayCollection([_hqSantaClara, _hqSantaMaria, _hqSantaDolores]));
+            var wv:_CompanyVO = new _CompanyVO("VW", _hqBerlin, new ArrayCollection([_hqBerlin, _hqMunchen]));
+
+            return new ArrayCollection([microsoft, intel, wv]);
+        }
+
+        private static function createListOfCompaniesWithOnePotentialAddressEach():IList
+        {
+            createHeadquartersIfNeeded();
+
+            var microsoft:_CompanyVO = new _CompanyVO("Microsoft", _hqRedmond, new ArrayCollection([_hqRedmond]));
+            var intel:_CompanyVO = new _CompanyVO("Intel", _hqSantaClara, new ArrayCollection([_hqSantaClara]));
+            var wv:_CompanyVO = new _CompanyVO("VW", _hqBerlin, new ArrayCollection([_hqBerlin]));
+
+            return new ArrayCollection([microsoft, intel, wv]);
+        }
+
+        private static function createHeadquartersIfNeeded():void
+        {
+            if(_hqRedmond)
+                return;
+
+            _hqRedmond = new _HeadquarterVO("Redmond", "redmond address 123");
+            _hqNewYork = new _HeadquarterVO("New York", "NY address 123");
+            _hqSantaClara = new _HeadquarterVO("Santa Clara", "santa clara address 123");
+            _hqSantaMaria = new _HeadquarterVO("Santa Maria", "santa maria address 123");
+            _hqSantaDolores = new _HeadquarterVO("Santa Dolores", "santa dolores address 123");
+            _hqBerlin = new _HeadquarterVO("Berlin", "berlin address 123");
+            _hqMunchen = new _HeadquarterVO("Munchen", "munchen address 123");
+        }
+    }
+}
\ No newline at end of file
diff --git a/frameworks/projects/spark/tests/spark/components/_CompanyVO.as b/frameworks/projects/spark/tests/spark/components/_CompanyVO.as
new file mode 100644
index 0000000..3889c62
--- /dev/null
+++ b/frameworks/projects/spark/tests/spark/components/_CompanyVO.as
@@ -0,0 +1,49 @@
+package spark.components {
+    import mx.collections.ArrayCollection;
+
+    [Bindable]
+    public class _CompanyVO
+    {
+        private var _headquarter:_HeadquarterVO;
+        private var _headquarterRewritten:Boolean = false;
+        private var _originalHeadquarter:_HeadquarterVO;
+
+        public var name:String;
+        public var potentialHeadquarters:ArrayCollection;
+
+
+        public function _CompanyVO(name:String, headquarter:_HeadquarterVO, potentialHeadquarters:ArrayCollection)
+        {
+            this.name = name;
+            this._headquarter = headquarter;
+            this._originalHeadquarter = headquarter;
+            this.potentialHeadquarters = potentialHeadquarters;
+        }
+
+        public function get headquarter():_HeadquarterVO
+        {
+            return _headquarter;
+        }
+
+        public function set headquarter(value:_HeadquarterVO):void
+        {
+            _headquarterRewritten = true;
+            _headquarter = value;
+        }
+
+        public function get headquarterRewritten():Boolean
+        {
+            return _headquarterRewritten;
+        }
+
+        public function get originalHeadquarter():_HeadquarterVO
+        {
+            return _originalHeadquarter;
+        }
+
+        public function toString():String
+        {
+            return "CompanyVO{name=" + String(name) + ", #hqs="+potentialHeadquarters.length+"}";
+        }
+    }
+}
diff --git a/frameworks/projects/spark/tests/spark/components/_HeadquarterVO.as b/frameworks/projects/spark/tests/spark/components/_HeadquarterVO.as
new file mode 100644
index 0000000..b41d129
--- /dev/null
+++ b/frameworks/projects/spark/tests/spark/components/_HeadquarterVO.as
@@ -0,0 +1,23 @@
+package spark.components {
+    [Bindable]
+    public class _HeadquarterVO {
+        public var name:String;
+        public var address:String;
+
+        public function _HeadquarterVO(name:String, address:String)
+        {
+            this.name = name;
+            this.address = address;
+        }
+
+        public function get label():String
+        {
+            return name;
+        }
+
+        public function toString():String
+        {
+            return "HeadquarterVO{name=" + String(name) + "}";
+        }
+    }
+}
diff --git a/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml b/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml
new file mode 100644
index 0000000..3e65389
--- /dev/null
+++ b/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<s:List xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
+    selectedItem="@{container.selectedCompany.headquarter}"
+    dataProvider="{container.potentialHeadquarters}">
+
+    <fx:Script>
+        <![CDATA[
+        private var _container:Object;
+
+        [Bindable]
+        public function get container():Object
+        {
+            return _container;
+        }
+
+        public function set container(value:Object):void
+        {
+            _container = value;
+        }
+        ]]>
+    </fx:Script>
+</s:List>