Merge branch 'devel/master' into devel/new_mesh 13/42313/3
authorFrancisco Santos <f1.santos@samsung.com>
Thu, 25 Jun 2015 14:23:06 +0000 (15:23 +0100)
committerFrancisco Santos <f1.santos@samsung.com>
Fri, 26 Jun 2015 12:55:46 +0000 (13:55 +0100)
Conflicts:
automated-tests/src/dali-toolkit/CMakeLists.txt
dali-toolkit/devel-api/shader-effects/distance-field-effect.cpp
dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp
dali-toolkit/internal/atlas-manager/atlas-manager-impl.h
dali-toolkit/internal/atlas-manager/atlas-manager.cpp
dali-toolkit/internal/atlas-manager/atlas-manager.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/public-api/controls/control-impl.cpp

Change-Id: I48b90c6c4696dbc7b65659ecf6004a09a17c7ab0

30 files changed:
1  2 
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-BubbleEmitter.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
build/tizen/configure.ac
build/tizen/dali-toolkit/Makefile.am
dali-toolkit/devel-api/file.list
dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp
dali-toolkit/internal/atlas-manager/atlas-manager-impl.h
dali-toolkit/internal/atlas-manager/atlas-manager.cpp
dali-toolkit/internal/atlas-manager/atlas-manager.h
dali-toolkit/internal/builder/builder-animations.cpp
dali-toolkit/internal/builder/builder-impl.cpp
dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/slider/slider-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h

@@@ -8,40 -8,59 +8,42 @@@ SET(CAPI_LIB "dali-toolkit"
  # List of test case sources (Only these get parsed for test cases)
  SET(TC_SOURCES
     utc-Dali-Alignment.cpp
 -   utc-Dali-BendyEffect.cpp
 -   utc-Dali-BlindEffect.cpp
     utc-Dali-BloomView.cpp
     utc-Dali-BubbleEmitter.cpp
     utc-Dali-Builder.cpp
 -   utc-Dali-CarouselEffect.cpp
     utc-Dali-CheckBoxButton.cpp
     utc-Dali-CubeTransitionEffect.cpp
 -   utc-Dali-DisplacementEffect.cpp
 -   utc-Dali-DistanceFieldEffect.cpp
+    utc-Dali-EffectsView.cpp
     utc-Dali-GaussianBlurView.cpp
     utc-Dali-JsonParser.cpp
     utc-Dali-KeyInputFocusManager.cpp
 -   utc-Dali-OverlayEffect.cpp
 -   utc-Dali-PageTurnEffect.cpp
     utc-Dali-PageTurnView.cpp
     utc-Dali-ScrollBar.cpp
     utc-Dali-ScrollView.cpp
 +   utc-Dali-ShaderEffects.cpp
     utc-Dali-ShadowView.cpp
 -   utc-Dali-ShearEffect.cpp
     utc-Dali-Slider.cpp
 -   utc-Dali-SoftButtonEffect.cpp
 -   utc-Dali-SpotEffect.cpp
 -   utc-Dali-SquareDissolveEffect.cpp
     utc-Dali-TableView.cpp
     utc-Dali-TextField.cpp
     utc-Dali-TextLabel.cpp
     utc-Dali-TextSelectionPopup.cpp
     utc-Dali-ToolBar.cpp
 -   utc-Dali-WaterEffect.cpp
     utc-Dali-Button.cpp
     utc-Dali-Control.cpp
     utc-Dali-ControlImpl.cpp
     utc-Dali-DefaultControls.cpp
 -   utc-Dali-DissolveEffect.cpp
     utc-Dali-AccessibilityFocusManager.cpp
 -   utc-Dali-IrisEffect.cpp
     utc-Dali-ItemLayout.cpp
     utc-Dali-ItemView.cpp
     utc-Dali-KeyboardFocusManager.cpp
 -   utc-Dali-MaskEffect.cpp
+    utc-Dali-Magnifier.cpp
     utc-Dali-NinePatchMaskEffect.cpp
     utc-Dali-Popup.cpp
     utc-Dali-PushButton.cpp
     utc-Dali-RadioButton.cpp
 -   utc-Dali-Ripple2DEffect.cpp
 -   utc-Dali-RippleEffect.cpp
     utc-Dali-ScrollViewEffect.cpp
     utc-Dali-StyleManager.cpp
     utc-Dali-SuperBlurView.cpp
 -   utc-Dali-SwirlEffect.cpp
  )
  
  # Append list of test harness files (Won't get parsed for test cases)
@@@ -23,8 -23,9 +23,8 @@@
  #include <dali-toolkit-test-suite-utils.h>
  
  #include <dali.h>
 +#include <dali/devel-api/rendering/renderer.h>
  #include <dali-toolkit/dali-toolkit.h>
 -#include <dali/devel-api/actors/mesh-actor.h>
 -#include <dali/devel-api/modeling/material.h>
  #include <dali-toolkit/devel-api/controls/bubble-effect/bubble-emitter.h>
  
  using namespace Dali;
@@@ -140,40 -141,13 +140,40 @@@ int UtcDaliBubbleEmitterNew(void
    END_TEST;
  }
  
 +int UtcDaliBubbleEmitterDownCast01(void)
 +{
 +  ToolkitTestApplication application;
 +
 +  tet_infoline(" UtcDaliBubbleEmitterDownCast01 ");
 +
 +  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 +  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
 +
 +  BaseHandle handle(emitter);
 +  BubbleEmitter emitter2 = BubbleEmitter::DownCast(handle);
 +  DALI_TEST_EQUALS( (bool)emitter2, true, TEST_LOCATION );
 +  END_TEST;
 +}
 +
 +int UtcDaliBubbleEmitterDownCast02(void)
 +{
 +  ToolkitTestApplication application;
 +
 +  tet_infoline(" UtcDaliBubbleEmitterDownCast02 ");
 +
 +  Handle handle = Handle::New(); // Create a custom object
 +  BubbleEmitter emitter = BubbleEmitter::DownCast(handle);
 +  DALI_TEST_EQUALS( (bool)emitter, false, TEST_LOCATION );
 +  END_TEST;
 +}
 +
  int UtcDaliBubbleEmitterGetRootActor(void)
  {
    ToolkitTestApplication application;
    tet_infoline( " UtcDaliBubbleEmitterGetRootActor " );
  
    Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
 +  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 270, Vector2( 5.f, 10.f ));
  
    Actor root = emitter.GetRootActor();
    DALI_TEST_CHECK( root );
@@@ -202,39 -176,56 +202,44 @@@ int UtcDaliBubbleEmitterSetBackground(v
    END_TEST;
  }
  
 -int UtcDaliBubbleEmitterSetShapeImage(void)
 +//TODO: test case for BubbleEmitter::SetShapeImage(Image)
 +// To test that the bubble-shape image is successfully switched in the sampler
 +/*int UtcDaliBubbleEmitterSetShapeImage(void)
  {
 -  ToolkitTestApplication application;
 -  tet_infoline( " UtcDaliBubbleEmitterSetShapeImage " );
 -
 -  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 -
 -  Actor root = emitter.GetRootActor();
 -  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
 -  Material material = bubbleMesh.GetMaterial();
 -
 -  DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage1 );
 -
 -  Image shapeImage2 = CreateSolidColorImage( application, Color::RED, 8, 8 );
 -  emitter.SetShapeImage( shapeImage2 );
 -
 -  DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage2 );
 -  END_TEST;
 -}
 +}*/
  
  int UtcDaliBubbleEmitterSetBubbleScale(void)
  {
    ToolkitTestApplication application;
    tet_infoline( " UtcDaliBubbleEmitterSetBubbleScale " );
  
 -  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 -
 +  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 +  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
++  DALI_TEST_CHECK(emitter);
    Actor root = emitter.GetRootActor();
 -  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
 -  ShaderEffect effect = bubbleMesh.GetShaderEffect();
 -  DALI_TEST_CHECK( effect );
 +  Stage::GetCurrent().Add( root );
++  root.SetPosition( Vector3::ZERO );
++  root.SetParentOrigin( ParentOrigin::CENTER );
++  root.SetAnchorPoint( AnchorPoint::CENTER );
 +
 +  TestGlAbstraction& gl = application.GetGlAbstraction();
 +
 +  Wait(application);
  
 -  Property::Index scalePropertyIndex = effect.GetPropertyIndex( "uDynamicScale" );
    float scaleValue;
 -  (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
 -  DALI_TEST_EQUALS(scaleValue, 1.f, TEST_LOCATION );
 +  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
 +  DALI_TEST_EQUALS( scaleValue, 1.f, TEST_LOCATION );
  
    emitter.SetBubbleScale( 2.f );
 -  application.SendNotification();
 -  application.Render();
 -  (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
 -  DALI_TEST_EQUALS(scaleValue, 2.f, TEST_LOCATION );
 +  Wait(application);
 +  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
 +  DALI_TEST_EQUALS( scaleValue, 2.f, TEST_LOCATION );
  
    emitter.SetBubbleScale( 0.5f );
 -  application.SendNotification();
 -  application.Render();
 -  (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
 -  DALI_TEST_EQUALS(scaleValue, 0.5f, TEST_LOCATION );
 +  Wait(application);
 +  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
 +  DALI_TEST_EQUALS( scaleValue, 0.5f, TEST_LOCATION );
++
    END_TEST;
  }
  
@@@ -243,8 -234,8 +248,8 @@@ int UtcDaliBubbleEmitterSetBubbleDensit
    ToolkitTestApplication application;
    tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
  
 -  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 +  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 +  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
  
    try
    {
@@@ -264,8 -255,8 +269,8 @@@ int UtcDaliBubbleEmitterSetBubbleDensit
    ToolkitTestApplication application;
    tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
  
 -  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 +  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 +  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
  
    try
    {
@@@ -284,32 -275,27 +289,36 @@@ int UtcDaliBubbleEmitterSetBlendMode(vo
    ToolkitTestApplication application;
    tet_infoline( " UtcDaliBubbleEmitterSetBlendMode " );
  
 -  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 -
 +  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 +  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
++  DALI_TEST_CHECK(emitter);
    Actor root = emitter.GetRootActor();
 -  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
 -
 -  BlendingFactor::Type srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha;
 +  Stage::GetCurrent().Add( root );
++  root.SetPosition( Vector3::ZERO );
++  root.SetParentOrigin( ParentOrigin::CENTER );
++  root.SetAnchorPoint( AnchorPoint::CENTER );
 +
 +  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
 +  Wait(application);
 +  DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
  
    emitter.SetBlendMode( true );
 -  bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
 -  DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
 -  DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE );
 -  DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ZERO );
 -  DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE );
 +  Wait(application);
 +  DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ZERO, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
  
    emitter.SetBlendMode( false );
 -  bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
 -  DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
 -  DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
 -  DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
 -  DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE_MINUS_SRC_ALPHA );
 +  Wait(application);
 +  DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
 +  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
 +
    END_TEST;
  }
  
@@@ -322,90 -308,103 +331,94 @@@ int UtcDaliBubbleEmitterEmitBubble(void
    BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
  
    Actor root = emitter.GetRootActor();
 -  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
 -  ShaderEffect effect = bubbleMesh.GetShaderEffect();
 -  DALI_TEST_CHECK( effect );
 +  Actor bubbleMesh = root.GetChildAt( 0 );
 +  Stage::GetCurrent().Add( root );
 +  DALI_TEST_CHECK( bubbleMesh );
  
 -  Property::Index propertyIndex0 = effect.GetPropertyIndex( "uPercentage[0]" );
 -  Property::Index propertyIndex1 = effect.GetPropertyIndex( "uPercentage[1]" );
 +  Property::Index propertyIndex0 = bubbleMesh.GetPropertyIndex( "uPercentage[0]" );
 +  Property::Index propertyIndex1 = bubbleMesh.GetPropertyIndex( "uPercentage[1]" );
    float value0, value1;
  
    Animation animation = Animation::New( 0.5f );
    emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
    emitter.EmitBubble( animation, Vector2(10.f,10.f), Vector2(5.f,5.f), Vector2(30.f,30.f) );
 -  (effect.GetProperty(propertyIndex0)).Get( value0 );
 -  (effect.GetProperty(propertyIndex1)).Get( value1 );
 +  (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
 +  (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
    DALI_TEST_EQUALS(value0, 0.f, TEST_LOCATION );
    DALI_TEST_EQUALS(value1, 0.f, TEST_LOCATION );
  
    animation.Play();
  
    Wait(application, 300);
 -  (effect.GetProperty(propertyIndex0)).Get( value0 );
 -  (effect.GetProperty(propertyIndex1)).Get( value1 );
 +  propertyIndex0 = bubbleMesh.GetPropertyIndex( "uPercentage[0]" );
 +  propertyIndex1 = bubbleMesh.GetPropertyIndex( "uPercentage[1]" );
 +  (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
 +  (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
    DALI_TEST_CHECK( value0 >= 0.6f );
    DALI_TEST_CHECK( value1 >= 0.6f );
  
 -  Wait(application, 600);
 -  (effect.GetProperty(propertyIndex0)).Get( value0 );
 -  (effect.GetProperty(propertyIndex1)).Get( value1 );
 +  Wait(application,500);
 +  (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
 +  (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
    DALI_TEST_EQUALS(value0, 1.f, TEST_LOCATION );
    DALI_TEST_EQUALS(value1, 1.f, TEST_LOCATION );
    END_TEST;
  }
  
 -int UtcDaliBubbleEmitterStartExplosion(void)
 +int UtcDaliBubbleEmitterRestore(void)
  {
    ToolkitTestApplication application;
 -  tet_infoline( " UtcDaliBubbleEmitterStartExplosion " );
 +  tet_infoline( " UtcDaliBubbleEmitterRestore " );
  
 -  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 +  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 +  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 90, Vector2( 5.f, 10.f ));
    Actor root = emitter.GetRootActor();
 -  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
 -  ShaderEffect effect = bubbleMesh.GetShaderEffect();
 -  DALI_TEST_CHECK( effect );
 -
 -  Property::Index propertyIndex = effect.GetPropertyIndex( "uMagnification" );
 -  float value;
 -  (effect.GetProperty(propertyIndex)).Get( value );
 -  DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
 -
 -  emitter.StartExplosion( 0.4, 4.f );
 +  Stage::GetCurrent().Add( root );
++  root.SetPosition( Vector3::ZERO );
++  root.SetParentOrigin( ParentOrigin::CENTER );
++  root.SetAnchorPoint( AnchorPoint::CENTER );
  
 -  Wait(application, 200); // 0.2s
 -  (effect.GetProperty(propertyIndex)).Get( value );
 -  DALI_TEST_CHECK( value >= 2.f );
 +  Actor bubbleMesh = root.GetChildAt( 0 );
 +  Renderer renderer = bubbleMesh.GetRendererAt( 0 );
 +  DALI_TEST_CHECK( renderer );
  
 -  Wait(application, 100); // 0.3s
 -  (effect.GetProperty(propertyIndex)).Get( value );
 -  DALI_TEST_CHECK( value >= 3.f );
 +  TestGlAbstraction& gl = application.GetGlAbstraction();
  
 -  Wait(application, 100); // 0.4s
 -  (effect.GetProperty(propertyIndex)).Get( value );
 -  DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
 -  END_TEST;
 -}
 +  float percentageValue;
 +  Vector4 startEndPosValue;
  
 -int UtcDaliBubbleEmitterRestore(void)
 -{
 -  ToolkitTestApplication application;
 -  tet_infoline( " UtcDaliBubbleEmitterRestore " );
 +  Animation animation = Animation::New( 0.5f );
 +  emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
  
 -  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
 -  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 -  Actor root = emitter.GetRootActor();
 -  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
 -  ShaderEffect effect = bubbleMesh.GetShaderEffect();
 -  DALI_TEST_CHECK( effect );
 +  Wait(application);
  
 -  Property::Index percentagePropertyIndex = effect.GetPropertyIndex( "uPercentage[0]" );
 -  float percentage;
 +  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
 +  DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
  
 -  Animation animation = Animation::New( 0.5f );
 -  emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
 -  (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
 -  DALI_TEST_EQUALS(percentage, 0.f, TEST_LOCATION );
 +  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartEndPosition[0]", startEndPosValue ) );
 +  DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
 +  DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
  
    animation.Play();
    Wait(application, 200);
    animation.Clear();
  
 -  (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
 -  DALI_TEST_CHECK( percentage < 0.5f && percentage >= 0.4);
 +  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
 +  DALI_TEST_CHECK( percentageValue < 0.5f && percentageValue >= 0.4);
 +
 +  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartEndPosition[0]", startEndPosValue ) );
 +  DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
 +  DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
  
    emitter.Restore();
    application.SendNotification();
    application.Render();
  
 -  (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
 -  DALI_TEST_EQUALS(percentage, 1.f, TEST_LOCATION );
 +  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
 +  DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
 +
 +  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartEndPosition[0]", startEndPosValue ) );
 +  DALI_TEST_EQUALS( startEndPosValue,  Vector4::ZERO, TEST_LOCATION );
++
    END_TEST;
  }
@@@ -18,6 -18,8 +18,7 @@@
  #include <iostream>
  #include <stdlib.h>
  #include <dali/integration-api/events/key-event-integ.h>
 -#include <dali/devel-api/actors/mesh-actor.h>
+ #include <dali/integration-api/events/tap-gesture-event.h>
  #include <dali-toolkit-test-suite-utils.h>
  #include <dali-toolkit/dali-toolkit.h>
  #include <dali-toolkit/devel-api/styling/style-manager.h>
@@@ -38,22 -40,49 +39,49 @@@ void dali_textfield_cleanup(void
  namespace
  {
  
- const char* const PROPERTY_NAME_RENDERING_BACKEND       = "rendering-backend";
- const char* const PROPERTY_NAME_PLACEHOLDER_TEXT        = "placeholder-text";
- const char* const PROPERTY_NAME_TEXT                    = "text";
- const char* const PROPERTY_NAME_FONT_FAMILY             = "font-family";
- const char* const PROPERTY_NAME_FONT_STYLE              = "font-style";
- const char* const PROPERTY_NAME_POINT_SIZE              = "point-size";
- const char* const PROPERTY_NAME_EXCEED_POLICY           = "exceed-policy";
- const char* const PROPERTY_NAME_PRIMARY_CURSOR_COLOR    = "primary-cursor-color";
- const char* const PROPERTY_NAME_SECONDARY_CURSOR_COLOR  = "secondary-cursor-color";
- const char* const PROPERTY_NAME_ENABLE_CURSOR_BLINK     = "enable-cursor-blink";
- const char* const PROPERTY_NAME_CURSOR_BLINK_INTERVAL   = "cursor-blink-interval";
- const char* const PROPERTY_NAME_CURSOR_BLINK_DURATION   = "cursor-blink-duration";
- const char* const PROPERTY_NAME_GRAB_HANDLE_IMAGE       = "grab-handle-image";
- const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX = "decoration-bounding-box";
- const char* const PROPERTY_NAME_HORIZONTAL_ALIGNMENT    = "horizontal-alignment";
- const char* const PROPERTY_NAME_VERTICAL_ALIGNMENT      = "vertical-alignment";
+ const char* const PROPERTY_NAME_RENDERING_BACKEND                    = "rendering-backend";
+ const char* const PROPERTY_NAME_TEXT                                 = "text";
+ const char* const PROPERTY_NAME_PLACEHOLDER_TEXT                     = "placeholder-text";
+ const char* const PROPERTY_NAME_PLACEHOLDER_TEXT_FOCUSED             = "placeholder-text-focused";
+ const char* const PROPERTY_NAME_FONT_FAMILY                          = "font-family";
+ const char* const PROPERTY_NAME_FONT_STYLE                           = "font-style";
+ const char* const PROPERTY_NAME_POINT_SIZE                           = "point-size";
+ const char* const PROPERTY_NAME_MAX_LENGTH                           = "max-length";
+ const char* const PROPERTY_NAME_EXCEED_POLICY                        = "exceed-policy";
+ const char* const PROPERTY_NAME_HORIZONTAL_ALIGNMENT                 = "horizontal-alignment";
+ const char* const PROPERTY_NAME_VERTICAL_ALIGNMENT                   = "vertical-alignment";
+ const char* const PROPERTY_NAME_TEXT_COLOR                           = "text-color";
+ const char* const PROPERTY_NAME_PLACEHOLDER_TEXT_COLOR               = "placeholder-text-color";
+ const char* const PROPERTY_NAME_SHADOW_OFFSET                        = "shadow-offset";
+ const char* const PROPERTY_NAME_SHADOW_COLOR                         = "shadow-color";
+ const char* const PROPERTY_NAME_PRIMARY_CURSOR_COLOR                 = "primary-cursor-color";
+ const char* const PROPERTY_NAME_SECONDARY_CURSOR_COLOR               = "secondary-cursor-color";
+ const char* const PROPERTY_NAME_ENABLE_CURSOR_BLINK                  = "enable-cursor-blink";
+ const char* const PROPERTY_NAME_CURSOR_BLINK_INTERVAL                = "cursor-blink-interval";
+ const char* const PROPERTY_NAME_CURSOR_BLINK_DURATION                = "cursor-blink-duration";
+ const char* const PROPERTY_NAME_GRAB_HANDLE_IMAGE                    = "grab-handle-image";
+ const char* const PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE            = "grab-handle-pressed-image";
+ const char* const PROPERTY_NAME_SCROLL_THRESHOLD                     = "scroll-threshold";
+ const char* const PROPERTY_NAME_SCROLL_SPEED                         = "scroll-speed";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT          = "selection-handle-image-left";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT         = "selection-handle-image-right";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT  = "selection-handle-pressed-image-left";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT = "selection-handle-pressed-image-right";
+ const char* const PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR            = "selection-highlight-color";
+ const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX              = "decoration-bounding-box";
+ const char* const PROPERTY_NAME_INPUT_METHOD_SETTINGS                = "input-method-settings";
+ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+ const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f );
+ const Dali::Vector4 LIGHT_BLUE( (0xb2 / 255.0f), (0xeb / 255.0f), (0xf2 / 255.0f), 0.5f ); // The text highlight color.
+ const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval
+ const float TO_MILLISECONDS = 1000.f;
+ const float TO_SECONDS = 1.f / TO_MILLISECONDS;
+ const float SCROLL_THRESHOLD = 10.f;
+ const float SCROLL_SPEED = 300.f;
  
  static bool gTextChangedCallBackCalled;
  static bool gMaxCharactersCallBackCalled;
@@@ -72,6 -101,38 +100,38 @@@ static void TestMaxLengthReachedCallbac
    gMaxCharactersCallBackCalled = true;
  }
  
+ // Generate a TapGestureEvent to send to Core.
+ Integration::TapGestureEvent GenerateTap(
+     Gesture::State state,
+     unsigned int numberOfTaps,
+     unsigned int numberOfTouches,
+     Vector2 point)
+ {
+   Integration::TapGestureEvent tap( state );
+   tap.numberOfTaps = numberOfTaps;
+   tap.numberOfTouches = numberOfTouches;
+   tap.point = point;
+   return tap;
+ }
+ // Generate a KeyEvent to send to Core.
+ Integration::KeyEvent GenerateKey( const std::string& keyName,
+                                    const std::string& keyString,
+                                    int keyCode,
+                                    int keyModifier,
+                                    unsigned long timeStamp,
+                                    const Integration::KeyEvent::State& keyState )
+ {
+   return Integration::KeyEvent( keyName,
+                                 keyString,
+                                 keyCode,
+                                 keyModifier,
+                                 timeStamp,
+                                 keyState );
+ }
  } // namespace
  
  int UtcDaliToolkitTextFieldConstructorP(void)
@@@ -155,33 -216,6 +215,6 @@@ int UtcDaliTextFieldNewP(void
    END_TEST;
  }
  
- int UtcDaliTextFieldGetPropertyN(void)
- {
-   ToolkitTestApplication application;
-   tet_infoline(" UtcDaliToolkitTextFieldGetPropertyN");
-   TextField field = TextField::New();
-   DALI_TEST_CHECK( field );
-   bool assert = false;
-   try
-   {
-     Property::Value value = field.GetProperty<bool>( 0 );
-   }
-   catch ( ... )
-   {
-     assert = true;
-   }
-   if ( assert )
-   {
-     tet_result(TET_PASS);
-   }
-   else
-   {
-     tet_result(TET_FAIL);
-   }
-   END_TEST;
- }
  // Positive test case for a method
  int UtcDaliTextFieldGetPropertyP(void)
  {
  
    // Check Property Indices are correct
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_RENDERING_BACKEND ) == TextField::Property::RENDERING_BACKEND );
-   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT ) == TextField::Property::PLACEHOLDER_TEXT );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_TEXT ) == TextField::Property::TEXT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT ) == TextField::Property::PLACEHOLDER_TEXT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT_FOCUSED ) == TextField::Property::PLACEHOLDER_TEXT_FOCUSED );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_FONT_FAMILY ) == TextField::Property::FONT_FAMILY );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_FONT_STYLE ) == TextField::Property::FONT_STYLE );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_POINT_SIZE ) == TextField::Property::POINT_SIZE );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_MAX_LENGTH ) == TextField::Property::MAX_LENGTH );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_EXCEED_POLICY ) == TextField::Property::EXCEED_POLICY );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_HORIZONTAL_ALIGNMENT ) == TextField::Property::HORIZONTAL_ALIGNMENT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_VERTICAL_ALIGNMENT ) == TextField::Property::VERTICAL_ALIGNMENT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_TEXT_COLOR ) == TextField::Property::TEXT_COLOR );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT_COLOR ) == TextField::Property::PLACEHOLDER_TEXT_COLOR );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SHADOW_OFFSET ) == TextField::Property::SHADOW_OFFSET );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SHADOW_COLOR ) == TextField::Property::SHADOW_COLOR );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PRIMARY_CURSOR_COLOR ) == TextField::Property::PRIMARY_CURSOR_COLOR );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SECONDARY_CURSOR_COLOR ) == TextField::Property::SECONDARY_CURSOR_COLOR );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_CURSOR_BLINK ) == TextField::Property::ENABLE_CURSOR_BLINK );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_INTERVAL ) == TextField::Property::CURSOR_BLINK_INTERVAL );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_DURATION ) == TextField::Property::CURSOR_BLINK_DURATION );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_IMAGE ) == TextField::Property::GRAB_HANDLE_IMAGE );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE ) == TextField::Property::GRAB_HANDLE_PRESSED_IMAGE );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SCROLL_THRESHOLD ) == TextField::Property::SCROLL_THRESHOLD );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SCROLL_SPEED ) == TextField::Property::SCROLL_SPEED );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT ) == TextField::Property::SELECTION_HANDLE_IMAGE_LEFT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT ) == TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT ) == TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT ) == TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR ) == TextField::Property::SELECTION_HIGHLIGHT_COLOR );
    DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_DECORATION_BOUNDING_BOX ) == TextField::Property::DECORATION_BOUNDING_BOX );
-   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_HORIZONTAL_ALIGNMENT ) == TextField::Property::HORIZONTAL_ALIGNMENT );
-   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_VERTICAL_ALIGNMENT ) == TextField::Property::VERTICAL_ALIGNMENT );
+   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_METHOD_SETTINGS ) == TextField::Property::INPUT_METHOD_SETTINGS );
    END_TEST;
  }
  
@@@ -218,76 -267,123 +266,123 @@@ int UtcDaliTextFieldSetPropertyP(void
    TextField field = TextField::New();
    DALI_TEST_CHECK( field );
  
-   // Check exceed policy
-   field.SetProperty( TextField::Property::EXCEED_POLICY, TextField::EXCEED_POLICY_CLIP );
+   // Check defaults.
+   DALI_TEST_EQUALS( field.GetProperty<unsigned int>( TextField::Property::RENDERING_BACKEND ), DEFAULT_RENDERING_BACKEND, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string(""), TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT ), std::string(""), TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT_FOCUSED ), std::string(""), TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_FAMILY ), std::string(""), TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_STYLE ), std::string(""), TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::POINT_SIZE ), 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<int>( TextField::Property::MAX_LENGTH ), 50u, TEST_LOCATION );
    DALI_TEST_EQUALS( field.GetProperty<int>( TextField::Property::EXCEED_POLICY ), TextField::EXCEED_POLICY_CLIP, TEST_LOCATION );
-   // Check cursor properties
-   field.SetProperty( TextField::Property::ENABLE_CURSOR_BLINK, true );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::HORIZONTAL_ALIGNMENT ), "BEGIN", TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::VERTICAL_ALIGNMENT ), "TOP", TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::TEXT_COLOR ), Color::BLACK, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<Vector2>( TextField::Property::SHADOW_OFFSET ), Vector2::ZERO, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PLACEHOLDER_TEXT_COLOR ), PLACEHOLDER_TEXT_COLOR, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SHADOW_COLOR ), Color::BLACK, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PRIMARY_CURSOR_COLOR ), Color::BLACK, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SECONDARY_CURSOR_COLOR ), Color::BLACK, TEST_LOCATION );
    DALI_TEST_EQUALS( field.GetProperty<bool>( TextField::Property::ENABLE_CURSOR_BLINK ), true, TEST_LOCATION );
-   field.SetProperty( TextField::Property::PRIMARY_CURSOR_COLOR, Color::RED );
-   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PRIMARY_CURSOR_COLOR ), Color::RED, TEST_LOCATION );
-   field.SetProperty( TextField::Property::SECONDARY_CURSOR_COLOR, Color::BLUE );
-   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SECONDARY_CURSOR_COLOR ), Color::BLUE, TEST_LOCATION );
-   field.SetProperty( TextField::Property::CURSOR_BLINK_DURATION, 10.0f );
-   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_DURATION ), 10.0f, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_INTERVAL ), CURSOR_BLINK_INTERVAL * TO_SECONDS, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_DURATION ), 0.f, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_THRESHOLD ), SCROLL_THRESHOLD, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_SPEED ), SCROLL_SPEED, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SELECTION_HIGHLIGHT_COLOR ), LIGHT_BLUE, TEST_LOCATION );
  
-   // Blink interval
-   field.SetProperty( TextField::Property::CURSOR_BLINK_INTERVAL, 1.0f );
-   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_INTERVAL ), 1.0f, TEST_LOCATION );
+   // Check the render backend property.
+   field.SetProperty( TextField::Property::RENDERING_BACKEND, Text::RENDERING_BASIC );
+   DALI_TEST_EQUALS( field.GetProperty<unsigned int>( TextField::Property::RENDERING_BACKEND ), Text::RENDERING_BASIC, TEST_LOCATION );
  
-   // Decoration bounding box
-   field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
-   DALI_TEST_EQUALS( field.GetProperty<Rect <int > >( TextField::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
-   // Check that the Alignment properties can be correctly set
-   field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "BEGIN" );
-   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::HORIZONTAL_ALIGNMENT ), "BEGIN", TEST_LOCATION );
-   field.SetProperty( TextField::Property::VERTICAL_ALIGNMENT, "CENTER" );
-   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::VERTICAL_ALIGNMENT ), "CENTER", TEST_LOCATION );
-   // Set text
+   // Check text property.
    field.SetProperty( TextField::Property::TEXT, "Setting Text" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string("Setting Text"), TEST_LOCATION );
+   // Check placeholder text properties.
+   field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "Setting Placeholder Text" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT ), std::string("Setting Placeholder Text"), TEST_LOCATION );
  
-   // Set placeholder text (currently not implemented)
-   field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "Setting Text" );
+   field.SetProperty( TextField::Property::PLACEHOLDER_TEXT_FOCUSED, "Setting Placeholder Text Focused" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT_FOCUSED ), std::string("Setting Placeholder Text Focused"), TEST_LOCATION );
  
-   // Set Grab Handle image
-   field.SetProperty( TextField::Property::GRAB_HANDLE_IMAGE, "" );
+   // Check font properties.
+   field.SetProperty( TextField::Property::FONT_FAMILY, "Setting font family" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_FAMILY ), std::string("Setting font family"), TEST_LOCATION );
+   field.SetProperty( TextField::Property::FONT_STYLE, "Setting font style" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_STYLE ), std::string("Setting font style"), TEST_LOCATION );
+   field.SetProperty( TextField::Property::POINT_SIZE, 10.f );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
  
    // Check that the MAX_LENGTH property can be correctly set
    const int maxNumberOfCharacters = 20;
    field.SetProperty( TextField::Property::MAX_LENGTH, maxNumberOfCharacters );
    DALI_TEST_EQUALS( field.GetProperty<int>( TextField::Property::MAX_LENGTH ), maxNumberOfCharacters, TEST_LOCATION );
  
-   END_TEST;
- }
+   // Check exceed policy
+   // Set a different exceed policy is not implemented.
  
- // Negative test case for a method
- int UtcDaliTextFieldSetPropertyN(void)
- {
-   ToolkitTestApplication application;
-   tet_infoline(" UtcDaliToolkitTextFieldSetPropertyN");
-   TextField field = TextField::New();
-   DALI_TEST_CHECK( field );
+   // Check that the Alignment properties can be correctly set
+   field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "END" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::HORIZONTAL_ALIGNMENT ), "END", TEST_LOCATION );
+   field.SetProperty( TextField::Property::VERTICAL_ALIGNMENT, "CENTER" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::VERTICAL_ALIGNMENT ), "CENTER", TEST_LOCATION );
+   // Check text's color property
+   field.SetProperty( TextField::Property::TEXT_COLOR, Color::WHITE );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::TEXT_COLOR ), Color::WHITE, TEST_LOCATION );
+   // Check placeholder text's color property.
+   field.SetProperty( TextField::Property::PLACEHOLDER_TEXT_COLOR, Color::RED );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PLACEHOLDER_TEXT_COLOR ), Color::RED, TEST_LOCATION );
+   // Check shadow properties.
+   field.SetProperty( TextField::Property::SHADOW_OFFSET, Vector2( 1.f, 1.f ) );
+   DALI_TEST_EQUALS( field.GetProperty<Vector2>( TextField::Property::SHADOW_OFFSET ), Vector2( 1.f, 1.f ), TEST_LOCATION );
+   field.SetProperty( TextField::Property::SHADOW_COLOR, Color::GREEN );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SHADOW_COLOR ), Color::GREEN, TEST_LOCATION );
+   // Check cursor properties
+   field.SetProperty( TextField::Property::PRIMARY_CURSOR_COLOR, Color::RED );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PRIMARY_CURSOR_COLOR ), Color::RED, TEST_LOCATION );
+   field.SetProperty( TextField::Property::SECONDARY_CURSOR_COLOR, Color::BLUE );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SECONDARY_CURSOR_COLOR ), Color::BLUE, TEST_LOCATION );
+   field.SetProperty( TextField::Property::ENABLE_CURSOR_BLINK, false );
+   DALI_TEST_EQUALS( field.GetProperty<bool>( TextField::Property::ENABLE_CURSOR_BLINK ), false, TEST_LOCATION );
+   field.SetProperty( TextField::Property::CURSOR_BLINK_INTERVAL, 1.f );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_INTERVAL ), 1.f, TEST_LOCATION );
+   field.SetProperty( TextField::Property::CURSOR_BLINK_DURATION, 10.f );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_DURATION ), 10.f, TEST_LOCATION );
+   // Check scroll properties.
+   field.SetProperty( TextField::Property::SCROLL_THRESHOLD, 1.f );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_THRESHOLD ), 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+   field.SetProperty( TextField::Property::SCROLL_SPEED, 100.f );
+   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_SPEED ), 100.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+   // Check handle images
+   field.SetProperty( TextField::Property::GRAB_HANDLE_IMAGE, "image1" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::GRAB_HANDLE_IMAGE ), "image1", TEST_LOCATION );
+   field.SetProperty( TextField::Property::GRAB_HANDLE_PRESSED_IMAGE, "image2" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::GRAB_HANDLE_PRESSED_IMAGE ), "image2", TEST_LOCATION );
+   field.SetProperty( TextField::Property::SELECTION_HANDLE_IMAGE_LEFT, "image3" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_IMAGE_LEFT ), "image3", TEST_LOCATION );
+   field.SetProperty( TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT, "image4" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT ), "image4", TEST_LOCATION );
+   field.SetProperty( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT, "image5" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT ), "image5", TEST_LOCATION );
+   field.SetProperty( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, "image6" );
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT ), "image6", TEST_LOCATION );
+   // Check the highlight color
+   field.SetProperty( TextField::Property::SELECTION_HIGHLIGHT_COLOR, Color::GREEN );
+   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SELECTION_HIGHLIGHT_COLOR ), Color::GREEN, TEST_LOCATION );
+   // Decoration bounding box
+   field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
+   DALI_TEST_EQUALS( field.GetProperty<Rect <int > >( TextField::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
  
-   bool assert = false;
-   try
-   {
-     field.SetProperty( 0, true );
-   }
-   catch ( ... )
-   {
-     assert = true;
-   }
-   if ( assert )
-   {
-     tet_result(TET_PASS);
-   }
-   else
-   {
-     tet_result(TET_FAIL);
-   }
    END_TEST;
  }
  
@@@ -301,6 -397,10 +396,10 @@@ int utcDaliTextFieldBasicRenderP(void
  
    field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "BEGIN" );
  
+   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+   Stage::GetCurrent().Add( field );
    try
    {
      // Render some text with the basic backend
@@@ -326,6 -426,11 +425,11 @@@ int utcDaliTextFieldAtlasRenderP(void
    DALI_TEST_CHECK( field );
  
    field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+   Stage::GetCurrent().Add( field );
    try
    {
      // Render some text with the shared atlas backend
@@@ -348,7 -453,7 +452,7 @@@ int utcDaliTextFieldTextChangedP(void
    TextField field = TextField::New();
    DALI_TEST_CHECK( field );
  
-   Stage::GetCurrent().Add(field);
+   Stage::GetCurrent().Add( field );
  
    field.TextChangedSignal().Connect(&TestTextChangedCallback);
  
  
    field.SetKeyInputFocus();
  
-   Dali::Integration::KeyEvent keyevent;
-   keyevent.keyName = "D";
-   keyevent.keyString = "D";
-   keyevent.keyCode = 0;
-   keyevent.keyModifier = 0;
-   keyevent.time = 0;
-   keyevent.state = Integration::KeyEvent::Down;
    gTextChangedCallBackCalled = false;
-   application.ProcessEvent( keyevent );
+   application.ProcessEvent( GenerateKey( "D", "D", 0, 0, 0, Integration::KeyEvent::Down ) );
    DALI_TEST_CHECK( gTextChangedCallBackCalled );
  
    END_TEST;
@@@ -383,13 -480,13 +479,13 @@@ int utcDaliTextFieldTextChangedN(void
    TextField field = TextField::New();
    DALI_TEST_CHECK( field );
  
-   Stage::GetCurrent().Add(field);
+   Stage::GetCurrent().Add( field );
  
    field.TextChangedSignal().Connect(&TestTextChangedCallback);
  
    gTextChangedCallBackCalled = false;
    field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "ABC" ); // Setting placeholder, not TEXT
-   DALI_TEST_CHECK( ! gTextChangedCallBackCalled );
+   DALI_TEST_CHECK( !gTextChangedCallBackCalled );
  
    END_TEST;
  }
@@@ -402,7 -499,7 +498,7 @@@ int utcDaliTextFieldMaxCharactersReache
    TextField field = TextField::New();
    DALI_TEST_CHECK( field );
  
-   Stage::GetCurrent().Add(field);
+   Stage::GetCurrent().Add( field );
  
    const int maxNumberOfCharacters = 1;
    field.SetProperty( TextField::Property::MAX_LENGTH, maxNumberOfCharacters );
    gMaxCharactersCallBackCalled = false;
    field.MaxLengthReachedSignal().Connect(&TestMaxLengthReachedCallback);
  
-   Dali::Integration::KeyEvent keyevent;
-   keyevent.keyName = "a";
-   keyevent.keyString = "a";
-   keyevent.keyCode = 0;
-   keyevent.keyModifier = 0;
-   keyevent.time = 0;
-   keyevent.state = Integration::KeyEvent::Down;
-   application.ProcessEvent( keyevent );
-   application.ProcessEvent( keyevent );
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
  
    DALI_TEST_CHECK( gMaxCharactersCallBackCalled );
  
@@@ -437,7 -525,7 +524,7 @@@ int utcDaliTextFieldMaxCharactersReache
    TextField field = TextField::New();
    DALI_TEST_CHECK( field );
  
-   Stage::GetCurrent().Add(field);
+   Stage::GetCurrent().Add( field );
  
    const int maxNumberOfCharacters = 3;
    field.SetProperty( TextField::Property::MAX_LENGTH, maxNumberOfCharacters );
    gMaxCharactersCallBackCalled = false;
    field.MaxLengthReachedSignal().Connect(&TestMaxLengthReachedCallback);
  
-   Dali::Integration::KeyEvent keyevent;
-   keyevent.keyName = "a";
-   keyevent.keyString = "a";
-   keyevent.keyCode = 0;
-   keyevent.keyModifier = 0;
-   keyevent.time = 0;
-   keyevent.state = Integration::KeyEvent::Down;
-   application.ProcessEvent( keyevent );
-   application.ProcessEvent( keyevent );
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
  
    DALI_TEST_CHECK( !gMaxCharactersCallBackCalled );
  
    END_TEST;
  }
+ int utcDaliTextFieldEvent01(void)
+ {
+   ToolkitTestApplication application;
+   tet_infoline(" utcDaliTextFieldEvent01");
+   // Creates a tap event. After creating a tap event the text field should
+   // have the focus and add text with key events should be possible.
+   TextField field = TextField::New();
+   DALI_TEST_CHECK( field );
+   Stage::GetCurrent().Add( field );
+   field.SetSize( 300.f, 50.f );
+   field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+   field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+   // Avoid a crash when core load gl resources.
+   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Add a key event but as the text field has not the focus it should do nothing.
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string(""), TEST_LOCATION );
+   // Create a tap event to touch the text field.
+   application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+   application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Now the text field has the focus, so it can handle the key events.
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+   // Create a second text field and send key events to it.
+   TextField field2 = TextField::New();
+   field2.SetParentOrigin( ParentOrigin::TOP_LEFT );
+   field2.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+   field2.SetSize( 100.f, 100.f );
+   field2.SetPosition( 100.f, 100.f );
+   Stage::GetCurrent().Add( field2 );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Create a tap event on the second text field.
+   application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+   application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // The second text field has the focus. It should handle the key events.
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Check the text has been added to the second text field.
+   DALI_TEST_EQUALS( field2.GetProperty<std::string>( TextField::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+   END_TEST;
+ }
+ int utcDaliTextFieldEvent02(void)
+ {
+   ToolkitTestApplication application;
+   tet_infoline(" utcDaliTextFieldEvent02");
+   // Checks if the right number of actors are created.
+   TextField field = TextField::New();
+   DALI_TEST_CHECK( field );
+   Stage::GetCurrent().Add( field );
+   field.SetSize( 300.f, 50.f );
+   field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+   field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+   // Avoid a crash when core load gl resources.
+   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Check there are the expected number of children ( active layer, offscreen root actor, and the offscreen image actor
+   DALI_TEST_EQUALS( field.GetChildCount(), 3u, TEST_LOCATION );
+   Actor layer = field.GetChildAt( 0u );
+   DALI_TEST_CHECK( layer.IsLayer() );
+   Actor offscreenRoot = field.GetChildAt( 1u );
+   DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+   Actor offscreenImage = field.GetChildAt( 2u );
+   ImageActor imageActor = ImageActor::DownCast( offscreenImage );
+   DALI_TEST_CHECK( imageActor );
+   // Create a tap event to touch the text field.
+   application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+   application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+   // Now the text field has the focus, so it can handle the key events.
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Checks the cursor and the renderer have been created.
+   DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 2u, TEST_LOCATION ); // The camera actor and the renderer
+   ImageActor cursor = ImageActor::DownCast( layer.GetChildAt( 0u ) );
+   DALI_TEST_CHECK( cursor );
+   CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+   DALI_TEST_CHECK( camera );
+   RenderableActor renderer = RenderableActor::DownCast( offscreenRoot.GetChildAt( 1u ) );
+   DALI_TEST_CHECK( renderer );
+   // Move the cursor and check the position changes.
+   Vector3 position1 = cursor.GetCurrentPosition();
+   application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   Vector3 position2 = cursor.GetCurrentPosition();
+   DALI_TEST_CHECK( position2.x < position1.x );
+   application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   Vector3 position3 = cursor.GetCurrentPosition();
+   DALI_TEST_EQUALS( position1, position3, TEST_LOCATION ); // Should be in the same position1.
+   // Send some taps and check the cursor positions.
+   // Try to tap at the beginning.
+   application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+   application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Cursor position should be the same than position1.
+   Vector3 position4 = cursor.GetCurrentPosition();
+   DALI_TEST_EQUALS( position2, position4, TEST_LOCATION ); // Should be in the same position2.
+   // Try to tap at the end.
+   application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 13.f, 25.0f ) ) );
+   application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 13.0f, 25.0f ) ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Cursor position should be the same than position1.
+   Vector3 position5 = cursor.GetCurrentPosition();
+   DALI_TEST_EQUALS( position1, position5, TEST_LOCATION ); // Should be in the same position1.
+   // Remove some text.
+   application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+   application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Cursor position should be the same than position2.
+   Vector3 position6 = cursor.GetCurrentPosition();
+   DALI_TEST_EQUALS( Vector3( 0.f, position2.y, position2.z ), position6, TEST_LOCATION ); // TODO Should be in the same position2.
+   // Should not be renderer.
+   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor only.
+   END_TEST;
+ }
+ int utcDaliTextFieldEvent03(void)
+ {
+   ToolkitTestApplication application;
+   tet_infoline(" utcDaliTextFieldEvent03");
+   // Checks if the highlight actor is created.
+   TextField field = TextField::New();
+   DALI_TEST_CHECK( field );
+   Stage::GetCurrent().Add( field );
+   field.SetProperty( TextField::Property::TEXT, "This is a long text for the size of the text-field." );
+   field.SetSize( 30.f, 50.f );
+   field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+   field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+   // Avoid a crash when core load gl resources.
+   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Tap first to get the focus.
+   application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+   application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // Double tap to select a word.
+   application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+   application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+   // Render and notify
+   application.SendNotification();
+   application.Render();
+   // The offscreen root actor should have three actors: the camera, a renderer and the highlight actor.
+   Actor offscreenRoot = field.GetChildAt( 1u );
+   DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+   CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+   DALI_TEST_CHECK( camera );
+   RenderableActor renderer = RenderableActor::DownCast( offscreenRoot.GetChildAt( 1u ) );
+   DALI_TEST_CHECK( renderer );
+   MeshActor highlight = MeshActor::DownCast( offscreenRoot.GetChildAt( 2u ) );
+   DALI_TEST_CHECK( highlight );
+   END_TEST;
+ }
diff --combined build/tizen/configure.ac
@@@ -45,6 -45,12 +45,12 @@@ AC_ARG_ENABLE([debug]
                [enable_debug=$enableval],
                [enable_debug=no])
  
+ AC_ARG_ENABLE([i18n],
+               [AC_HELP_STRING([--enable-i18n],
+                               [Turns on internationalisation])],
+               [enable_i18n=$enableval],
+               [enable_i18n=no])
  # option to build JavaScript plugin
  # configure settings and output
  # --enable-javascript        // enable_javascript = yes
@@@ -56,7 -62,7 +62,7 @@@ AC_ARG_ENABLE([javascript]
                [AC_HELP_STRING([--enable-javascript],
                 [Enable JavaScript plugin])] ,
                 [enable_javascript=$enableval],
 -               [enable_javascript=automatic])
 +               [enable_javascript=no])
  
  
  if test "x$enable_debug" = "xyes"; then
@@@ -67,8 -73,9 +73,9 @@@ if test "x$enable_debug" = "xno" -a "x$
    DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -fvisibility=hidden -DHIDE_DALI_INTERNALS"
  fi
  
+ if test "x$enable_i18n" = "xyes"; then
+   DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -DDGETTEXT_ENABLED "
+ fi
  
  # Tizen Profile options
  AC_ARG_ENABLE([profile],
@@@ -96,14 -96,17 +96,15 @@@ develapishadowviewdir =         $(devel
  develapisuperblurviewdir =      $(develapicontrolsdir)/super-blur-view
  develapifocusmanagerdir =       $(develapidir)/focus-manager
  develapiscriptingdir =          $(develapidir)/scripting
 -develapibubbleeffectdir =       $(develapidir)/shader-effects/bubble-effect
  develapishadereffectsdir =      $(develapidir)/shader-effects
  develapitransitioneffectsdir =  $(develapidir)/transition-effects
  develapistylingdir =            $(develapidir)/styling
  develapitoolbardir =            $(develapicontrolsdir)/tool-bar
+ develapitextselectionpopupdir = $(develapicontrolsdir)/text-controls
  
  # devel headers
  develapibloomview_HEADERS =         $(devel_api_bloom_view_header_files)
  develapibubbleemitter_HEADERS =     $(devel_api_bubble_emitter_header_files)
 -develapibubbleeffect_HEADERS =      $(devel_api_bubble_effect_header_files)
  develapibuilder_HEADERS =           $(devel_api_builder_header_files)
  develapieffectsview_HEADERS =       $(devel_api_effects_view_header_files)
  develapifocusmanager_HEADERS =      $(devel_api_focus_manager_header_files)
@@@ -118,6 -121,7 +119,7 @@@ develapistyling_HEADERS =           $(d
  develapisuperblurview_HEADERS =     $(devel_api_super_blur_view_header_files)
  develapitoolbar_HEADERS =           $(devel_api_tool_bar_header_files)
  develapitransitioneffects_HEADERS = $(devel_api_transition_effects_header_files)
+ develapitextselectionpopup_HEADERS = $(devel_api_text_selection_popup_header_files)
  
  # public api source
  publicapidir =                  $(topleveldir)/public-api
@@@ -17,10 -17,41 +17,11 @@@ devel_api_src_files = 
    $(devel_api_src_dir)/controls/slider/slider.cpp \
    $(devel_api_src_dir)/controls/super-blur-view/super-blur-view.cpp \
    $(devel_api_src_dir)/controls/text-controls/text-selection-popup.cpp \
+   $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.cpp \
    $(devel_api_src_dir)/controls/tool-bar/tool-bar.cpp \
    $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.cpp \
    $(devel_api_src_dir)/styling/style-manager.cpp \
    $(devel_api_src_dir)/scripting/script.cpp \
 -  $(devel_api_src_dir)/shader-effects/bubble-effect/bubble-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/bubble-effect/color-adjuster.cpp \
 -  $(devel_api_src_dir)/shader-effects/alpha-discard-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/bendy-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/blind-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/bouncing-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/carousel-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/displacement-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/dissolve-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/dissolve-local-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/distance-field-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/image-region-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/iris-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/mask-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/mirror-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/motion-blur-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/motion-stretch-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/nine-patch-mask-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/overlay-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/page-turn-book-spine-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/page-turn-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/quadratic-bezier.cpp \
 -  $(devel_api_src_dir)/shader-effects/ripple-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/ripple2d-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/shear-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/soft-button-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/spot-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/square-dissolve-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/swirl-effect.cpp \
 -  $(devel_api_src_dir)/shader-effects/water-effect.cpp \
    $(devel_api_src_dir)/transition-effects/cube-transition-cross-effect.cpp \
    $(devel_api_src_dir)/transition-effects/cube-transition-effect.cpp \
    $(devel_api_src_dir)/transition-effects/cube-transition-fold-effect.cpp \
  devel_api_bloom_view_header_files = \
    $(devel_api_src_dir)/controls/bloom-view/bloom-view.h
  
 -devel_api_bubble_effect_header_files =  \
 -  $(devel_api_src_dir)/shader-effects/bubble-effect/bubble-effect.h \
 -  $(devel_api_src_dir)/shader-effects/bubble-effect/color-adjuster.h
 -
  devel_api_bubble_emitter_header_files = \
    $(devel_api_src_dir)/controls/bubble-effect/bubble-emitter.h
  
@@@ -88,6 -123,8 +89,6 @@@ devel_api_shader_effects_header_files 
    $(devel_api_src_dir)/shader-effects/motion-stretch-effect.h \
    $(devel_api_src_dir)/shader-effects/nine-patch-mask-effect.h \
    $(devel_api_src_dir)/shader-effects/overlay-effect.h \
 -  $(devel_api_src_dir)/shader-effects/page-turn-book-spine-effect.h \
 -  $(devel_api_src_dir)/shader-effects/page-turn-effect.h \
    $(devel_api_src_dir)/shader-effects/quadratic-bezier.h \
    $(devel_api_src_dir)/shader-effects/ripple-effect.h \
    $(devel_api_src_dir)/shader-effects/ripple2d-effect.h \
    $(devel_api_src_dir)/shader-effects/soft-button-effect.h \
    $(devel_api_src_dir)/shader-effects/spot-effect.h \
    $(devel_api_src_dir)/shader-effects/square-dissolve-effect.h \
 -  $(devel_api_src_dir)/shader-effects/swirl-effect.h \
 -  $(devel_api_src_dir)/shader-effects/water-effect.h
 +  $(devel_api_src_dir)/shader-effects/swirl-effect.h
  
  devel_api_super_blur_view_header_files = \
    $(devel_api_src_dir)/controls/super-blur-view/super-blur-view.h
  
- devel_api_text_selection_popup_header_files = \
-   $(devel_api_src_dir)/controls/text-controls/text-selection-popup.h
+ devel_api_text_controls_header_files = \
+   $(devel_api_src_dir)/controls/text-controls/text-selection-popup.h \
+   $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.h
  
  devel_api_tool_bar_header_files = \
    $(devel_api_src_dir)/controls/tool-bar/tool-bar.h
@@@ -20,8 -20,6 +20,8 @@@
  // EXTERNAL INCLUDE
  #include <iostream>
  #include <string.h>
 +#include <dali/devel-api/rendering/sampler.h>
 +#include <dali/devel-api/rendering/shader.h>
  #include <dali/integration-api/debug.h>
  
  namespace Dali
@@@ -43,47 -41,6 +43,47 @@@ namespac
    const uint32_t DOUBLE_PIXEL_PADDING( SINGLE_PIXEL_PADDING << 1 );
    const uint32_t FILLED_PIXEL( -1 );
    Toolkit::AtlasManager::AtlasSize EMPTY_SIZE;
 +
 +  #define MAKE_SHADER(A)#A
 +
 +  const char* VERTEX_SHADER = MAKE_SHADER(
 +  attribute mediump vec2    aPosition;
 +  attribute mediump vec2    aTexCoord;
 +  uniform   mediump mat4    uMvpMatrix;
 +  uniform   mediump vec3    uSize;
 +  varying   mediump vec2    vTexCoord;
 +
 +  void main()
 +  {
 +    mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
 +    position.xyz *= uSize;
 +    gl_Position = uMvpMatrix * position;
 +    vTexCoord = aTexCoord;
 +  }
 +  );
 +
 +  const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
 +  uniform lowp    vec4      uColor;
 +  uniform         sampler2D sTexture;
 +  varying mediump vec2      vTexCoord;
 +
 +  void main()
 +  {
 +    mediump vec4 color = texture2D( sTexture, vTexCoord );
 +    gl_FragColor = vec4( uColor.rgb, uColor.a * color.r );
 +  }
 +  );
 +
 +  const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER(
 +  uniform         sampler2D sTexture;
 +  varying mediump vec2      vTexCoord;
 +
 +  void main()
 +  {
 +    gl_FragColor = texture2D( sTexture, vTexCoord );
 +  }
 +  );
 +
  }
  
  AtlasManager::AtlasManager()
@@@ -94,8 -51,6 +94,8 @@@
    mNewAtlasSize.mHeight = DEFAULT_ATLAS_HEIGHT;
    mNewAtlasSize.mBlockWidth = DEFAULT_BLOCK_WIDTH;
    mNewAtlasSize.mBlockHeight = DEFAULT_BLOCK_HEIGHT;
 +  mShaderL8 = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
 +  mShaderRgba = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RGBA );
  }
  
  AtlasManagerPtr AtlasManager::New()
  
  AtlasManager::~AtlasManager()
  {
 -  for ( uint32_t i = 0; i < mAtlasList.size(); ++i )
 +  for ( SizeType i = 0; i < mAtlasList.size(); ++i )
    {
 +    mAtlasList[ i ].mAtlas.UploadedSignal().Disconnect( this, &AtlasManager::OnUpload );
      delete[] mAtlasList[ i ].mStripBuffer;
    }
 +
 +  // Are there any upload signals pending? Free up those buffer images now.
 +  for ( SizeType i = 0; i < mUploadedImages.Size(); ++i )
 +  {
 +    delete[] mUploadedImages[ i ];
 +  }
 +}
 +
 +void AtlasManager::OnUpload( Image image )
 +{
 +  if ( mUploadedImages.Size() )
 +  {
 +    delete[] mUploadedImages[ 0 ];
 +    mUploadedImages.Erase( mUploadedImages.Begin() );
 +  }
 +  else
 +  {
 +    DALI_LOG_ERROR("Atlas Image Upload List should not be empty\n");
 +  }
  }
  
  Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasManager::AtlasSize& size, Pixel::Format pixelformat )
    atlasDescriptor.mAtlas = atlas;
    atlasDescriptor.mSize = size;
    atlasDescriptor.mPixelFormat = pixelformat;
 -  std::stringstream materialLabel;
 -  materialLabel << "Atlas Material - ";
 -  materialLabel << mAtlasList.size();
 -  atlasDescriptor.mMaterial = Material::New( materialLabel.str() );
 -  atlasDescriptor.mMaterial.SetDiffuseTexture( atlas );
    atlasDescriptor.mNextFreeBlock = 1u; // indicate next free block will be the first ( +1 )
 +  atlas.UploadedSignal().Connect( this, &AtlasManager::OnUpload );
  
    // What size do we need for this atlas' strip buffer ( assume 32bit pixel format )?
 -  uint32_t neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2;
 +  SizeType neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2;
    atlasDescriptor.mStripBuffer = new PixelBuffer[ neededStripSize ];
    memset( atlasDescriptor.mStripBuffer, 0, neededStripSize );
  
                                                       SINGLE_PIXEL_PADDING,
                                                       blockHeight - DOUBLE_PIXEL_PADDING,
                                                       pixelformat );
 +  mUploadedImages.PushBack( NULL );
    atlasDescriptor.mFilledPixelImage = BufferImage::New( reinterpret_cast< PixelBuffer* >( &mFilledPixel ), 1, 1, pixelformat );
    atlas.Upload( atlasDescriptor.mFilledPixelImage, 0, 0 );
 +
 +  Sampler sampler = Sampler::New( atlas, "sTexture" );
 +  sampler.SetProperty( Sampler::Property::AFFECTS_TRANSPARENCY, true );
 +  atlasDescriptor.mMaterial = Material::New( pixelformat == Pixel::L8 ? mShaderL8 : mShaderRgba );
 +  atlasDescriptor.mMaterial.AddSampler( sampler );
 +  atlasDescriptor.mSampler = sampler;
 +  atlasDescriptor.mMaterial.SetBlendMode( BlendingMode::ON );
    mAtlasList.push_back( atlasDescriptor );
    return mAtlasList.size();
  }
@@@ -238,7 -169,7 +238,7 @@@ void AtlasManager::Add( const BufferIma
      if ( Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy || !foundAtlas-- )
      {
        // Haven't found an atlas for this image!!!!!!
 -          return;
 +      return;
      }
    }
  
@@@ -334,12 -265,16 +334,12 @@@ void AtlasManager::CreateMesh( SizeTyp
                                 const Vector2& position,
                                 SizeType widthInBlocks,
                                 SizeType heightInBlocks,
 -                               Dali::MeshData& meshData,
 +                               Toolkit::AtlasManager::Mesh2D& mesh,
                                 AtlasSlotDescriptor& desc )
  {
 -  Dali::MeshData::Vertex vertex;
 -  Dali::MeshData::VertexContainer vertices;
 -  Dali::MeshData::FaceIndices faces;
 -  Dali::MeshData::FaceIndex faceIndex = 0;
 -  meshData.SetHasNormals( false );
 -  meshData.SetHasColor( true );
 -  meshData.SetHasTextureCoords( true );
 +
 +  Toolkit::AtlasManager::Vertex2D vertex;
 +  uint32_t faceIndex = 0;       // TODO change to unsigned short when property type is available
  
    SizeType blockWidth = mAtlasList[ atlas ].mSize.mBlockWidth;
    SizeType blockHeight = mAtlasList[ atlas ].mSize.mBlockHeight;
        }
  
        // Top left
 -      vertex.x = topLeft.x;
 -      vertex.y = topLeft.y;
 -      vertex.z = 0.0f;
 -      vertex.u = fBlockX;
 -      vertex.v = fBlockY;
 +      vertex.mPosition.x = topLeft.x;
 +      vertex.mPosition.y = topLeft.y;
 +      vertex.mTexCoords.x = fBlockX;
 +      vertex.mTexCoords.y = fBlockY;
  
 -      vertices.push_back( vertex );
 +      mesh.mVertices.PushBack( vertex );
  
        // Top Right
 -      vertex.x = topLeft.x + ndcVWidth;
 -      vertex.y = topLeft.y;
 -      vertex.z = 0.0f;
 -      vertex.u = fBlockX + ndcWidth;
 -      vertex.v = fBlockY;
 +      vertex.mPosition.x = topLeft.x + ndcVWidth;
 +      vertex.mPosition.y = topLeft.y;
 +      vertex.mTexCoords.x = fBlockX + ndcWidth;
 +      vertex.mTexCoords.y = fBlockY;
  
 -      vertices.push_back( vertex );
 +      mesh.mVertices.PushBack( vertex );
  
        // Bottom Left
 -      vertex.x = topLeft.x;
 -      vertex.y = topLeft.y + ndcVHeight;
 -      vertex.z = 0.0f;
 -      vertex.u = fBlockX;
 -      vertex.v = fBlockY + ndcHeight;
 +      vertex.mPosition.x = topLeft.x;
 +      vertex.mPosition.y = topLeft.y + ndcVHeight;
 +      vertex.mTexCoords.x = fBlockX;
 +      vertex.mTexCoords.y = fBlockY + ndcHeight;
  
 -      vertices.push_back( vertex );
 +      mesh.mVertices.PushBack( vertex );
  
        // Bottom Right
        topLeft.x += ndcVWidth;
 -      vertex.x = topLeft.x;
 -      vertex.y = topLeft.y + ndcVHeight;
 -      vertex.z = 0.0f;
 -      vertex.u = fBlockX + ndcWidth;
 -      vertex.v = fBlockY + ndcHeight;
 +      vertex.mPosition.x = topLeft.x;
 +      vertex.mPosition.y = topLeft.y + ndcVHeight;
 +      vertex.mTexCoords.x = fBlockX + ndcWidth;
 +      vertex.mTexCoords.y = fBlockY + ndcHeight;
  
 -      vertices.push_back( vertex );
 +      mesh.mVertices.PushBack( vertex );
  
        // Six indices in counter clockwise winding
 -      faces.push_back( faceIndex + 1u );
 -      faces.push_back( faceIndex );
 -      faces.push_back( faceIndex + 2u );
 -      faces.push_back( faceIndex + 2u );
 -      faces.push_back( faceIndex + 3u );
 -      faces.push_back( faceIndex + 1u );
 +      mesh.mIndices.PushBack( faceIndex + 1u );
 +      mesh.mIndices.PushBack( faceIndex );
 +      mesh.mIndices.PushBack( faceIndex + 2u );
 +      mesh.mIndices.PushBack( faceIndex + 2u );
 +      mesh.mIndices.PushBack( faceIndex + 3u );
 +      mesh.mIndices.PushBack( faceIndex + 1u );
        faceIndex += 4;
      }
  
    // If there's only one block then skip this next vertex optimisation
    if ( widthInBlocks * heightInBlocks > 1 )
    {
 -    Dali::MeshData::VertexContainer optimizedVertices;
 -    OptimizeVertices( vertices, faces, optimizedVertices );
 -    meshData.SetVertices( optimizedVertices );
 -  }
 -  else
 -  {
 -    meshData.SetVertices( vertices );
 +    Toolkit::AtlasManager::Mesh2D optimizedMesh;
 +    OptimizeMesh( mesh, optimizedMesh );
    }
 -
 -  meshData.SetFaceIndices( faces );
 -  meshData.SetMaterial( mAtlasList[ atlas ].mMaterial );
 +  //PrintMeshData( mesh );
  }
  
 -void AtlasManager::PrintMeshData( const MeshData& meshData )
 +void AtlasManager::PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh )
  {
 -  std::cout << "\nMesh Data for Image: VertexCount = " << meshData.GetVertexCount();
 -  std::cout << ", Triangles = " << meshData.GetFaceCount() << std::endl;
 +  uint32_t vertexCount = mesh.mVertices.Size();
 +  uint32_t indexCount = mesh.mIndices.Size();
 +  std::cout << "\nMesh Data for Image: VertexCount = " << vertexCount;
 +  std::cout << ", Triangles = " << indexCount / 3 << std::endl;
  
 -  Dali::MeshData::VertexContainer vertices = meshData.GetVertices();
 -  Dali::MeshData::FaceIndices faces = meshData.GetFaces();
 -
 -  for ( SizeType v = 0; v < vertices.size(); ++v )
 +  for ( SizeType v = 0; v < vertexCount; ++v )
    {
 -    std::cout << " Vertex(" << v << ") x = " << vertices[v].x << ", ";
 -    std::cout << "y = " << vertices[v].y << ", " << "z = " << vertices[v].z << ", ";
 -    std::cout << "u = " << vertices[v].u << ", " << "v = " << vertices[v].v << std::endl;
 +    std::cout << " Vertex(" << v << ") x = " << mesh.mVertices[v].mPosition.x << ", ";
 +    std::cout << "y = " << mesh.mVertices[v].mPosition.y << ", ";
 +    std::cout << "u = " << mesh.mVertices[v].mTexCoords.x << ", ";
 +    std::cout << "v = " << mesh.mVertices[v].mTexCoords.y << std::endl;
    }
  
    std::cout << "\n Indices: ";
 -  for ( SizeType i = 0; i < faces.size(); ++i )
 +  for ( SizeType i = 0; i < indexCount; ++i )
    {
 -    std::cout << " " << faces[ i ];
 +    std::cout << " " << mesh.mIndices[ i ];
    }
    std::cout << std::endl;
  }
  
 -void AtlasManager::OptimizeVertices( const MeshData::VertexContainer& in,
 -                                     MeshData::FaceIndices& faces,
 -                                     MeshData::VertexContainer& out )
 +void AtlasManager::OptimizeMesh( const Toolkit::AtlasManager::Mesh2D& in,
 +                                 Toolkit::AtlasManager::Mesh2D& out )
  {
    unsigned short vertexIndex = 0;
  
    // We could check to see if blocks are next to each other, but it's probably just as quick to compare verts
 -  for ( SizeType i = 0; i < faces.size(); ++i )
 +  for ( SizeType i = 0; i < in.mIndices.Size(); ++i )
    {
      // Fetch a vertex, has it already been assigned?
      bool foundVertex = false;
 -    Dali::MeshData::Vertex v = in[ faces [ i ] ];
 -    for ( SizeType j = 0; j < vertexIndex; ++j )
 +    Toolkit::AtlasManager::Vertex2D v = in.mVertices[ in.mIndices[ i ] ];
 +    for ( SizeType j = 0; j < out.mVertices.Size(); ++j )
      {
 -      if ( v.x == out[ j ].x && v.y == out[ j ].y && v.z == out[ j ].z &&
 -           v.u == out[ j ].u && v.v == out[ j ].v && v.nX == out[ j ].nX &&
 -           v.nY == out[ j ].nY && v.nZ == out[ j ].nZ )
 +      if ( v.mPosition.x == out.mVertices[ j ].mPosition.x && v.mPosition.y == out.mVertices[ j ].mPosition.y &&
 +           v.mTexCoords.x == out.mVertices[ j ].mTexCoords.x && v.mTexCoords.y == out.mVertices[ j ].mTexCoords.y )
        {
          // Yes, so store this down as the vertex to use
 -        faces[ i ] = j;
 +        out.mIndices.PushBack( j );
          foundVertex = true;
          break;
        }
      // Did we find a vertex ?
      if ( !foundVertex )
      {
 -      // Add a new vertex
 -      faces[ i ] = vertexIndex++;
 -      out.push_back( v );
 +      // No so add a new one
 +      out.mVertices.PushBack( v );
 +      vertexIndex++;
      }
    }
  }
  
 -void AtlasManager::StitchMesh( MeshData& first,
 -                               const MeshData& second,
 +void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
 +                               const Toolkit::AtlasManager::Mesh2D& second,
                                 bool optimize )
  {
 +  uint32_t vc = first.mVertices.Size();
  
 -  // Would be much quicker to be able to get a non-const reference to these containers and update in situ
 -  MeshData::VertexContainer v1 = first.GetVertices();
 -  MeshData::VertexContainer v2 = second.GetVertices();
 -  MeshData::FaceIndices f1 = first.GetFaces();
 -  MeshData::FaceIndices f2 = second.GetFaces();
 -
 -  uint32_t vc1 = first.GetVertexCount();
 -  uint32_t vc2 = second.GetVertexCount();
 -
 -  for ( uint32_t v = 0; v < vc2; ++v )
 +  for ( uint32_t v = 0; v < second.mVertices.Size(); ++v )
    {
 -    v1.push_back( v2[ v ] );
 +    first.mVertices.PushBack( second.mVertices[ v ] );
    }
  
 -  for ( uint32_t f = 0; f < f2.size(); ++f )
 +  for ( uint32_t i = 0; i < second.mIndices.Size(); ++i )
    {
 -    f1.push_back( f2[ f ] + vc1 );
 +    first.mIndices.PushBack( second.mIndices[ i ] + vc );
    }
  
    if ( optimize )
    {
 -    MeshData::VertexContainer optimizedVertices;
 -    OptimizeVertices( v1, f1, optimizedVertices );
 -    first.SetVertices( optimizedVertices );
 -  }
 -  else
 -  {
 -    first.SetVertices( v1 );
 +    Toolkit::AtlasManager::Mesh2D optimizedMesh;
 +    OptimizeMesh( first, optimizedMesh );
 +    first = optimizedMesh;
    }
 -
 -  first.SetFaceIndices( f1 );
  }
  
 -void AtlasManager::StitchMesh( const MeshData& first,
 -                               const MeshData& second,
 -                               MeshData& out,
 +void AtlasManager::StitchMesh( const Toolkit::AtlasManager::Mesh2D& first,
 +                               const Toolkit::AtlasManager::Mesh2D& second,
 +                               Toolkit::AtlasManager::Mesh2D& out,
                                 bool optimize )
  {
 -  MeshData::VertexContainer v1 = first.GetVertices();
 -  MeshData::VertexContainer v2 = second.GetVertices();
 -  MeshData::FaceIndices f1 = first.GetFaces();
 -  MeshData::FaceIndices f2 = second.GetFaces();
 -
 -  uint32_t vc1 = first.GetVertexCount();
 -  uint32_t vc2 = second.GetVertexCount();
 -
 -  MeshData::VertexContainer vertices;
 -
 -  MeshData::FaceIndices faces;
 -
 -  MeshData::Vertex vertex;
 +  uint32_t vc = first.mVertices.Size();
  
 -  for ( uint32_t v = 0; v < vc1; ++v )
 +  for ( uint32_t v = 0; v < vc; ++v )
    {
 -    vertices.push_back( v1[ v ] );
 +    out.mVertices.PushBack( first.mVertices[ v ] );
    }
  
 -  for ( uint32_t v = 0; v < vc2; ++v )
 +  for ( uint32_t v = 0; v < second.mVertices.Size(); ++v )
    {
 -    vertices.push_back( v2[ v  ] );
 +    out.mVertices.PushBack( second.mVertices[ v ] );
    }
  
 -  for ( uint32_t f = 0; f < f1.size(); ++f )
 +  for ( uint32_t i = 0; i < first.mIndices.Size(); ++i )
    {
 -    faces.push_back( f1[ f ] );
 +    out.mIndices.PushBack( first.mIndices[ i ] );
    }
  
 -  for ( uint32_t f = 0; f < f2.size(); ++f )
 +  for ( uint32_t i = 0; i < second.mIndices.Size(); ++i )
    {
 -    faces.push_back( f2[ f ] + vc1 );
 +    out.mIndices.PushBack( second.mIndices[ i ] + vc );
    }
  
    if ( optimize )
    {
 -    MeshData::VertexContainer optimizedVertices;
 -    OptimizeVertices( vertices, faces, optimizedVertices );
 -    out.SetVertices( optimizedVertices );
 +    Toolkit::AtlasManager::Mesh2D optimizedMesh;
 +    OptimizeMesh( out, optimizedMesh );
 +    out = optimizedMesh;
    }
 -  else
 -  {
 -    out.SetVertices( vertices );
 -  }
 -
 -  out.SetMaterial( first.GetMaterial() );
 -  out.SetFaceIndices( faces );
  }
  
  void AtlasManager::UploadImage( const BufferImage& image,
    {
      DALI_LOG_ERROR("Uploading image to Atlas Failed!.\n");
    }
 +  else
 +  {
 +     mUploadedImages.PushBack( const_cast< BufferImage& >( image ).GetBuffer() );
 +  }
  
    // If this is the first block then we need to keep the first pixel free for underline texture
    if ( block )
      {
        DALI_LOG_ERROR("Uploading top strip to Atlas Failed!\n");
      }
 +    else
 +    {
 +      mUploadedImages.PushBack( NULL );
 +    }
  
      // Blit left strip
      if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip,
      {
        DALI_LOG_ERROR("Uploading left strip to Atlas Failed!\n");
      }
 +    else
 +    {
 +      mUploadedImages.PushBack( NULL );
 +    }
    }
  
    // Blit bottom strip
      {
        DALI_LOG_ERROR("Uploading bottom strip to Atlas Failed!.\n");
      }
 +    else
 +    {
 +     mUploadedImages.PushBack( NULL );
 +    }
    }
  
    // Blit right strip
      {
        DALI_LOG_ERROR("Uploading right strip to Atlas Failed!.\n");
      }
 +    else
 +    {
 +      mUploadedImages.PushBack( NULL );
 +    }
    }
  }
  
  void AtlasManager::GenerateMeshData( ImageId id,
                                       const Vector2& position,
-                                      Toolkit::AtlasManager::Mesh2D& meshData )
 -                                     MeshData& meshData,
++                                     Toolkit::AtlasManager::Mesh2D& meshData,
+                                      bool addReference )
  {
    // Read the atlas Id to use for this image
    SizeType imageId = id - 1u;
  
    CreateMesh( atlas, width, height, position, widthInBlocks, heightInBlocks, meshData, mImageList[ imageId ] );
  
-   // Mesh created so increase the reference count
-   mImageList[ imageId ].mCount++;
+   // Mesh created so increase the reference count, if we're asked to
+   if ( addReference )
+   {
+     mImageList[ imageId ].mCount++;
+   }
  }
  
  Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
@@@ -865,26 -830,6 +869,26 @@@ void AtlasManager::GetMetrics( Toolkit:
    metrics.mTextureMemoryUsed = textureMemoryUsed;
  }
  
 +Material AtlasManager::GetMaterial( AtlasId atlas ) const
 +{
 +  if ( atlas && atlas <= mAtlasList.size() )
 +  {
 +    return mAtlasList[ atlas -1u ].mMaterial;
 +  }
 +  Material null;
 +  return null;
 +}
 +
 +Sampler AtlasManager::GetSampler( AtlasId atlas ) const
 +{
 +  if ( atlas && atlas <= mAtlasList.size() )
 +  {
 +    return mAtlasList[ atlas -1u ].mSampler;
 +  }
 +  Sampler null;
 +  return null;
 +}
 +
  } // namespace Internal
  
  } // namespace Toolkit
@@@ -46,7 -46,7 +46,7 @@@ typedef Dali::Vector< Toolkit::AtlasMan
  class AtlasManager;
  typedef IntrusivePtr<AtlasManager> AtlasManagerPtr;
  
 -class AtlasManager : public Dali::BaseObject
 +class AtlasManager : public Dali::BaseObject, public ConnectionTracker
  {
  public:
  
@@@ -67,7 -67,6 +67,7 @@@
      BufferImage mFilledPixelImage;                                      // Image used by atlas for operations such as underline
      PixelBuffer* mStripBuffer;                                          // Blank image buffer used to pad upload
      Material mMaterial;                                                 // material used for atlas texture
 +    Sampler mSampler;                                                   // sampler used for atlas texture
      SizeType mNextFreeBlock;                                            // next free block will be placed here ( actually +1 )
      Dali::Vector< SizeType > mFreeBlocksList;                           // unless there are any previously freed blocks
    };
     */
    void GenerateMeshData( ImageId id,
                           const Vector2& position,
-                          Toolkit::AtlasManager::Mesh2D& mesh );
 -                         MeshData& mesh,
++                         Toolkit::AtlasManager::Mesh2D& mesh,
+                          bool addReference );
  
    /**
     * @copydoc Toolkit::AtlasManager::StitchMesh
     */
 -  void StitchMesh( MeshData& first,
 -                   const MeshData& second,
 +  void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
 +                   const Toolkit::AtlasManager::Mesh2D& second,
                     bool optimize );
  
    /**
     * @copydoc Toolkit::AtlasManager::StitchMesh
     */
 -  void StitchMesh( const MeshData& first,
 -                   const MeshData& second,
 -                   MeshData& out, bool optimize );
 +  void StitchMesh(  const Toolkit::AtlasManager::Mesh2D& first,
 +                    const Toolkit::AtlasManager::Mesh2D& second,
 +                    Toolkit::AtlasManager::Mesh2D& out,
 +                    bool optimize );
  
    /**
     * @copydoc Toolkit::AtlasManager::Remove
     */
    void GetMetrics( Toolkit::AtlasManager::Metrics& metrics );
  
 +  /**
 +   * @copydoc Toolkit::AtlasManager::GetMaterial
 +   */
 +  Material GetMaterial( AtlasId atlas ) const;
 +
 +/**
 +   * @copydoc Toolkit::AtlasManager::GetSampler
 +   */
 +  Sampler GetSampler( AtlasId atlas ) const;
 +
  private:
  
 -  std::vector< AtlasDescriptor > mAtlasList;        // List of atlases created
 -  std::vector< AtlasSlotDescriptor > mImageList;  // List of bitmaps store in atlases
 +  std::vector< AtlasDescriptor > mAtlasList;            // List of atlases created
 +  std::vector< AtlasSlotDescriptor > mImageList;        // List of bitmaps store in atlases
 +  Vector< PixelBuffer* > mUploadedImages;               // List of PixelBuffers passed to UploadedSignal
 +  Toolkit::AtlasManager::AtlasSize mNewAtlasSize;       // Atlas size to use in next creation
 +  Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;  // Policy for faling to add an Image
 +  SizeType mFilledPixel;                                // 32Bit pixel image for underlining
  
    SizeType CheckAtlas( SizeType atlas,
                         SizeType width,
                     const Vector2& position,
                     SizeType widthInBlocks,
                     SizeType heightInBlocks,
 -                   Dali::MeshData& meshData,
 +                   Toolkit::AtlasManager::Mesh2D& mesh,
                     AtlasSlotDescriptor& desc );
  
 -  void OptimizeVertices( const MeshData::VertexContainer& in,
 -                         MeshData::FaceIndices& faces,
 -                         MeshData::VertexContainer& out );
 +  void OptimizeMesh( const Toolkit::AtlasManager::Mesh2D& in,
 +                     Toolkit::AtlasManager::Mesh2D& out );
  
    void UploadImage( const BufferImage& image,
                      const AtlasSlotDescriptor& desc );
  
 -  void PrintMeshData( const MeshData& meshData );
 +  void PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh );
 +
 +  void OnUpload( Image image );
 +
 +  Shader mShaderL8;
 +  Shader mShaderRgba;
  
 -  Toolkit::AtlasManager::AtlasSize mNewAtlasSize;
 -  Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;
 -  uint32_t mFilledPixel;
  };
  
  } // namespace Internal
@@@ -69,23 -69,25 +69,25 @@@ bool AtlasManager::Remove( ImageId id 
  
  void AtlasManager::GenerateMeshData( ImageId id,
                                       const Vector2& position,
-                                      Mesh2D& mesh )
 -                                     MeshData& meshData,
++                                     Mesh2D& mesh,
+                                      bool addReference )
  {
    GetImplementation(*this).GenerateMeshData( id,
                                               position,
-                                              mesh );
 -                                             meshData,
++                                             mesh,
+                                              addReference );
  }
  
 -void AtlasManager::StitchMesh( MeshData& first,
 -                               const MeshData& second,
 +void AtlasManager::StitchMesh( Mesh2D& first,
 +                               const Mesh2D& second,
                                 bool optimize )
  {
    GetImplementation(*this).StitchMesh( first, second, optimize );
  }
  
 -void AtlasManager::StitchMesh( const MeshData& first,
 -                               const MeshData& second,
 -                               MeshData& out,
 +void AtlasManager::StitchMesh( const Mesh2D& first,
 +                               const Mesh2D& second,
 +                               Mesh2D& out,
                                 bool optimize )
  {
    GetImplementation(*this).StitchMesh( first, second, out, optimize );
@@@ -128,17 -130,7 +130,17 @@@ Pixel::Format AtlasManager::GetPixelFor
  
  void AtlasManager::GetMetrics( Metrics& metrics )
  {
 -  return GetImplementation(*this).GetMetrics( metrics );
 +  GetImplementation(*this).GetMetrics( metrics );
 +}
 +
 +Material AtlasManager::GetMaterial( AtlasId atlas ) const
 +{
 +  return GetImplementation(*this).GetMaterial( atlas );
 +}
 +
 +Sampler AtlasManager::GetSampler( AtlasId atlas ) const
 +{
 +  return GetImplementation(*this).GetSampler( atlas );
  }
  
  } // namespace Toolkit
@@@ -20,9 -20,9 +20,9 @@@
  // EXTERNAL INCLUDES
  #include <stdint.h>
  #include <dali/public-api/common/dali-vector.h>
 -#include <dali/devel-api/geometry/mesh-data.h>
 -#include <dali/devel-api/images/atlas.h>
  #include <dali/public-api/images/buffer-image.h>
 +#include <dali/devel-api/images/atlas.h>
 +#include <dali/devel-api/rendering/material.h>
  
  namespace Dali
  {
@@@ -187,18 -187,6 +187,18 @@@ public
      Dali::Vector< AtlasMetricsEntry > mAtlasMetrics;    // container of atlas information
    };
  
 +  struct Vertex2D
 +  {
 +    Vector2 mPosition;
 +    Vector2 mTexCoords;
 +  };
 +
 +  struct Mesh2D
 +  {
 +    Vector< Vertex2D > mVertices;
 +    Vector< unsigned int> mIndices;
 +  };
 +
    /**
     * Create an AtlasManager handle; this can be initialised with AtlasManager::New()
     * Calling member functions with an uninitialised handle is not allowed.
     * @param[in] id Image Id returned in the AtlasSlot from the add operation
     * @param[in] position position of the resulting mesh in model space
     * @param[out] mesh Mesh Data Object to populate with mesh data
+    * @param[in] addReference Whether to increase the internal reference count for image or not
     */
    void GenerateMeshData( ImageId id,
                           const Vector2& position,
-                          Mesh2D& mesh );
 -                         MeshData& mesh,
++                         Mesh2D& mesh,
+                          bool addReference = true );
  
    /**
     * @brief Append second mesh to the first mesh
     * @param[in] second Second mesh
     * @param[in] optimize should we optimize vertex data
     */
 -  void StitchMesh( MeshData& first,
 -                   const MeshData& second,
 +  void StitchMesh( Mesh2D& first,
 +                   const Mesh2D& second,
                     bool optimize = false );
  
    /**
     * @param[in] optimize should we optimize vertex data
     * @param[out] out resulting mesh
     */
 -  void StitchMesh( const MeshData& first,
 -                   const MeshData& second,
 -                   MeshData& out,
 +  void StitchMesh( const Mesh2D& first,
 +                   const Mesh2D& second,
 +                   Mesh2D& out,
                     bool optimize = false );
  
    /**
     */
    void GetMetrics( Metrics& metrics );
  
 +  /**
 +   * @brief Get Material used by atlas
 +   *
 +   * @param atlas[in] atlas AtlasId
 +   *
 +   * @return Material used by atlas
 +   */
 +  Material GetMaterial( AtlasId atlas ) const;
 +
 + /**
 +   * @brief Get Sampler used by atlas
 +   *
 +   * @param atlas[in] atlas AtlasId
 +   *
 +   * @return Sampler used by atlas
 +   */
 +  Sampler GetSampler( AtlasId atlas ) const;
  private:
  
    explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
  
  } // namespace Dali
  
 -#endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__
 +#endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__
@@@ -17,7 -17,7 +17,7 @@@
  
  // EXTERNAL INCLUDES
  #include <dali/public-api/actors/layer.h>
 -#include <dali/public-api/actors/renderable-actor.h>
 +#include <dali/public-api/actors/image-actor.h>
  #include <dali/integration-api/debug.h>
  
  // INTERNAL INCLUDES
@@@ -134,7 -134,7 +134,7 @@@ AlphaFunction GetAlphaFunction( const s
    }
    else
    {
-     DALI_ASSERT_ALWAYS( iter != alphaFunctionLut.end() && "Unknown Anchor Constant" );
+     DALI_ASSERT_ALWAYS( iter != alphaFunctionLut.end() && "Unknown Alpha Constant" );
      return Dali::AlphaFunction::DEFAULT;
    }
  }
@@@ -229,13 -229,13 +229,13 @@@ Animation CreateAnimation( const TreeNo
          // to allow animating shader uniforms
          if( propIndex == Property::INVALID_INDEX )
          {
 -          RenderableActor renderable = RenderableActor::DownCast( targetHandle );
 -          if( renderable )
 +          ImageActor imageActor = ImageActor::DownCast( targetHandle );
 +          if( imageActor )
            {
              // A limitation here is that its possible that between creation of animation
              // and running it the ShaderEffect of the actor has been changed.
              // However this is a unlikely use case especially when using scripts.
 -            if( ShaderEffect effect = renderable.GetShaderEffect() )
 +            if( ShaderEffect effect = imageActor.GetShaderEffect() )
              {
                propIndex = effect.GetPropertyIndex( *property );
                if(propIndex != Property::INVALID_INDEX)
@@@ -176,11 -176,6 +176,6 @@@ std::string PropertyValueToString( cons
        ret = std::string("Map Size=") + ToString( value.Get<Property::Map>().Count() );
        break;
      }
-     case Property::TYPE_COUNT:
-     {
-       ret = "";
-       break;
-     }
    }
  
    return ret;
@@@ -263,7 -258,7 +258,7 @@@ void Builder::SetProperties( const Tree
        // special field 'effect' references the shader effect instances
        if(key == "effect")
        {
 -        RenderableActor actor = RenderableActor::DownCast(handle);
 +        ImageActor actor = ImageActor::DownCast(handle);
          if( actor )
          {
            OptionalString str = constant.IsString( keyChild.second );
  
        if( Property::INVALID_INDEX == index )
        {
 -        RenderableActor actor = RenderableActor::DownCast(handle);
 +        ImageActor actor = ImageActor::DownCast(handle);
          if( actor )
          {
            if( ShaderEffect effect = actor.GetShaderEffect() )
@@@ -721,11 -716,12 +716,12 @@@ FrameBufferImage Builder::GetFrameBuffe
      {
        if( OptionalChild image = IsChild( *images, name ) )
        {
-         Dali::Property::Value propertyMap(Property::MAP);
-         if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) )
+         Dali::Property::Value property(Property::MAP);
+         if( SetPropertyFromNode( *image, Property::MAP, property, constant ) )
          {
-           propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage")));
-           ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( propertyMap ) );
+           Property::Map* map = property.GetMap();
+           (*map)[ KEYNAME_TYPE ] = Property::Value(std::string("FrameBufferImage") );
+           ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( property ) );
            mFrameBufferImageLut[ name ] = ret;
          }
        }
  #include <dali/public-api/common/stage.h>
  #include <dali/public-api/render-tasks/render-task-list.h>
  #include <dali/public-api/images/resource-image.h>
+ #include <dali/public-api/object/type-registry.h>
+ #include <dali/devel-api/object/type-registry-helper.h>
  
- using namespace Dali;
+ namespace Dali
+ {
+ namespace Toolkit
+ {
+ namespace Internal
+ {
  
  namespace // unnamed namespace
  {
  
+ Dali::BaseHandle Create()
+ {
+   return Toolkit::Magnifier::New();
+ }
+ DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Magnifier, Toolkit::Control, Create )
+ DALI_PROPERTY_REGISTRATION( Toolkit, Magnifier, "frame-visibility",     BOOLEAN, FRAME_VISIBILITY     )
+ DALI_PROPERTY_REGISTRATION( Toolkit, Magnifier, "magnification-factor", FLOAT,   MAGNIFICATION_FACTOR )
+ DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Magnifier, "source-position", VECTOR3, SOURCE_POSITION )
+ DALI_TYPE_REGISTRATION_END()
  const char* DEFAULT_FRAME_IMAGE_PATH = DALI_IMAGE_DIR "magnifier-image-frame.png";
  
  const float IMAGE_BORDER_INDENT = 14.0f;            ///< Indent of border in pixels.
@@@ -92,16 -116,7 +116,7 @@@ struct RenderTaskViewportSizeConstrain
    }
  };
  
- }
- namespace Dali
- {
- namespace Toolkit
- {
- namespace Internal
- {
+ } // unnamed namespace
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////
  // Magnifier
@@@ -124,7 -139,6 +139,6 @@@ Dali::Toolkit::Magnifier Magnifier::New
  
  Magnifier::Magnifier()
  : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
-   mPropertySourcePosition(Property::INVALID_INDEX),
    mDefaultCameraDistance(1000.f),
    mActorSize(Vector3::ZERO),
    mMagnificationFactor(1.0f)
@@@ -136,15 -150,9 +150,9 @@@ void Magnifier::SetSourceActor(Actor ac
    mTask.SetSourceActor( actor );
  }
  
- void Magnifier::SetSourcePosition(const Vector3& position)
- {
-   Self().SetProperty(mPropertySourcePosition, position);
- }
  void Magnifier::Initialize()
  {
    Actor self = Self();
-   mPropertySourcePosition = self.RegisterProperty( Toolkit::Magnifier::SOURCE_POSITION_PROPERTY_NAME, Vector3::ZERO );
    Vector2 stageSize(Stage::GetCurrent().GetSize());
  
    // NOTE:
    Stage().GetCurrent().Add(mSourceActor);
    mSourceActor.SetParentOrigin(ParentOrigin::CENTER);
    Constraint constraint = Constraint::New<Vector3>( mSourceActor, Actor::Property::POSITION, EqualToConstraint() );
-   constraint.AddSource( Source( self, mPropertySourcePosition ) );
+   constraint.AddSource( Source( self, Toolkit::Magnifier::Property::SOURCE_POSITION ) );
    constraint.Apply();
  
    // create the render task this will render content on top of everything
@@@ -247,6 -255,7 +255,6 @@@ void Magnifier::SetFrameVisibility(boo
  
      Image image = ResourceImage::New( DEFAULT_FRAME_IMAGE_PATH );
      mFrame = ImageActor::New( image );
 -    mFrame.SetDrawMode(DrawMode::OVERLAY);
      mFrame.SetStyle( ImageActor::STYLE_NINE_PATCH );
      mFrame.SetPositionInheritanceMode(DONT_INHERIT_POSITION);
      mFrame.SetInheritScale(true);
@@@ -316,6 -325,56 +324,56 @@@ void Magnifier::Update(
    mCameraActor.SetAspectRatio( worldSize.width / worldSize.height );
  }
  
+ void Magnifier::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+ {
+   Toolkit::Magnifier magnifier = Toolkit::Magnifier::DownCast( Dali::BaseHandle( object ) );
+   if( magnifier )
+   {
+     Magnifier& magnifierImpl( GetImpl( magnifier ) );
+     switch( index )
+     {
+       case Toolkit::Magnifier::Property::FRAME_VISIBILITY:
+       {
+         magnifierImpl.SetFrameVisibility( value.Get< bool >() );
+         break;
+       }
+       case Toolkit::Magnifier::Property::MAGNIFICATION_FACTOR:
+       {
+         magnifierImpl.SetMagnificationFactor( value.Get< float >() );
+         break;
+       }
+     }
+   }
+ }
+ Property::Value Magnifier::GetProperty( BaseObject* object, Property::Index index )
+ {
+   Property::Value value;
+   Toolkit::Magnifier magnifier = Toolkit::Magnifier::DownCast( Dali::BaseHandle( object ) );
+   if( magnifier )
+   {
+     Magnifier& magnifierImpl( GetImpl( magnifier ) );
+     switch( index )
+     {
+       case Toolkit::Magnifier::Property::FRAME_VISIBILITY:
+       {
+         value = magnifierImpl.GetFrameVisibility();
+         break;
+       }
+       case Toolkit::Magnifier::Property::MAGNIFICATION_FACTOR:
+       {
+         value = magnifierImpl.GetMagnificationFactor();
+         break;
+       }
+     }
+   }
+   return value;
+ }
  } // namespace Internal
  
  } // namespace Toolkit
  
  // EXTERNAL INCLUDES
  #include <cstring> // for strcmp
- #include <dali/integration-api/debug.h>
  #include <dali/public-api/animation/constraint.h>
  #include <dali/public-api/animation/constraints.h>
+ #include <dali/public-api/images/resource-image.h>
  #include <dali/public-api/object/type-registry.h>
+ #include <dali/public-api/object/property-array.h>
  #include <dali/devel-api/object/type-registry-helper.h>
- #include <dali/public-api/images/resource-image.h>
+ #include <dali/integration-api/debug.h>
  
  // INTERNAL INCLUDES
  #include <dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h>
@@@ -218,6 -220,7 +220,6 @@@ void ScrollBar::SetScrollIndicator( Act
  
      Actor self = Self();
      self.Add(mIndicator);
 -    self.SetDrawMode(DrawMode::OVERLAY);
  
      if( !mPanGestureDetector )
      {
@@@ -599,16 -602,19 +601,19 @@@ void ScrollBar::SetProperty( BaseObject
        }
        case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
        {
-         Dali::Vector<float> positions;
-         size_t positionCount = value.GetSize();
-         positions.Resize( positionCount );
-         for( size_t i = 0; i != positionCount; ++i )
+         Property::Array* array = value.GetArray();
+         if( array )
          {
-           value.GetItem(i).Get( positions[i] );
+           Dali::Vector<float> positions;
+           size_t positionCount = array->Count();
+           positions.Resize( positionCount );
+           for( size_t i = 0; i != positionCount; ++i )
+           {
+             array->GetElementAt( i ).Get( positions[i] );
+           }
+           scrollBarImpl.SetScrollPositionIntervals(positions);
          }
-         scrollBarImpl.SetScrollPositionIntervals(positions);
          break;
        }
      }
@@@ -653,12 -659,13 +658,13 @@@ Property::Value ScrollBar::GetProperty
        }
        case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
        {
-         Property::Value value;
+         Property::Value value( Property::ARRAY );
+         Property::Array* array = value.GetArray();
          Dali::Vector<float> positions = scrollBarImpl.GetScrollPositionIntervals();
-         size_t positionCount( positions.Size() );
+         size_t positionCount( array->Count() );
          for( size_t i( 0 ); i != positionCount; ++i )
          {
-           value.AppendItem( positions[i] );
+           array->PushBack( positions[i] );
          }
          break;
        }
@@@ -53,6 -53,8 +53,8 @@@ DALI_ANIMATABLE_PROPERTY_REGISTRATION( 
  DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layout-orientation",  INTEGER,  LAYOUT_ORIENTATION)
  DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scroll-content-size", FLOAT,    SCROLL_CONTENT_SIZE)
  
+ DALI_SIGNAL_REGISTRATION(              Toolkit, ItemView, "layout-activated",    LAYOUT_ACTIVATED_SIGNAL )
  DALI_TYPE_REGISTRATION_END()
  
  const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f;
@@@ -422,6 -424,11 +424,11 @@@ void ItemView::ActivateLayout(unsigned 
      mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnLayoutActivationScrollFinished);
      mScrollAnimation.Play();
    }
+   else
+   {
+     // Emit the layout activated signal
+     mLayoutActivatedSignal.Emit();
+   }
  
    AnimateScrollOvershoot(0.0f);
    mScrollOvershoot = 0.0f;
@@@ -1298,6 -1305,9 +1305,9 @@@ void ItemView::OnLayoutActivationScroll
    RemoveAnimation(mScrollAnimation);
    mRefreshEnabled = true;
    DoRefresh(GetCurrentLayoutPosition(0), true);
+   // Emit the layout activated signal
+   mLayoutActivatedSignal.Emit();
  }
  
  void ItemView::OnOvershootOnFinished(Animation& animation)
@@@ -1467,6 -1477,7 +1477,6 @@@ void ItemView::EnableScrollOvershoot( b
      mOvershootOverlay.SetColor(mOvershootEffectColor);
      mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT);
      mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT);
 -    mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY);
      self.Add(mOvershootOverlay);
  
      Constraint constraint = Constraint::New<Vector3>( mOvershootOverlay, Actor::Property::SIZE, OvershootOverlaySizeConstraint );
@@@ -1624,6 -1635,26 +1634,26 @@@ void ItemView::OnScrollPositionChanged
    DoRefresh(position, false); // No need to cache extra items.
  }
  
+ bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+ {
+   Dali::BaseHandle handle( object );
+   bool connected( true );
+   Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( handle );
+   if( 0 == strcmp( signalName.c_str(), LAYOUT_ACTIVATED_SIGNAL ) )
+   {
+     itemView.LayoutActivatedSignal().Connect( tracker, functor );
+   }
+   else
+   {
+     // signalName does not match any signal
+     connected = false;
+   }
+   return connected;
+ }
  } // namespace Internal
  
  } // namespace Toolkit
@@@ -570,6 -570,7 +570,6 @@@ void Slider::CreateHandleValueDisplay(
      mHandleValueTextLabel.SetAnchorPoint( AnchorPoint::CENTER );
      mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
      mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
 -    mHandleValueTextLabel.SetDrawMode( DrawMode::OVERLAY );
      mHandle.Add( mHandleValueTextLabel );
    }
  }
@@@ -724,7 -725,7 +724,7 @@@ float Slider::MarkFilter( float value 
    const float MARK_TOLERANCE = GetMarkTolerance();
  
    float mark;
-   for( std::size_t i = 0; i < mMarks.Size(); ++i)
+   for( MarkList::SizeType i = 0; i < mMarks.Count(); ++i)
    {
      const Property::Value& propertyValue = mMarks[i];
      propertyValue.Get( mark );
@@@ -746,7 -747,7 +746,7 @@@ float Slider::SnapToMark( float value 
    float closestDist = std::numeric_limits<float>::max();
  
    float mark;
-   for( std::size_t i = 0; i < mMarks.Size(); ++i)
+   for( MarkList::SizeType  i = 0; i < mMarks.Count(); ++i)
    {
      const Property::Value& propertyValue = mMarks[i];
      propertyValue.Get( mark );
@@@ -62,7 -62,7 +62,7 @@@ namespace // unnamed namespac
  namespace
  {
  
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::HorizontalAlignment > HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
  {
    { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
    { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
@@@ -70,7 -70,7 +70,7 @@@
  };
  const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
  
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::VerticalAlignment > VERTICAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
  {
    { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
    { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
@@@ -251,11 -251,14 +251,14 @@@ void TextField::SetProperty( BaseObject
            const std::string alignStr = value.Get< std::string >();
            DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %f\n", impl.mController.Get(), alignStr.c_str() );
  
-           const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
-                                                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-           impl.mController->SetHorizontalAlignment( alignment );
+           LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+           if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
+                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                               alignment ) )
+           {
+             impl.mController->SetHorizontalAlignment( alignment );
+           }
          }
          break;
        }
            const std::string alignStr = value.Get< std::string >();
            DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %f\n", impl.mController.Get(), alignStr.c_str() );
  
-           LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
-                                                                                                                     VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                     VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
-           impl.mController->SetVerticalAlignment( alignment );
+           LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
+           if( Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
+                                                                             VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                             VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                             alignment ) )
+           {
+             impl.mController->SetVerticalAlignment( alignment );
+           }
          }
          break;
        }
@@@ -612,9 -618,13 +618,13 @@@ Property::Value TextField::GetProperty
        {
          if( impl.mController )
          {
-           value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
-                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
+                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+           if( name )
+           {
+             value = std::string( name );
+           }
          }
          break;
        }
        {
          if( impl.mController )
          {
-           value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
-                                                                                                                   VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                   VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
+                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+           if( name )
+           {
+             value = std::string( name );
+           }
          }
          break;
        }
@@@ -859,7 -873,8 +873,8 @@@ void TextField::OnInitialize(
  
    mController = Text::Controller::New( *this );
  
-   mDecorator = Text::Decorator::New( *this, *mController );
+   mDecorator = Text::Decorator::New( *mController,
+                                      *mController );
  
    mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
  
    // Fill-parent area by default
    self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
    self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
 +  self.OnStageSignal().Connect( this, &TextField::OnStageConnect );
  }
  
  void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@@ -917,40 -931,54 +932,58 @@@ void TextField::OnRelayout( const Vecto
        mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
      }
  
 -    RenderableActor renderableActor;
 -    if( mRenderer )
 -    {
 -      renderableActor = mRenderer->Render( mController->GetView() );
 -    }
 -
 +    RenderText();
      EnableClipping( (Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy), size );
 +  }
 +}
  
 -    if( renderableActor != mRenderableActor )
 -    {
 -      UnparentAndReset( mRenderableActor );
 -      mRenderableActor = renderableActor;
 -    }
 +void TextField::RenderText()
 +{
 +  Actor renderableActor;
 +  if( mRenderer )
 +  {
 +    renderableActor = mRenderer->Render( mController->GetView(), mDepth );
 +  }
  
 -    if( mRenderableActor )
 -    {
 -      const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
 +  if( renderableActor != mRenderableActor )
 +  {
 +    UnparentAndReset( mRenderableActor );
 +    mRenderableActor = renderableActor;
 +  }
  
 -      mRenderableActor.SetPosition( offset.x, offset.y );
 +  if( mRenderableActor )
 +  {
 +    const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
  
 -      // Make sure the actor is parented correctly with/without clipping
 -      if( mClipper )
 -      {
 -        mClipper->GetRootActor().Add( mRenderableActor );
 -      }
 -      else
 -      {
 -        Self().Add( mRenderableActor );
 -      }
 +    mRenderableActor.SetPosition( offset.x, offset.y );
 +
 +    // Make sure the actor is parented correctly with/without clipping
 +    if( mClipper )
 +    {
 +      mClipper->GetRootActor().Add( mRenderableActor );
 +    }
 +    else
 +    {
 +      Self().Add( mRenderableActor );
      }
+     for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
+            endIt = mClippingDecorationActors.end();
+          it != endIt;
+          ++it )
+     {
+       Actor actor = *it;
+       if( mClipper )
+       {
+         mClipper->GetRootActor().Add( actor );
+       }
+       else
+       {
+         Self().Add( actor );
+       }
+     }
+     mClippingDecorationActors.clear();
    }
  }
  
@@@ -1036,10 -1064,19 +1069,19 @@@ bool TextField::OnKeyEvent( const KeyEv
    return mController->KeyEvent( event );
  }
  
ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
void TextField::AddDecoration( Actor& actor, bool needsClipping )
  {
-   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
-   return mController->OnImfEvent( imfManager, imfEvent );
+   if( actor )
+   {
+     if( needsClipping )
+     {
+       mClippingDecorationActors.push_back( actor );
+     }
+     else
+     {
+       Self().Add( actor );
+     }
+   }
  }
  
  void TextField::RequestTextRelayout()
@@@ -1053,24 -1090,18 +1095,30 @@@ void TextField::TextChanged(
    mTextChangedSignal.Emit( handle );
  }
  
 +void TextField::OnStageConnect( Dali::Actor actor )
 +{
 +  if ( mHasBeenStaged )
 +  {
 +    RenderText();
 +  }
 +  else
 +  {
 +    mHasBeenStaged = true;
 +  }
 +}
 +
  void TextField::MaxLengthReached()
  {
    Dali::Toolkit::TextField handle( GetOwner() );
    mMaxLengthReachedSignal.Emit( handle );
  }
  
+ ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+ {
+   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
+   return mController->OnImfEvent( imfManager, imfEvent );
+ }
  void TextField::EnableClipping( bool clipping, const Vector2& size )
  {
    if( clipping )
@@@ -1110,11 -1141,6 +1158,11 @@@ void TextField::KeyboardStatusChanged(b
    }
  }
  
 +void TextField::OnStageConnection( unsigned int depth )
 +{
 +  mDepth = depth;
 +}
 +
  bool TextField::OnTouched( Actor actor, const TouchEvent& event )
  {
    return true;
  TextField::TextField()
  : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
    mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
 -  mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP )
 +  mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
 +  mDepth( 0 ),
 +  mHasBeenStaged( false )
  {
  }
  
@@@ -137,19 -137,14 +137,19 @@@ private: // From Contro
    virtual void OnPan( const PanGesture& gesture );
  
    /**
 +   * @copydoc Control::OnStageConnection()
 +   */
 +  virtual void OnStageConnection( unsigned int depth );
 +
 +  /**
     * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&)
     */
    virtual bool OnKeyEvent(const KeyEvent& event);
  
    /**
-    * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
+    * @copydoc Text::ControlInterface::AddDecoration()
     */
-   ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
+   virtual void AddDecoration( Actor& actor, bool needsClipping );
  
    /**
     * @copydoc Text::ControlInterface::RequestTextRelayout()
     */
    virtual void MaxLengthReached();
  
+   /**
+    * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
+    */
+   ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
  private: // Implementation
  
    /**
    TextField(const TextField&);
    TextField& operator=(const TextField& rhs);
  
 +  /**
 +   * @brief Render view, create and attach actor(s) to this Text Field.
 +   */
 +  void RenderText();
 +
 +  // Connection needed to re-render text, when a Text Field returns to the stage.
 +  void OnStageConnect( Dali::Actor actor );
 +
  private: // Data
  
    // Signals
    Text::RendererPtr mRenderer;
    Text::DecoratorPtr mDecorator;
    Text::ClipperPtr mClipper; ///< For EXCEED_POLICY_CLIP
+   std::vector<Actor> mClippingDecorationActors;   ///< Decoration actors which need clipping.
  
 -  RenderableActor mRenderableActor;
 +  Actor mRenderableActor;
  
    int mRenderingBackend;
    int mExceedPolicy;
 +  unsigned int mDepth;
 +  bool mHasBeenStaged:1;
  };
  
  } // namespace Internal
@@@ -50,7 -50,7 +50,7 @@@ namespac
  namespace
  {
  
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::HorizontalAlignment > HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
  {
    { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
    { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
@@@ -58,7 -58,7 +58,7 @@@
  };
  const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
  
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::VerticalAlignment > VERTICAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
  {
    { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
    { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
@@@ -189,11 -189,14 +189,14 @@@ void TextLabel::SetProperty( BaseObject
        {
          if( impl.mController )
          {
-           const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
-                                                                                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-           impl.mController->SetHorizontalAlignment( alignment );
+           LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+           if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
+                                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                              alignment ) )
+           {
+             impl.mController->SetHorizontalAlignment( alignment );
+           }
          }
          break;
        }
        {
          if( impl.mController )
          {
-           const LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
-                                                                                                                                          VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                                          VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
-           impl.mController->SetVerticalAlignment( alignment );
+           LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
+           if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
+                                                                                            VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                            VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                            alignment ) )
+           {
+             impl.mController->SetVerticalAlignment( alignment );
+           }
          }
          break;
        }
@@@ -356,9 -362,13 +362,13 @@@ Property::Value TextLabel::GetProperty
        {
          if( impl.mController )
          {
-           value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
-                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
+                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+           if( name )
+           {
+             value = std::string( name );
+           }
          }
          break;
        }
        {
          if( impl.mController )
          {
-           value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
-                                                                                                                 VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                 VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
+                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+           if( name )
+           {
+             value = std::string( name );
+           }
          }
          break;
        }
@@@ -439,7 -453,6 +453,7 @@@ void TextLabel::OnInitialize(
    // Enable the text ellipsis.
    LayoutEngine& engine = mController->GetLayoutEngine();
    engine.SetTextEllipsisEnabled( true );
 +  self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
  }
  
  void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@@ -466,53 -479,38 +480,58 @@@ void TextLabel::OnRelayout( const Vecto
      {
        mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
      }
 +    RenderText();
 +  }
 +}
  
 -    RenderableActor renderableActor;
 -    if( mRenderer )
 -    {
 -      renderableActor = mRenderer->Render( mController->GetView() );
 -    }
 +void TextLabel::RequestTextRelayout()
 +{
 +  RelayoutRequest();
 +}
  
 -    if( renderableActor != mRenderableActor )
 -    {
 -      UnparentAndReset( mRenderableActor );
 +void TextLabel::RenderText()
 +{
 +  Actor renderableActor;
 +  if( mRenderer )
 +  {
 +    renderableActor = mRenderer->Render( mController->GetView(), mDepth );
 +  }
  
 -      if( renderableActor )
 -      {
 -        const Vector2& alignmentOffset = mController->GetAlignmentOffset();
 -        renderableActor.SetPosition( alignmentOffset.x, alignmentOffset.y );
 +  if( renderableActor != mRenderableActor )
 +  {
 +    UnparentAndReset( mRenderableActor );
  
 -        Self().Add( renderableActor );
 -      }
 +    if( renderableActor )
 +    {
 +      const Vector2& alignmentOffset = mController->GetAlignmentOffset();
 +      renderableActor.SetPosition( alignmentOffset.x, alignmentOffset.y );
  
 -      mRenderableActor = renderableActor;
 +      Self().Add( renderableActor );
      }
 +    mRenderableActor = renderableActor;
 +  }
 +}
 +
 +void TextLabel::OnStageConnect( Dali::Actor actor )
 +{
 +  if ( mHasBeenStaged )
 +  {
 +    RenderText();
 +  }
 +  else
 +  {
 +    mHasBeenStaged = true;
    }
  }
  
 -void TextLabel::RequestTextRelayout()
+ void TextLabel::AddDecoration( Actor& actor, bool needsClipping )
+ {
+   // TextLabel does not show decorations
+ }
 +void TextLabel::OnStageConnection( unsigned int depth )
  {
 -  RelayoutRequest();
 +  mDepth = depth;
  }
  
  void TextLabel::TextChanged()
@@@ -527,9 -525,7 +546,9 @@@ void TextLabel::MaxLengthReached(
  
  TextLabel::TextLabel()
  : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
 -  mRenderingBackend( DEFAULT_RENDERING_BACKEND )
 +  mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
 +  mDepth( 0 ),
 +  mHasBeenStaged( false )
  {
  }
  
@@@ -93,11 -93,11 +93,16 @@@ private: // From Contro
    virtual float GetHeightForWidth( float width );
  
    /**
+    * @copydoc Text::ControlInterface::AddDecoration()
+    */
+   virtual void AddDecoration( Actor& actor, bool needsClipping );
+   /**
 +   * @copydoc Control::OnStageConnection()
 +   */
 +  virtual void OnStageConnection( unsigned int depth );
 +
 +  /**
     * @copydoc Text::ControlInterface::RequestTextRelayout()
     */
    virtual void RequestTextRelayout();
@@@ -130,22 -130,13 +135,22 @@@ private
    TextLabel(const TextLabel&);
    TextLabel& operator=(const TextLabel& rhs);
  
 +  // Connection needed to re-render text, when a Text Label returns to the stage
 +  void OnStageConnect( Dali::Actor actor );
 +
 +  /**
 +   * @brief Render view, create and attach actor(s) to this Text Label
 +   */
 +  void RenderText();
 +
  private: // Data
  
    Text::ControllerPtr mController;
    Text::RendererPtr mRenderer;
 -  RenderableActor mRenderableActor;
 -
 +  Actor mRenderableActor;
    int mRenderingBackend;
 +  unsigned int mDepth;
 +  bool mHasBeenStaged:1;
  };
  
  } // namespace Internal
@@@ -19,8 -19,7 +19,8 @@@
  #include <dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h>
  
  // INTERNAL INCLUDES
- #include <dali-toolkit/public-api/controls/buttons/push-button.h>
+ #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
 +#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
  #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
  #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
  
  #include <dali/public-api/images/resource-image.h>
  #include <dali/public-api/math/vector2.h>
  #include <dali/public-api/math/vector4.h>
+ #include <dali/devel-api/object/type-registry-helper.h>
  #include <libintl.h>
  #include <cfloat>
  
- // todo Move this to adaptor??
- #define GET_LOCALE_TEXT(string) dgettext("elementary", string)
  namespace Dali
  {
  
@@@ -46,15 -43,14 +44,14 @@@ namespace Interna
  
  namespace
  {
- const Dali::Vector4 DEFAULT_POPUP_BACKGROUND( Dali::Vector4( .20f, 0.29f, 0.44f, 1.0f ) );
- const Dali::Vector4 DEFAULT_POPUP_BACKGROUND_PRESSED( Dali::Vector4( 0.07f, 0.10f, 0.17f, 1.0f ) );
- const Dali::Vector4 DEFAULT_POPUP_LINE_COLOR( Dali::Vector4( 0.36f, 0.45f, 0.59f, 1.0f ) );
+ // todo Move this to adaptor??
+ #define GET_LOCALE_TEXT(string) dgettext("elementary", string)
+ const Dali::Vector4 DEFAULT_POPUP_LINE_COLOR( Dali::Vector4( 0.69f, 0.93f, 0.93f, 1.0f ) );
  const Dali::Vector4 DEFAULT_OPTION_ICON( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
- const Dali::Vector4 DEFAULT_OPTION_ICON_PRESSED( Dali::Vector4( 0.5f, 1.0f, 1.0f, 1.0f ) );
- const Dali::Vector4 DEFAULT_OPTION_TEXT( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
- const Dali::Vector4 DEFAULT_OPTION_TEXT_PRESSED( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
+ const Dali::Vector4 DEFAULT_OPTION_ICON_PRESSED( Dali::Vector4( 0.12f, 0.56f, 1.0f, 1.0f ) );
  
- const std::string DEFAULT_POPUP_BACKGROUND_IMAGE( DALI_IMAGE_DIR "popup_bubble_bg.#.png" );
+ const std::string DEFAULT_POPUP_BACKGROUND_IMAGE( DALI_IMAGE_DIR "selection-popup-bg#.png" );
  const std::string OPTION_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" );
  const std::string OPTION_ICON_COPY( DALI_IMAGE_DIR "copy_paste_icon_copy.png" );
  const std::string OPTION_ICON_CUT( DALI_IMAGE_DIR "copy_paste_icon_cut.png" );
@@@ -62,20 -58,27 +59,27 @@@ const std::string OPTION_ICON_PASTE( DA
  const std::string OPTION_ICON_SELECT( DALI_IMAGE_DIR "copy_paste_icon_select.png" );
  const std::string OPTION_ICON_SELECT_ALL( DALI_IMAGE_DIR "copy_paste_icon_select_all.png" );
  
- const Dali::Vector2 DEFAULT_POPUP_MAX_SIZE( 450.0f, 100.0f ); ///< The maximum size of the popup.
- const Dali::Vector2 OPTION_ICON_SIZE( 65.0f, 65.0f );       ///< The size of the icon.
  const float OPTION_MARGIN_WIDTH( 10.f );          ///< The margin between the right or lefts edge and the text or icon.
- const float OPTION_MAX_WIDTH( 110.0f );          ///< The maximum width of the option   //todo Make Property
- const float OPTION_MIN_WIDTH( 86.0f );           ///< The minimum width of the option. //todo Make Property
- const float POPUP_DIVIDER_WIDTH( 3.f );        ///< The size of the divider.
  
- const Dali::Vector2 POPUP_TAIL_SIZE( 20.0f, 16.0f ); ///< The size of the tail.
- const float POPUP_TAIL_Y_OFFSET( 5.f );        ///< The y offset of the tail (when its position is on the bottom).
- const float POPUP_TAIL_TOP_Y_OFFSET( 3.f );    ///< The y offset of the tail (when its position is on the top).
+ #ifdef DGETTEXT_ENABLED
+ #define POPUP_CUT_STRING GET_LOCALE_TEXT("IDS_COM_BODY_CUT")
+ #define POPUP_COPY_STRING GET_LOCALE_TEXT("IDS_COM_BODY_COPY")
+ #define POPUP_PASTE_STRING GET_LOCALE_TEXT("IDS_COM_BODY_PASTE")
+ #define POPUP_SELECT_STRING GET_LOCALE_TEXT("IDS_COM_SK_SELECT")
+ #define POPUP_SELECT_ALL_STRING GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL")
+ #define POPUP_CLIPBOARD_STRING GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD")
+ #else
  
- const float HIDE_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup hide animation in seconds.
- const float SHOW_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup show animation in seconds.
+ #define POPUP_CUT_STRING  "Cut"
+ #define POPUP_COPY_STRING  "Copy"
+ #define POPUP_PASTE_STRING  "Paste"
+ #define POPUP_SELECT_STRING  "Select"
+ #define POPUP_SELECT_ALL_STRING  "Select All"
+ #define POPUP_CLIPBOARD_STRING  "Clipboard"
+ #endif
  
  const char* const OPTION_SELECT_WORD = "option-select_word";                       // "Select Word" popup option.
  const char* const OPTION_SELECT_ALL("option-select_all");                          // "Select All" popup option.
@@@ -84,23 -87,43 +88,43 @@@ const char* const OPTION_COPY("option-c
  const char* const OPTION_PASTE("option-paste");                                    // "Paste" popup option.
  const char* const OPTION_CLIPBOARD("option-clipboard");                            // "Clipboard" popup option.
  
- } // namespace
+ BaseHandle Create()
+ {
+   return Toolkit::TextSelectionPopup::New( Toolkit::TextSelectionPopup::NONE, NULL );
+ }
+ // Setup properties, signals and actions using the type-registry.
+ DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextSelectionPopup, Toolkit::Control, Create );
  
- //// Comparison function for ButtonRequirement Priority
- //bool TextSelectionPopup::PriorityCompare( ButtonRequirement const& a, ButtonRequirement const& b )
- //{
- //  return a.priority < b.priority;
- //}
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-max-size", VECTOR2,   POPUP_MAX_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-min-size", VECTOR2,   POPUP_MIN_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "option-max-size", VECTOR2,   OPTION_MAX_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "option-min-size", VECTOR2,   OPTION_MIN_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "option-divider-size", VECTOR2,   OPTION_DIVIDER_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-clipboard-button-image", STRING, POPUP_CLIPBOARD_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-cut-button-image", STRING, POPUP_CUT_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-copy-button-image", STRING, POPUP_COPY_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-paste-button-image", STRING, POPUP_PASTE_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-select-button-image", STRING, POPUP_SELECT_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-select-all-button-image", STRING, POPUP_SELECT_ALL_BUTTON_ICON_IMAGE )
  
+ DALI_TYPE_REGISTRATION_END()
  
- Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New()
+ } // namespace
+ Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New( Toolkit::TextSelectionPopup::Buttons buttonsToEnable,
+                                                            TextSelectionPopupCallbackInterface* callbackInterface )
  {
-   // Create the implementation, temporarily owned by this handle on stack
-   IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup();
+    // Create the implementation, temporarily owned by this handle on stack
+   IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup( callbackInterface );
  
    // Pass ownership to CustomActor handle
    Dali::Toolkit::TextSelectionPopup handle( *impl );
  
+   impl->mEnabledButtons = buttonsToEnable;
    // Second-phase init of the implementation
    // This can only be done after the CustomActor connection has been made...
    impl->Initialize();
@@@ -120,49 -143,63 +144,63 @@@ void TextSelectionPopup::SetProperty( B
      {
        case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
        {
-        impl.SetPopupMaxSize( value.Get< Vector2 >() );
+        impl.SetDimensionToCustomise( POPUP_MAXIMUM_SIZE, value.Get< Vector2 >() );
         break;
        }
-       case Toolkit::TextSelectionPopup::Property::POPUP_BACKGROUND_IMAGE:
+       case Toolkit::TextSelectionPopup::Property::POPUP_MIN_SIZE:
        {
-         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-         impl.SetPopupImage( POPUP_BACKGROUND, image );
+         impl.SetDimensionToCustomise( POPUP_MINIMUM_SIZE, value.Get< Vector2 >() );
+         break;
+       }
+       case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
+       {
+         impl.SetDimensionToCustomise( OPTION_MAXIMUM_SIZE, value.Get< Vector2 >() );
+         break;
+       }
+       case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
+       {
+         impl.SetDimensionToCustomise( OPTION_MINIMUM_SIZE, value.Get< Vector2>() );
+         break;
+       }
+       case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
+       {
+         impl.SetDimensionToCustomise( OPTION_DIVIDER_SIZE, value.Get< Vector2>() );
          break;
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
        {
          ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-         impl.SetPopupImage( POPUP_CLIPBOARD_BUTTON, image );
+         impl.SetButtonImage( Toolkit::TextSelectionPopup::CLIPBOARD, image );
          break;
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
        {
          ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-         impl.SetPopupImage( POPUP_CUT_BUTTON_ICON, image );
+         impl.SetButtonImage( Toolkit::TextSelectionPopup::CUT, image );
          break;
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
        {
          ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-         impl.SetPopupImage( POPUP_COPY_BUTTON_ICON, image );
+         impl.SetButtonImage( Toolkit::TextSelectionPopup::COPY, image );
          break;
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
        {
          ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-         impl.SetPopupImage( POPUP_PASTE_BUTTON_ICON, image );
+         impl.SetButtonImage( Toolkit::TextSelectionPopup::PASTE, image );
          break;
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
        {
          ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-         impl.SetPopupImage( POPUP_SELECT_BUTTON_ICON, image );
+         impl.SetButtonImage( Toolkit::TextSelectionPopup::SELECT, image );
          break;
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
        {
          ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-         impl.SetPopupImage( POPUP_SELECT_ALL_BUTTON_ICON, image );
+         impl.SetButtonImage( Toolkit::TextSelectionPopup::SELECT_ALL, image );
          break;
        }
      } // switch
@@@ -183,21 -220,27 +221,27 @@@ Property::Value TextSelectionPopup::Get
      {
        case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
        {
-         value = impl.GetPopupMaxSize();
+         value = impl.GetDimensionToCustomise( POPUP_MAXIMUM_SIZE );
          break;
        }
-       case Toolkit::TextSelectionPopup::Property::POPUP_BACKGROUND_IMAGE:
+       case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
        {
-         ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_BACKGROUND ) );
-         if( image )
-         {
-           value = image.GetUrl();
-         }
+         value = impl.GetDimensionToCustomise( OPTION_MAXIMUM_SIZE );
+         break;
+       }
+       case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
+       {
+         value = impl.GetDimensionToCustomise( OPTION_MINIMUM_SIZE );
+         break;
+       }
+       case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
+       {
+         value = impl.GetDimensionToCustomise( OPTION_DIVIDER_SIZE );
          break;
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
        {
-         ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_CLIPBOARD_BUTTON ) );
+         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::CLIPBOARD ) );
          if( image )
          {
            value = image.GetUrl();
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
        {
-         ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_CUT_BUTTON_ICON ) );
+         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::CUT ) );
          if( image )
          {
            value = image.GetUrl();
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
        {
-         ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_COPY_BUTTON_ICON ) );
+         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::COPY ) );
          if( image )
          {
            value = image.GetUrl();
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
        {
-         ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_PASTE_BUTTON_ICON ) );
+         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::PASTE ) );
          if( image )
          {
            value = image.GetUrl();
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
        {
-         ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_SELECT_BUTTON_ICON ) );
+         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::SELECT ) );
          if( image )
          {
            value = image.GetUrl();
        }
        case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
        {
-         ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_SELECT_ALL_BUTTON_ICON ) );
+         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::SELECT_ALL ) );
          if( image )
          {
            value = image.GetUrl();
@@@ -259,106 -302,220 +303,220 @@@ void TextSelectionPopup::OnInitialize(
    CreatePopup();
  }
  
void TextSelectionPopup::OnRelayout( const Vector2& size, RelayoutContainer& container )
bool TextSelectionPopup::OnCutButtonPressed( Toolkit::Button button )
  {
+   if( mCallbackInterface )
+   {
+     mCallbackInterface->TextPopupButtonTouched( Toolkit::TextSelectionPopup::CUT );
+   }
  
+   return true;
  }
  
void TextSelectionPopup::SetPopupMaxSize( const Size& maxSize )
bool TextSelectionPopup::OnCopyButtonPressed( Toolkit::Button button )
  {
-   mMaxSize = maxSize;
+   if( mCallbackInterface )
+   {
+     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::COPY );
+   }
+   return true;
  }
  
- const Dali::Vector2& TextSelectionPopup::GetPopupMaxSize() const
+ bool TextSelectionPopup::OnPasteButtonPressed( Toolkit::Button button )
  {
-   return mMaxSize;
+   if( mCallbackInterface )
+   {
+     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::PASTE );
+   }
+   return true;
  }
  
void TextSelectionPopup::SetPopupImage( PopupParts part, Dali::Image image )
bool TextSelectionPopup::OnSelectButtonPressed( Toolkit::Button button )
  {
-    switch ( part )
-    {
-    case POPUP_BACKGROUND :
+   if( mCallbackInterface )
+   {
+     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::SELECT );
+   }
+   return true;
+ }
+ bool TextSelectionPopup::OnSelectAllButtonPressed( Toolkit::Button button )
+ {
+   if( mCallbackInterface )
+   {
+     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::SELECT_ALL );
+   }
+   return true;
+ }
+ bool TextSelectionPopup::OnClipboardButtonPressed( Toolkit::Button button )
+ {
+   if( mCallbackInterface )
+   {
+     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::CLIPBOARD );
+   }
+   return true;
+ }
+ void TextSelectionPopup::SetDimensionToCustomise( const PopupCustomisations& settingToCustomise, const Size& dimension )
+ {
+   switch( settingToCustomise )
+   {
+     case POPUP_MAXIMUM_SIZE :
+     {
+       Actor self = Self();
+       mMaxSize = dimension;
+       if ( mToolbar )
+       {
+         mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, mMaxSize );
+       }
+       break;
+     }
+     case POPUP_MINIMUM_SIZE :
+     {
+       Actor self = Self();
+       mMinSize = dimension;
+       // Option can not be smaller than this if only one.
+       break;
+     }
+     case OPTION_MAXIMUM_SIZE :
+     {
+       mOptionMaxSize = dimension;
+       // Option max size not currently currently supported
+       break;
+     }
+     case OPTION_MINIMUM_SIZE :
+     {
+       mOptionMinSize = dimension;
+       // Option min size not currently currently supported
+       break;
+     }
+     case OPTION_DIVIDER_SIZE :
+     {
+       mOptionDividerSize = dimension;
+       if ( mToolbar )
+       {
+         // Resize Dividers not currently supported
+       }
+       break;
+     }
+   } // switch
+ }
+ Size TextSelectionPopup::GetDimensionToCustomise( const PopupCustomisations& settingToCustomise )
+ {
+   switch( settingToCustomise )
+   {
+     case POPUP_MAXIMUM_SIZE :
+     {
+       return mMaxSize;
+     }
+     case POPUP_MINIMUM_SIZE :
+     {
+       return mMinSize;
+     }
+     case OPTION_MAXIMUM_SIZE :
+     {
+       return mOptionMaxSize;
+     }
+     case OPTION_MINIMUM_SIZE :
+     {
+       return mOptionMinSize;
+     }
+     case OPTION_DIVIDER_SIZE :
+     {
+       return mOptionDividerSize;
+     }
+   } // switch
+   return Size::ZERO;
+ }
+ void TextSelectionPopup::SetButtonImage( Toolkit::TextSelectionPopup::Buttons button, Dali::Image image )
+ {
+    switch ( button )
     {
-      mBackgroundImage = image;
-    }
     break;
-    case POPUP_CLIPBOARD_BUTTON :
+    case Toolkit::TextSelectionPopup::CLIPBOARD:
     {
       mClipboardIconImage  = image;
     }
     break;
-    case POPUP_CUT_BUTTON_ICON :
+    case Toolkit::TextSelectionPopup::CUT :
     {
       mCutIconImage = image;
     }
     break;
-    case POPUP_COPY_BUTTON_ICON :
+    case Toolkit::TextSelectionPopup::COPY :
     {
       mCopyIconImage = image;
     }
     break;
-    case POPUP_PASTE_BUTTON_ICON :
+    case Toolkit::TextSelectionPopup::PASTE :
     {
       mPasteIconImage = image;
     }
     break;
-    case POPUP_SELECT_BUTTON_ICON :
+    case Toolkit::TextSelectionPopup::SELECT :
     {
       mSelectIconImage = image;
     }
     break;
-    case POPUP_SELECT_ALL_BUTTON_ICON :
+    case Toolkit::TextSelectionPopup::SELECT_ALL :
     {
       mSelectAllIconImage = image;
     }
     break;
+    default :
+    {
+      DALI_ASSERT_DEBUG( "TextSelectionPopup SetPopupImage Unknown Button" );
+    }
     } // switch
  }
  
- Dali::Image TextSelectionPopup::GetPopupImage( PopupParts part )
+ Dali::Image TextSelectionPopup::GetButtonImage( Toolkit::TextSelectionPopup::Buttons button )
  {
-   switch ( part )
+   switch ( button )
    {
-   case POPUP_BACKGROUND :
-   {
-     return mBackgroundImage;
-   }
-   break;
-   case POPUP_CLIPBOARD_BUTTON :
+   case Toolkit::TextSelectionPopup::CLIPBOARD :
    {
      return mClipboardIconImage;
    }
    break;
-   case POPUP_CUT_BUTTON_ICON :
+   case Toolkit::TextSelectionPopup::CUT :
    {
      return mCutIconImage;
    }
    break;
-   case POPUP_COPY_BUTTON_ICON :
+   case Toolkit::TextSelectionPopup::COPY :
    {
      return mCopyIconImage;
    }
    break;
-   case POPUP_PASTE_BUTTON_ICON :
+   case Toolkit::TextSelectionPopup::PASTE :
    {
      return mPasteIconImage;
    }
    break;
-   case POPUP_SELECT_BUTTON_ICON :
+   case Toolkit::TextSelectionPopup::SELECT :
    {
      return mSelectIconImage;
    }
    break;
-   case POPUP_SELECT_ALL_BUTTON_ICON :
+   case Toolkit::TextSelectionPopup::SELECT_ALL :
    {
      return mSelectAllIconImage;
    }
    break;
    default :
    {
-     DALI_ASSERT_DEBUG( "Unknown Popup Part" );
+     DALI_ASSERT_DEBUG( "TextSelectionPopup GetPopupImage Unknown Button" );
    }
    } // switch
  
     {
       mCutIconImage = ResourceImage::New( OPTION_ICON_CUT );
     }
-    mOrderListOfButtons.push_back( ButtonRequirement( ButtonsCut, mCutOptionPriority, OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), mCutIconImage, true ) );
+    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::CUT, mCutOptionPriority, OPTION_CUT, POPUP_CUT_STRING , mCutIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::CUT)  ) );
  
     if ( !mCopyIconImage )
     {
       mCopyIconImage = ResourceImage::New( OPTION_ICON_COPY );
     }
-    mOrderListOfButtons.push_back( ButtonRequirement( ButtonsCopy, mCopyOptionPriority, OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), mCopyIconImage, true ) );
+    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::COPY, mCopyOptionPriority, OPTION_COPY, POPUP_COPY_STRING, mCopyIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::COPY)  ) );
  
     if ( !mPasteIconImage )
     {
       mPasteIconImage = ResourceImage::New( OPTION_ICON_PASTE );
     }
-    mOrderListOfButtons.push_back( ButtonRequirement( ButtonsPaste, mPasteOptionPriority, OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), mPasteIconImage, true ) );
+    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::PASTE, mPasteOptionPriority, OPTION_PASTE, POPUP_PASTE_STRING, mPasteIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::PASTE)  ) );
  
     if ( !mSelectIconImage )
     mSelectIconImage = ResourceImage::New( OPTION_ICON_SELECT );
-    mOrderListOfButtons.push_back( ButtonRequirement( ButtonsSelect, mSelectOptionPriority, OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), mSelectIconImage, true ) );
+    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::SELECT, mSelectOptionPriority, OPTION_SELECT_WORD, POPUP_SELECT_STRING, mSelectIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::SELECT)  ) );
  
     if ( !mSelectAllIconImage )
     {
      mSelectAllIconImage = ResourceImage::New( OPTION_ICON_SELECT_ALL );
     }
-    mOrderListOfButtons.push_back( ButtonRequirement( ButtonsSelectAll, mSelectAllOptionPriority, OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), mSelectAllIconImage, true ) );
+    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::SELECT_ALL, mSelectAllOptionPriority, OPTION_SELECT_ALL, POPUP_SELECT_ALL_STRING, mSelectAllIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::SELECT_ALL)  ) );
  
     if ( !mClipboardIconImage )
     {
       mClipboardIconImage = ResourceImage::New( OPTION_ICON_CLIPBOARD );
     }
-    mOrderListOfButtons.push_back( ButtonRequirement( ButtonsClipboard, mClipboardOptionPriority, OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), mClipboardIconImage, true ) );
+    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::CLIPBOARD, mClipboardOptionPriority, OPTION_CLIPBOARD, POPUP_CLIPBOARD_STRING, mClipboardIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::CLIPBOARD)  ) );
  
     // Sort the buttons according their priorities.
     std::sort( mOrderListOfButtons.begin(), mOrderListOfButtons.end(), TextSelectionPopup::ButtonPriorityCompare() );
   }
  
-  void TextSelectionPopup::CreateBackground()
+  void TextSelectionPopup::AddOption( const ButtonRequirement& button, bool showDivider, bool showIcons, bool showCaption  )
   {
-    if ( mBackgroundImage )
-    {
-      SetBackgroundImage (  mBackgroundImage );
-    }
  
-    SetBackgroundColor( mBackgroundColor );
-  }
+    const std::string& name = button.name;
+    const std::string& caption = button.caption;
+    Image iconImage = button.icon;
  
-  void TextSelectionPopup::AddOption( Dali::Toolkit::TableView& parent, const std::string& name, const std::string& caption, const Image iconImage, bool finalOption, bool showIcons, bool showCaption, std::size_t& indexInTable )
-  {
     // 1. Create the backgrounds for the popup option both normal and pressed.
     // Both containers will be added to a button.
  
-    Toolkit::TableView optionContainer = Toolkit::TableView::New( (showIcons)?2:1 , 1 );
-    optionContainer.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
-    optionContainer.SetMinimumSize( Vector2( OPTION_MIN_WIDTH, 0 ) );
+    Toolkit::TableView optionContainer = Toolkit::TableView::New( (showIcons&showCaption)?2:1 , 1 );
 -   optionContainer.SetDrawMode( DrawMode::OVERLAY );
+    optionContainer.SetFitHeight( 0 );
     optionContainer.SetFitWidth( 0 );
  
-    Toolkit::TableView  optionPressedContainer = Toolkit::TableView::New( (showIcons)?2:1 , 1 );
-    optionPressedContainer.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
-    optionPressedContainer.SetMinimumSize( Vector2( OPTION_MIN_WIDTH, 0 ) );
+    Toolkit::TableView  optionPressedContainer = Toolkit::TableView::New( (showIcons&showCaption)?2:1 , 1 );
 -   optionPressedContainer.SetDrawMode( DrawMode::OVERLAY );
+    optionPressedContainer.SetFitHeight( 0 );
     optionPressedContainer.SetFitWidth( 0 );
+    optionPressedContainer.SetBackgroundColor( mPressedColor );
  #ifdef DECORATOR_DEBUG
     optionContainer.SetName("optionContainer");
     optionPressedContainer.SetName("optionPressedContainer");
  
     if ( showCaption )
     {
-    Toolkit::TextLabel captionTextLabel = Toolkit::TextLabel::New();
-    captionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
-    optionContainer.SetFitHeight( 0 );
-    Toolkit::TextLabel pressedCaptionTextLabel = Toolkit::TextLabel::New();
-    pressedCaptionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
-    optionPressedContainer.SetFitHeight( 0 );
-    captionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH );
-    captionTextLabel.SetMaximumSize( Vector2( OPTION_MAX_WIDTH - 2.f * OPTION_MARGIN_WIDTH , FLT_MAX ) ); //todo FLT_MAX Size negotiation feature needed
-    pressedCaptionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH );
-    pressedCaptionTextLabel.SetMaximumSize( Vector2( OPTION_MAX_WIDTH - 2.f * OPTION_MARGIN_WIDTH , FLT_MAX) ); //todo FLT_MAX Size negotiation feature needed
-    optionContainer.AddChild( captionTextLabel, Toolkit::TableView::CellPosition( 1, 0 )  ); // todo Labels need ellipsis or similar
-    optionPressedContainer.AddChild( pressedCaptionTextLabel, Toolkit::TableView::CellPosition( 1, 0 )  ); // todo Labels need ellipsis or similar
+      Toolkit::TextLabel captionTextLabel = Toolkit::TextLabel::New();
+      captionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
+      captionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+      Toolkit::TextLabel pressedCaptionTextLabel = Toolkit::TextLabel::New();
+      pressedCaptionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
+      pressedCaptionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+      Padding padding;
+      padding.left = 24.0f;
+      padding.right = 24.0f;
+      padding.top = 14.0f;
+      padding.bottom = 14.0f;
+      captionTextLabel.SetPadding( padding );
+      pressedCaptionTextLabel.SetPadding( padding );
+      optionContainer.AddChild( captionTextLabel, Toolkit::TableView::CellPosition(( showIcons&showCaption)?1:0, 0 )  );
+      optionPressedContainer.AddChild( pressedCaptionTextLabel, Toolkit::TableView::CellPosition(( showIcons&showCaption)?1:0, 0 ) );
     }
  
+    // 3. Create the icons
     if ( showIcons )
     {
-      // 3. Create the icons
       ImageActor pressedIcon = ImageActor::New(  iconImage );
       ImageActor icon = ImageActor::New(  iconImage );
-      icon.SetName("image-icon-2014");
 +     icon.SetSortModifier( DECORATION_DEPTH_INDEX - 1 );
 +     pressedIcon.SetSortModifier( DECORATION_DEPTH_INDEX - 1 );
       icon.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
       pressedIcon.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
-      pressedIcon.SetColor( mIconPressedColor );
-      optionContainer.SetFitHeight( 0 );
-      optionPressedContainer.SetFitHeight( 0 );
+      icon.SetColor( mIconColor );
+      if ( showCaption & showIcons )
+      {
+        optionContainer.SetFitHeight( 1 );
+        optionContainer.SetFitWidth( 1 );
+        optionPressedContainer.SetFitHeight( 1 );
+        optionPressedContainer.SetFitWidth( 1 );
+      }
       optionContainer.AddChild( icon, Toolkit::TableView::CellPosition( 0, 0 )  );
       optionPressedContainer.AddChild( pressedIcon, Toolkit::TableView::CellPosition( 0, 0 )  );
       icon.SetPadding( Padding( 10.0f, 10.0f, 10.0f, 10.0f ) );
       pressedIcon.SetPadding( Padding( 10.0f, 10.0f, 10.0f, 10.0f ) );
     }
  
-    // 5. Create a option.
+    // 4. Create a option.
     Toolkit::PushButton option = Toolkit::PushButton::New();
     option.SetName( name );
     option.SetAnimationTime( 0.0f );
-    option.SetSize( OPTION_ICON_SIZE );
-    //option.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
+    option.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
  
-    // 6. Set the normal option image.
+    switch( button.id )
+    {
+      case Toolkit::TextSelectionPopup::CUT:
+      {
+        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnCutButtonPressed );
+        break;
+      }
+      case Toolkit::TextSelectionPopup::COPY:
+      {
+        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnCopyButtonPressed );
+        break;
+      }
+      case Toolkit::TextSelectionPopup::PASTE:
+      {
+        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnPasteButtonPressed );
+        break;
+      }
+      case Toolkit::TextSelectionPopup::SELECT:
+      {
+        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnSelectButtonPressed );
+        break;
+      }
+      case Toolkit::TextSelectionPopup::SELECT_ALL:
+      {
+        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnSelectAllButtonPressed );
+        break;
+      }
+      case Toolkit::TextSelectionPopup::CLIPBOARD:
+      {
+        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnClipboardButtonPressed );
+        break;
+      }
+      case Toolkit::TextSelectionPopup::NONE:
+      {
+        // Nothing to do:
+        break;
+      }
+    }
+    // 5. Set the normal option image.
     option.SetButtonImage( optionContainer );
  
-    // 7. Set the pressed option image
+    // 6. Set the pressed option image
     option.SetSelectedImage( optionPressedContainer );
  
-    // 9 Add option to table view
-    parent.SetFitWidth( indexInTable );
-    parent.AddChild( option, Toolkit::TableView::CellPosition( 0, indexInTable )  );
-    indexInTable++;
+    // 7 Add option to tool bar
+    mToolbar.AddOption( option );
  
-    // 10. Add the divider
-    if( !finalOption )
+    // 8. Add the divider
+    if( showDivider )
     {
-      const Size size( POPUP_DIVIDER_WIDTH, 0.0f ); // Height FILL_TO_PARENT
+      const Size size( mOptionDividerSize.width, 0.0f ); // Height FILL_TO_PARENT
  
       ImageActor divider = Toolkit::CreateSolidColorActor( Color::WHITE );
       divider.SetSize( size );
       divider.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
-      parent.SetFitWidth( indexInTable );
-      parent.AddChild( divider, Toolkit::TableView::CellPosition( 0, indexInTable )  );
-      indexInTable++;
+      divider.SetColor( mLineColor );
+      mToolbar.AddDivider( divider );
     }
   }
  
-  void TextSelectionPopup::SetUpPopup()
-  {
-    Actor self = Self();
-    self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
-    // Create Layer and Stencil.
-    mStencilLayer = Layer::New();
-    mStencilLayer.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
-    mStencilLayer.SetParentOrigin( ParentOrigin::CENTER );
-    ImageActor stencil = CreateSolidColorActor( Color::RED );
-    stencil.SetDrawMode( DrawMode::STENCIL );
-    stencil.SetVisible( true );
-    stencil.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
-    stencil.SetParentOrigin( ParentOrigin::CENTER );
-    Actor scrollview = Actor::New(); //todo make a scrollview
-    scrollview.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
-    scrollview.SetParentOrigin( ParentOrigin::CENTER );
-    mTableOfButtons.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
-    mTableOfButtons.SetFitHeight( 0 );
-    mTableOfButtons.SetParentOrigin( ParentOrigin::CENTER );
-    mStencilLayer.Add( stencil );
-    mStencilLayer.Add( scrollview );
-    scrollview.Add( mTableOfButtons );
-    self.Add( mStencilLayer );
-    //self.Add ( mTableOfButtons );
-  }
-  void TextSelectionPopup::AddPopupOptions( bool createTail, bool showIcons, bool showCaptions )
+  std::size_t TextSelectionPopup::GetNumberOfEnabledOptions()
   {
-    mContentSize = Vector2::ZERO;
-    // Add the options into the buttons container.
-    // 1. Determine how many buttons are active and should be added to container.
     std::size_t numberOfOptions = 0u;
     for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
     {
       }
     }
  
-    // 2. Iterate list of buttons and add active ones.
-    std::size_t optionsAdded = 0u;
-    numberOfOptions = ( numberOfOptions*2 ) - 1 ; // Last Option does not get a divider so -1 or if only one option then also no divider
-    mTableOfButtons = Dali::Toolkit::TableView::New( 1, numberOfOptions );
+    return numberOfOptions;
+  }
  
+  void TextSelectionPopup::AddPopupOptionsToToolbar( bool showIcons, bool showCaptions )
+  {
+    // Iterate list of buttons and add active ones to Toolbar
+    std::size_t numberOfOptionsRequired =  GetNumberOfEnabledOptions();
+    std::size_t numberOfOptionsAdded = 0u;
     for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
     {
       const ButtonRequirement& button( *it );
       if ( button.enabled )
       {
-        AddOption( mTableOfButtons, button.name, button.caption, button.icon, optionsAdded == numberOfOptions - 1, showIcons, showCaptions, optionsAdded ); // -1 to ignore the last divider
+        numberOfOptionsAdded++;
+        AddOption(  button, ( numberOfOptionsAdded < numberOfOptionsRequired ) , showIcons, showCaptions );
       }
     }
   }
  
   void TextSelectionPopup::CreatePopup()
   {
-    if ( !mStencilLayer )
+    Actor self = Self();
+    CreateOrderedListOfPopupOptions();  //todo Currently causes all options to be shown
+    self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+    SetBackgroundImage( NinePatchImage::New( DEFAULT_POPUP_BACKGROUND_IMAGE ) );
+    if ( !mToolbar )
     {
-      CreateOrderedListOfPopupOptions();  //todo Currently causes all options to be shown
-      CreateBackground();
-      AddPopupOptions( true, true, false );  // todo false so not to show Labels until ellipses or similar possible.
-      SetUpPopup();
+      mToolbar = Toolkit::TextSelectionToolbar::New();
+      mToolbar.SetParentOrigin( ParentOrigin::CENTER );
+      mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, mMaxSize );
+      self.Add( mToolbar );
+      AddPopupOptionsToToolbar( mShowIcons, mShowCaptions );
     }
-    mStencilLayer.RaiseToTop();
   }
  
- TextSelectionPopup::TextSelectionPopup()
- : Control( ControlBehaviour( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ) ),
-   mMaxSize ( DEFAULT_POPUP_MAX_SIZE ),
-   mVisiblePopUpSize( DEFAULT_POPUP_MAX_SIZE ),
-   mRequiredPopUpSize( DEFAULT_POPUP_MAX_SIZE ),
-   mBackgroundColor( DEFAULT_POPUP_BACKGROUND ),
-   mBackgroundPressedColor( DEFAULT_POPUP_BACKGROUND_PRESSED ),
+ TextSelectionPopup::TextSelectionPopup( TextSelectionPopupCallbackInterface* callbackInterface )
+ : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+   mToolbar(),
+   mMaxSize(),
+   mMinSize(),
+   mOptionDividerSize( Size( 2.0f, 0.0f) ),
+   mEnabledButtons( Toolkit::TextSelectionPopup::NONE ),
+   mCallbackInterface( callbackInterface ),
    mLineColor( DEFAULT_POPUP_LINE_COLOR ),
    mIconColor( DEFAULT_OPTION_ICON ),
-   mIconPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
-   mTextColor( DEFAULT_OPTION_TEXT ),
-   mTextPressedColor( DEFAULT_OPTION_TEXT_PRESSED ),
+   mPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
    mSelectOptionPriority( 1 ),
    mSelectAllOptionPriority ( 2 ),
    mCutOptionPriority ( 3 ),
    mCopyOptionPriority ( 4 ),
    mPasteOptionPriority ( 5 ),
    mClipboardOptionPriority( 6 ),
-   mShowIcons( true ),
-   mShowCaptions( false )
+   mShowIcons( false ),
+   mShowCaptions( true )
  {
  }
  
@@@ -621,3 -786,5 +787,5 @@@ TextSelectionPopup::~TextSelectionPopup
  } // namespace Toolkit
  
  } // namespace Dali
@@@ -15,7 -15,6 +15,7 @@@ toolkit_src_files = 
     $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
     $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
     $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
 +   $(toolkit_src_dir)/controls/bubble-effect/bubble-actor.cpp \
     $(toolkit_src_dir)/controls/buttons/button-impl.cpp \
     $(toolkit_src_dir)/controls/buttons/check-box-button-impl.cpp \
     $(toolkit_src_dir)/controls/buttons/push-button-impl.cpp \
@@@ -26,7 -25,6 +26,7 @@@
     $(toolkit_src_dir)/controls/popup/popup-impl.cpp \
     $(toolkit_src_dir)/controls/popup/popup-style-impl.cpp \
     $(toolkit_src_dir)/controls/page-turn-view/page-turn-portrait-view-impl.cpp \
 +   $(toolkit_src_dir)/controls/page-turn-view/page-turn-effect.cpp \
     $(toolkit_src_dir)/controls/page-turn-view/page-turn-landscape-view-impl.cpp \
     $(toolkit_src_dir)/controls/page-turn-view/page-turn-view-impl.cpp \
     $(toolkit_src_dir)/controls/scroll-bar/scroll-bar-impl.cpp \
@@@ -48,6 -46,7 +48,7 @@@
     $(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \
     $(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \
     $(toolkit_src_dir)/controls/text-controls/text-selection-popup-impl.cpp \
+    $(toolkit_src_dir)/controls/text-controls/text-selection-toolbar-impl.cpp \
     $(toolkit_src_dir)/controls/tool-bar/tool-bar-impl.cpp \
     $(toolkit_src_dir)/focus-manager/accessibility-focus-manager-impl.cpp \
     $(toolkit_src_dir)/focus-manager/keyboard-focus-manager-impl.cpp \
@@@ -56,6 -55,8 +57,6 @@@
     $(toolkit_src_dir)/filters/emboss-filter.cpp \
     $(toolkit_src_dir)/filters/image-filter.cpp \
     $(toolkit_src_dir)/filters/spread-filter.cpp \
 -   $(toolkit_src_dir)/shader-effects/page-turn-effect-impl.cpp \
 -   $(toolkit_src_dir)/shader-effects/water-effect-impl.cpp \
     $(toolkit_src_dir)/styling/style-manager-impl.cpp \
     $(toolkit_src_dir)/text/bidirectional-support.cpp \
     $(toolkit_src_dir)/text/character-set-conversion.cpp \
@@@ -24,6 -24,7 +24,6 @@@
  #include <dali/public-api/adaptor-framework/timer.h>
  #include <dali/public-api/actors/image-actor.h>
  #include <dali/public-api/actors/layer.h>
 -#include <dali/devel-api/actors/mesh-actor.h>
  #include <dali/public-api/animation/constraint.h>
  #include <dali/public-api/common/constants.h>
  #include <dali/public-api/common/stage.h>
@@@ -32,6 -33,8 +32,6 @@@
  #include <dali/public-api/events/touch-event.h>
  #include <dali/public-api/events/pan-gesture.h>
  #include <dali/public-api/events/pan-gesture-detector.h>
 -#include <dali/devel-api/geometry/mesh.h>
 -#include <dali/devel-api/geometry/mesh-data.h>
  #include <dali/public-api/images/resource-image.h>
  #include <dali/public-api/math/rect.h>
  #include <dali/public-api/math/vector2.h>
@@@ -41,7 -44,6 +41,7 @@@
  
  // INTERNAL INCLUDES
  #include <dali-toolkit/public-api/controls/control.h>
 +#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
  #include <dali-toolkit/public-api/controls/control-impl.h>
  #include <dali-toolkit/public-api/controls/buttons/push-button.h>
  #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
@@@ -73,13 -75,17 +73,17 @@@ namespac
  
  const char* DEFAULT_GRAB_HANDLE_IMAGE_RELEASED( DALI_IMAGE_DIR "insertpoint-icon.png" );
  const char* DEFAULT_GRAB_HANDLE_IMAGE_PRESSED( DALI_IMAGE_DIR "insertpoint-icon-pressed.png" );
- const char* DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
- const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
+ const char* DEFAULT_SELECTION_HANDLE_ONE_RELEASED( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
+ const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
+ const char* DEFAULT_SELECTION_HANDLE_TWO_RELEASED( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
+ const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
  
- const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.5f, 2.0f, 1.0f );
- const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.5f, 1.5f, 1.0f );
+ const int DEFAULT_POPUP_OFFSET( -100.0f ); // Vertical offset of Popup from cursor or handles position.
  
- const Dali::Vector4 LIGHT_BLUE( 0.07f, 0.41f, 0.59f, 1.0f ); // The text highlight color.
+ const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.25f, 1.5f, 1.0f );
+ const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.25f, 1.5f, 1.0f );
+ const Dali::Vector4 LIGHT_BLUE( (0xb2 / 255.0f), (0xeb / 255.0f), (0xf2 / 255.0f), 0.5f ); // The text highlight color.
  
  const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval
  const float TO_MILLISECONDS = 1000.f;
@@@ -191,6 -197,7 +195,7 @@@ struct Decorator::Impl : public Connect
        grabDisplacementY( 0.f ),
        active( false ),
        visible( false ),
+       pressed( false ),
        flipped( false )
      {
      }
      float grabDisplacementY;
      bool active  : 1;
      bool visible : 1;
+     bool pressed : 1;
      bool flipped : 1;
    };
  
-   Impl( Dali::Toolkit::Internal::Control& parent, Observer& observer )
-   : mTextControlParent( parent ),
-     mObserver( observer ),
+   struct PopupImpl
+   {
+     PopupImpl()
+     : position(),
+       offset( DEFAULT_POPUP_OFFSET )
+     {
+     }
+     TextSelectionPopup actor;
+     Vector3 position;
+     int offset;
+   };
+   Impl( ControllerInterface& controller,
+         TextSelectionPopupCallbackInterface& callbackInterface )
+   : mController( controller ),
+     mEnabledPopupButtons( TextSelectionPopup::NONE ),
+     mTextSelectionPopupCallbackInterface( callbackInterface ),
      mBoundingBox( Rect<int>() ),
      mHighlightColor( LIGHT_BLUE ),
+     mHighlightPosition( Vector2::ZERO ),
      mActiveCursor( ACTIVE_CURSOR_NONE ),
      mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ),
      mCursorBlinkDuration( 0.0f ),
      mActiveCopyPastePopup( false ),
      mCursorBlinkStatus( true ),
      mPrimaryCursorVisible( false ),
-     mSecondaryCursorVisible( false )
+     mSecondaryCursorVisible( false ),
+     mSwapSelectionHandles( false ),
+     mNotifyEndOfScroll( false )
    {
    }
  
      // TODO - Remove this if nothing is active
      CreateActiveLayer();
  
 +    /*
      // Show or hide the cursors
      CreateCursors();
      if( mPrimaryCursor )
        if( mPrimaryCursorVisible )
        {
          Vector2 position = cursor.position;
-         if( GRAB_HANDLE == mHandleScrolling )
-         {
-           if( mScrollDirection == SCROLL_RIGHT )
-           {
-             position.x = 0.f;
-           }
-           else
-           {
-             position.x = size.width;
-           }
-         }
  
          mPrimaryCursor.SetPosition( position.x,
                                      position.y );
        }
        mSecondaryCursor.SetVisible( mSecondaryCursorVisible );
      }
 -
 +    */
      // Show or hide the grab handle
      HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
      if( grabHandle.active )
      {
        Vector2 position = grabHandle.position;
  
-       if( GRAB_HANDLE == mHandleScrolling )
-       {
-         if( mScrollDirection == SCROLL_RIGHT )
-         {
-           position.x = 0.f;
-         }
-         else
-         {
-           position.x = size.width;
-         }
-       }
        const bool isVisible = ( position.x <= size.width ) && ( position.x >= 0.f );
  
        if( isVisible )
      HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ];
      if( primary.active || secondary.active )
      {
-       SetupTouchEvents();
+       Vector2 primaryPosition = primary.position;
+       Vector2 secondaryPosition = secondary.position;
+       const bool isPrimaryVisible = ( primaryPosition.x <= size.width ) && ( primaryPosition.x >= 0.f );
+       const bool isSecondaryVisible = ( secondaryPosition.x <= size.width ) && ( secondaryPosition.x >= 0.f );
+       if( isPrimaryVisible || isSecondaryVisible )
+       {
+         SetupTouchEvents();
  
-       CreateSelectionHandles();
+         CreateSelectionHandles();
  
-       primary.actor.SetPosition( primary.position.x,
-                                  primary.position.y + primary.lineHeight );
+         if( isPrimaryVisible )
+         {
+           primary.actor.SetPosition( primaryPosition.x,
+                                      primaryPosition.y + primary.lineHeight );
+         }
  
-       secondary.actor.SetPosition( secondary.position.x,
-                                    secondary.position.y + secondary.lineHeight );
+         if( isSecondaryVisible )
+         {
+           secondary.actor.SetPosition( secondaryPosition.x,
+                                        secondaryPosition.y + secondary.lineHeight );
+         }
+       }
+       primary.actor.SetVisible( isPrimaryVisible );
+       secondary.actor.SetVisible( isSecondaryVisible );
  
        CreateHighlight();
        UpdateHighlight();
      {
        UnparentAndReset( primary.actor );
        UnparentAndReset( secondary.actor );
 -      UnparentAndReset( mHighlightMeshActor );
 +      //UnparentAndReset( mHighlightMeshActor );
      }
  
      if ( mActiveCopyPastePopup )
      {
-       if ( !mCopyPastePopup )
+       // todo Swap UnparentAndReset for DeterminePositionPopup() if mCopyPastePopup.actor valid Once the issue with the labels disappearing is fixed.
+       UnparentAndReset( mCopyPastePopup.actor );
+       if ( !mCopyPastePopup.actor )
        {
-         mCopyPastePopup = TextSelectionPopup::New();
+         mCopyPastePopup.actor = TextSelectionPopup::New( mEnabledPopupButtons, &mTextSelectionPopupCallbackInterface );
  #ifdef DECORATOR_DEBUG
-         mCopyPastePopup.SetName("mCopyPastePopup");
+         mCopyPastePopup.actor.SetName("mCopyPastePopup");
  #endif
-         mCopyPastePopup.SetAnchorPoint( AnchorPoint::CENTER );
-         mCopyPastePopup.OnRelayoutSignal().Connect( this,  &Decorator::Impl::PopUpRelayoutComplete  ); // Position popup after size negotiation
-         mActiveLayer.Add ( mCopyPastePopup );
+         mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
+         mCopyPastePopup.actor.OnRelayoutSignal().Connect( this,  &Decorator::Impl::PopupRelayoutComplete  ); // Position popup after size negotiation
+         mActiveLayer.Add ( mCopyPastePopup.actor );
        }
      }
      else
      {
-      if ( mCopyPastePopup )
+      if ( mCopyPastePopup.actor )
       {
-        UnparentAndReset( mCopyPastePopup );
+        UnparentAndReset( mCopyPastePopup.actor );
       }
      }
    }
      mHandle[ GRAB_HANDLE ].position += scrollOffset;
      mHandle[ LEFT_SELECTION_HANDLE ].position += scrollOffset;
      mHandle[ RIGHT_SELECTION_HANDLE ].position += scrollOffset;
-     // TODO Highlight box??
+     mHighlightPosition += scrollOffset;
    }
  
-   void PopUpRelayoutComplete( Actor actor )
+   void DeterminePositionPopup()
    {
-     // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
+     if ( !mActiveCopyPastePopup )
+     {
+       return;
+     }
  
-     mCopyPastePopup.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopUpRelayoutComplete  );
+     if ( mHandle[LEFT_SELECTION_HANDLE].active || mHandle[RIGHT_SELECTION_HANDLE].active )
+     {
+       float minHandleXPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
+       float maxHandleXPosition = std::max (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
  
-     Vector3 popupPosition( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f); //todo 100 to be an offset Property
+       float minHandleYPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.y, mHandle[RIGHT_SELECTION_HANDLE].position.y );
  
-     Vector3 popupSize = Vector3( mCopyPastePopup.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
+       mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) *0.5f );
+       mCopyPastePopup.position.y = minHandleYPosition + mCopyPastePopup.offset;
+     }
+     else
+     {
+       mCopyPastePopup.position = Vector3( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f ); //todo 100 to be an offset Property
+     }
+     Vector3 popupSize = Vector3( mCopyPastePopup.actor.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
  
-     GetConstrainedPopupPosition( popupPosition, popupSize, AnchorPoint::CENTER, mActiveLayer, mBoundingBox );
+     GetConstrainedPopupPosition( mCopyPastePopup.position, popupSize, AnchorPoint::CENTER, mActiveLayer, mBoundingBox );
  
-     SetUpPopUpPositionNotifications();
+     SetUpPopupPositionNotifications();
+     mCopyPastePopup.actor.SetPosition( mCopyPastePopup.position );
+   }
+   void PopupRelayoutComplete( Actor actor )
+   {
+     // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
+     mCopyPastePopup.actor.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopupRelayoutComplete  );
  
-     mCopyPastePopup.SetPosition( popupPosition ); //todo grabhandle(cursor) or selection handle positions to be used
+     DeterminePositionPopup();
    }
  
    void CreateCursor( ImageActor& cursor, const Vector4& color )
    {
      cursor = CreateSolidColorActor( color );
 +    cursor.SetSortModifier( DECORATION_DEPTH_INDEX );
      cursor.SetParentOrigin( ParentOrigin::TOP_LEFT ); // Need to set the default parent origin as CreateSolidColorActor() sets a different one.
      cursor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
    }
    // Add or Remove cursor(s) from parent
    void CreateCursors()
    {
 +    /*
      if( mActiveCursor == ACTIVE_CURSOR_NONE )
      {
        UnparentAndReset( mPrimaryCursor );
      }
      else
      {
 -      /* Create Primary and or Secondary Cursor(s) if active and add to parent */
 +      // Create Primary and or Secondary Cursor(s) if active and add to parent
        if ( mActiveCursor == ACTIVE_CURSOR_PRIMARY ||
             mActiveCursor == ACTIVE_CURSOR_BOTH )
        {
          UnparentAndReset( mSecondaryCursor );
        }
      }
 +    */
    }
  
    bool OnCursorBlinkTimerTick()
    {
 +    /*
      // Cursor blinking
      if ( mPrimaryCursor )
      {
      }
  
      mCursorBlinkStatus = !mCursorBlinkStatus;
 -
 +    */
      return true;
    }
  
    {
      if( !mActiveLayer )
      {
-       Actor parent = mTextControlParent.Self();
        mActiveLayer = Layer::New();
  #ifdef DECORATOR_DEBUG
        mActiveLayer.SetName ( "ActiveLayerActor" );
        mActiveLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
        mActiveLayer.SetPositionInheritanceMode( USE_PARENT_POSITION );
  
-       parent.Add( mActiveLayer );
+       // Add the active layer telling the controller it doesn't need clipping.
+       mController.AddDecoration( mActiveLayer, false );
      }
  
      mActiveLayer.RaiseToTop();
        }
  
        grabHandle.actor = ImageActor::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
 +      grabHandle.actor.SetSortModifier( DECORATION_DEPTH_INDEX );
        grabHandle.actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
 -      grabHandle.actor.SetDrawMode( DrawMode::OVERLAY );
        // Area that Grab handle responds to, larger than actual handle so easier to move
  #ifdef DECORATOR_DEBUG
        grabHandle.actor.SetName( "GrabHandleActor" );
      {
        if( !mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
        {
-         mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE );
+         mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_RELEASED );
+       }
+       if( !mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] )
+       {
+         mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_PRESSED );
        }
  
        primary.actor = ImageActor::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
        primary.actor.SetName("SelectionHandleOne");
  #endif
        primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
 -      primary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text
 +      primary.actor.SetSortModifier( DECORATION_DEPTH_INDEX );
        primary.flipped = false;
  
        primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
        primary.grabArea.SetName("SelectionHandleOneGrabArea");
  #endif
        primary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+       primary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+       primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
        primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
-       primary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
  
        mTapDetector.Attach( primary.grabArea );
        mPanGestureDetector.Attach( primary.grabArea );
      {
        if( !mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
        {
-         mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO );
+         mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_RELEASED );
+       }
+       if( !mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] )
+       {
+         mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_PRESSED );
        }
  
        secondary.actor = ImageActor::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
        secondary.actor.SetName("SelectionHandleTwo");
  #endif
        secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text.
 -      secondary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text
 +      secondary.actor.SetSortModifier( DECORATION_DEPTH_INDEX );
        secondary.flipped = false;
  
        secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
        secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
  #endif
        secondary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+       secondary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+       secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
        secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
-       secondary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
  
        mTapDetector.Attach( secondary.grabArea );
        mPanGestureDetector.Attach( secondary.grabArea );
  
    void CreateHighlight()
    {
 +    /*
      if ( !mHighlightMeshActor )
      {
        mHighlightMaterial = Material::New( "HighlightMaterial" );
        mHighlightMeshActor.SetName( "HighlightMeshActor" );
  #endif
        mHighlightMeshActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-       mHighlightMeshActor.SetPosition( 0.0f, 0.0f, DISPLAYED_HIGHLIGHT_Z_OFFSET );
  
-       Actor parent = mTextControlParent.Self();
-       parent.Add( mHighlightMeshActor );
+       // Add the highlight box telling the controller it needs clipping.
+       mController.AddDecoration( mHighlightMeshActor, true );
      }
+     mHighlightMeshActor.SetPosition( mHighlightPosition.x, mHighlightPosition.y, DISPLAYED_HIGHLIGHT_Z_OFFSET );
 +    */
    }
  
    void UpdateHighlight()
      //  9*    *7
      //
  
 +    /*
      if ( mHighlightMesh && mHighlightMaterial && !mHighlightQuadList.empty() )
      {
        MeshData::VertexContainer vertices;
        mHighlightMeshData.SetData( vertices, faceIndices, bones, mHighlightMaterial );
        mHighlightMesh.UpdateMeshData( mHighlightMeshData );
      }
 +    */
    }
  
    void OnTap( Actor actor, const TapGesture& tap )
      if( Gesture::Started    == gesture.state ||
          Gesture::Continuing == gesture.state )
      {
+       Vector2 targetSize;
+       mController.GetTargetSize( targetSize );
        if( x < mScrollThreshold )
        {
          mScrollDirection = SCROLL_RIGHT;
          mHandleScrolling = type;
          StartScrollTimer();
        }
-       else if( x > mTextControlParent.Self().GetTargetSize().width - mScrollThreshold )
+       else if( x > targetSize.width - mScrollThreshold )
        {
          mScrollDirection = SCROLL_LEFT;
          mHandleScrolling = type;
        {
          mHandleScrolling = HANDLE_TYPE_COUNT;
          StopScrollTimer();
-         mObserver.HandleEvent( type, HANDLE_PRESSED, x, y );
+         mController.DecorationEvent( type, HANDLE_PRESSED, x, y );
        }
      }
      else if( Gesture::Finished  == gesture.state ||
               Gesture::Cancelled == gesture.state )
      {
-       if( mScrollTimer && mScrollTimer.IsRunning() )
+       if( mScrollTimer &&
+           ( mScrollTimer.IsRunning() || mNotifyEndOfScroll ) )
        {
+         mNotifyEndOfScroll = false;
          mHandleScrolling = HANDLE_TYPE_COUNT;
          StopScrollTimer();
-         mObserver.HandleEvent( type, HANDLE_STOP_SCROLLING, x, y );
+         mController.DecorationEvent( type, HANDLE_STOP_SCROLLING, x, y );
        }
        else
        {
-         mObserver.HandleEvent( type, HANDLE_RELEASED, x, y );
+         mController.DecorationEvent( type, HANDLE_RELEASED, x, y );
        }
-       handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+       if( GRAB_HANDLE == type )
+       {
+         handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+       }
+       else
+       {
+         HandleType selectionHandleType = type;
+         if( mSwapSelectionHandles != handle.flipped )
+         {
+           selectionHandleType = ( LEFT_SELECTION_HANDLE == type ) ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE;
+         }
+         handle.actor.SetImage( mHandleImages[selectionHandleType][HANDLE_IMAGE_RELEASED] );
+       }
+       handle.pressed = false;
      }
    }
  
      {
        const TouchPoint& point = event.GetPoint(0);
  
-       if( TouchPoint::Down == point.state &&
-           mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED] )
+       if( TouchPoint::Down == point.state )
        {
-         mHandle[GRAB_HANDLE].actor.SetImage( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED] );
+         mHandle[GRAB_HANDLE].pressed = true;
+         Image imagePressed = mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED];
+         if( imagePressed )
+         {
+           mHandle[GRAB_HANDLE].actor.SetImage( imagePressed );
+         }
        }
-       else if( TouchPoint::Up == point.state &&
-                mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] )
+       else if( TouchPoint::Up == point.state )
        {
-         mHandle[GRAB_HANDLE].actor.SetImage( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
+         mHandle[GRAB_HANDLE].pressed = false;
+         Image imageReleased = mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED];
+         if( imageReleased )
+         {
+           mHandle[GRAB_HANDLE].actor.SetImage( imageReleased );
+         }
        }
      }
  
      return true;
    }
  
-   bool OnHandleOneTouched( Actor actor, const TouchEvent& touch )
+   bool OnHandleOneTouched( Actor actor, const TouchEvent& event )
    {
-     // TODO
+     // Switch between pressed/release selection handle images
+     if( event.GetPointCount() > 0 &&
+         mHandle[LEFT_SELECTION_HANDLE].actor )
+     {
+       const TouchPoint& point = event.GetPoint(0);
+       const bool flip = mSwapSelectionHandles != mHandle[LEFT_SELECTION_HANDLE].flipped;
+       if( TouchPoint::Down == point.state )
+       {
+         mHandle[LEFT_SELECTION_HANDLE].pressed = true;
+         Image imagePressed = mHandleImages[flip ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED];
+         if( imagePressed )
+         {
+           mHandle[LEFT_SELECTION_HANDLE].actor.SetImage( imagePressed );
+         }
+       }
+       else if( TouchPoint::Up == point.state )
+       {
+         mHandle[LEFT_SELECTION_HANDLE].pressed = false;
+         Image imageReleased = mHandleImages[flip ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED];
+         if( imageReleased )
+         {
+           mHandle[LEFT_SELECTION_HANDLE].actor.SetImage( imageReleased );
+         }
+       }
+     }
      // Consume to avoid pop-ups accidentally closing, when handle is outside of pop-up area
      return true;
    }
  
-   bool OnHandleTwoTouched( Actor actor, const TouchEvent& touch )
+   bool OnHandleTwoTouched( Actor actor, const TouchEvent& event )
    {
-     // TODO
+     // Switch between pressed/release selection handle images
+     if( event.GetPointCount() > 0 &&
+         mHandle[RIGHT_SELECTION_HANDLE].actor )
+     {
+       const TouchPoint& point = event.GetPoint(0);
+       const bool flip = mSwapSelectionHandles != mHandle[RIGHT_SELECTION_HANDLE].flipped;
+       if( TouchPoint::Down == point.state )
+       {
+         Image imagePressed = mHandleImages[flip ? LEFT_SELECTION_HANDLE : RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED];
+         mHandle[RIGHT_SELECTION_HANDLE].pressed = true;
+         if( imagePressed )
+         {
+           mHandle[RIGHT_SELECTION_HANDLE].actor.SetImage( imagePressed );
+         }
+       }
+       else if( TouchPoint::Up == point.state )
+       {
+         Image imageReleased = mHandleImages[flip ? LEFT_SELECTION_HANDLE : RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED];
+         mHandle[RIGHT_SELECTION_HANDLE].pressed = false;
+         if( imageReleased )
+         {
+           mHandle[RIGHT_SELECTION_HANDLE].actor.SetImage( imageReleased );
+         }
+       }
+     }
      // Consume to avoid pop-ups accidentally closing, when handle is outside of pop-up area
      return true;
    }
    {
      float alternativePosition=0.0f;;
  
 +    /*
      if ( mPrimaryCursor ) // Secondary cursor not used for paste
      {
        Cursor cursor = PRIMARY_CURSOR;
        alternativePosition = mCursor[cursor].position.y;
      }
 -
 +    */
      const float popupHeight = 120.0f; // todo Set as a MaxSize Property in Control or retrieve from CopyPastePopup class.
  
      if( mHandle[GRAB_HANDLE].active )
      // if can't be positioned above, then position below row.
      alternativeYPosition = AlternatePopUpPositionRelativeToCursor();
  
-     mCopyPastePopup.SetY( alternativeYPosition );
+     mCopyPastePopup.actor.SetY( alternativeYPosition );
    }
  
  
-   void SetUpPopUpPositionNotifications( )
+   void SetUpPopupPositionNotifications( )
    {
      // Note Property notifications ignore any set anchor point so conditions must allow for this.  Default is Top Left.
  
      Vector4 worldCoordinatesBoundingBox;
      LocalToWorldCoordinatesBoundingBox( mBoundingBox, worldCoordinatesBoundingBox );
  
-     float popupHeight = mCopyPastePopup.GetRelayoutSize( Dimension::HEIGHT);
+     float popupHeight = mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT);
  
-     PropertyNotification verticalExceedNotification = mCopyPastePopup.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
-                                                       OutsideCondition( worldCoordinatesBoundingBox.y + popupHeight/2,
-                                                                         worldCoordinatesBoundingBox.w - popupHeight/2 ) );
+     PropertyNotification verticalExceedNotification = mCopyPastePopup.actor.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+                                                       OutsideCondition( worldCoordinatesBoundingBox.y + popupHeight * 0.5f,
+                                                                         worldCoordinatesBoundingBox.w - popupHeight * 0.5f ) );
  
      verticalExceedNotification.NotifySignal().Connect( this, &Decorator::Impl::PopUpLeavesVerticalBoundary );
    }
      }
  
      requiredPopupPosition.x = requiredPopupPosition.x + xOffSetToKeepWithinBounds;
+     // Prevent pixel mis-alignment by rounding down.
+     requiredPopupPosition.x = static_cast<int>( requiredPopupPosition.x );
+     requiredPopupPosition.y = static_cast<int>( requiredPopupPosition.y );
+   }
+   void FlipSelectionHandleImages()
+   {
+     SetupTouchEvents();
+     CreateSelectionHandles();
+     HandleImpl& leftHandle = mHandle[LEFT_SELECTION_HANDLE];
+     HandleImpl& rightHandle = mHandle[RIGHT_SELECTION_HANDLE];
+     const HandleImageType leftImageType = leftHandle.pressed ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED;
+     const HandleImageType rightImageType = rightHandle.pressed ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED;
+     const bool leftFlipped = mSwapSelectionHandles != leftHandle.flipped;
+     const bool rightFlipped = mSwapSelectionHandles != rightHandle.flipped;
+     leftHandle.actor.SetImage( leftFlipped ? mHandleImages[RIGHT_SELECTION_HANDLE][leftImageType] : mHandleImages[LEFT_SELECTION_HANDLE][leftImageType] );
+     leftHandle.actor.SetAnchorPoint( leftFlipped ? AnchorPoint::TOP_LEFT : AnchorPoint::TOP_RIGHT );
+     rightHandle.actor.SetImage( rightFlipped ? mHandleImages[LEFT_SELECTION_HANDLE][rightImageType] : mHandleImages[RIGHT_SELECTION_HANDLE][rightImageType] );
+     rightHandle.actor.SetAnchorPoint( rightFlipped ? AnchorPoint::TOP_RIGHT : AnchorPoint::TOP_LEFT );
    }
  
    void SetScrollThreshold( float threshold )
      return mScrollSpeed;
    }
  
+   void NotifyEndOfScroll()
+   {
+     StopScrollTimer();
+     if( mScrollTimer )
+     {
+       mNotifyEndOfScroll = true;
+     }
+   }
    /**
     * Creates and starts a timer to scroll the text when handles are close to the edges of the text.
     *
    {
      if( HANDLE_TYPE_COUNT != mHandleScrolling )
      {
-       mObserver.HandleEvent( mHandleScrolling,
-                              HANDLE_SCROLLING,
-                              mScrollDirection == SCROLL_RIGHT ? mScrollDistance : -mScrollDistance,
-                              0.f );
+       mController.DecorationEvent( mHandleScrolling,
+                                    HANDLE_SCROLLING,
+                                    mScrollDirection == SCROLL_RIGHT ? mScrollDistance : -mScrollDistance,
+                                    0.f );
      }
  
      return true;
    }
  
-   Internal::Control&  mTextControlParent;
-   Observer&           mObserver;
+   ControllerInterface& mController;
  
    TapGestureDetector  mTapDetector;
    PanGestureDetector  mPanGestureDetector;
    Timer               mScrollTimer;               ///< Timer used to scroll the text when the grab handle is moved close to the edges.
  
    Layer               mActiveLayer;               ///< Layer for active handles and alike that ensures they are above all else.
 -  ImageActor          mPrimaryCursor;
 -  ImageActor          mSecondaryCursor;
 -  MeshActor           mHighlightMeshActor;        ///< Mesh Actor to display highlight
 +  //ImageActor          mPrimaryCursor;
 +  //ImageActor          mSecondaryCursor;
 +  //MeshActor           mHighlightMeshActor;        ///< Mesh Actor to display highlight
-   TextSelectionPopup  mCopyPastePopup;
+   PopupImpl           mCopyPastePopup;
+   TextSelectionPopup::Buttons mEnabledPopupButtons; /// Bit mask of currently enabled Popup buttons
+   TextSelectionPopupCallbackInterface& mTextSelectionPopupCallbackInterface;
  
    Image               mHandleImages[HANDLE_TYPE_COUNT][HANDLE_IMAGE_TYPE_COUNT];
    Image               mCursorImage;
 -  Mesh                mHighlightMesh;             ///< Mesh for highlight
 -  MeshData            mHighlightMeshData;         ///< Mesh Data for highlight
 -  Material            mHighlightMaterial;         ///< Material used for highlight
 +  //Mesh                mHighlightMesh;             ///< Mesh for highlight
 +  //MeshData            mHighlightMeshData;         ///< Mesh Data for highlight
 +  //Material            mHighlightMaterial;         ///< Material used for highlight
  
    CursorImpl          mCursor[CURSOR_COUNT];
    HandleImpl          mHandle[HANDLE_TYPE_COUNT];
  
    Rect<int>           mBoundingBox;
    Vector4             mHighlightColor;            ///< Color of the highlight
+   Vector2             mHighlightPosition;         ///< The position of the highlight actor.
  
    unsigned int        mActiveCursor;
    unsigned int        mCursorBlinkInterval;
    float               mScrollThreshold;         ///< Defines a square area inside the control, close to the edge. A cursor entering this area will trigger scroll events.
    float               mScrollSpeed;             ///< The scroll speed in pixels per second.
    float               mScrollDistance;          ///< Distance the text scrolls during a scroll interval.
-   unsigned int        mScrollInterval;          ///< Time in milliseconds of a scroll interval.
  
    bool                mActiveCopyPastePopup   : 1;
    bool                mCursorBlinkStatus      : 1; ///< Flag to switch between blink on and blink off.
    bool                mPrimaryCursorVisible   : 1; ///< Whether the primary cursor is visible.
    bool                mSecondaryCursorVisible : 1; ///< Whether the secondary cursor is visible.
+   bool                mSwapSelectionHandles   : 1; ///< Whether to swap the selection handle images.
+   bool                mNotifyEndOfScroll      : 1; ///< Whether to notify the end of the scroll.
  };
  
- DecoratorPtr Decorator::New( Internal::Control& parent, Observer& observer )
+ DecoratorPtr Decorator::New( ControllerInterface& controller,
+                              TextSelectionPopupCallbackInterface& callbackInterface )
  {
-   return DecoratorPtr( new Decorator(parent, observer) );
+   return DecoratorPtr( new Decorator( controller,
+                                       callbackInterface ) );
  }
  
  void Decorator::SetBoundingBox( const Rect<int>& boundingBox )
@@@ -1206,6 -1374,18 +1382,18 @@@ void Decorator::GetPosition( HandleTyp
    height = handle.lineHeight;
  }
  
+ const Vector2& Decorator::GetPosition( HandleType handleType ) const
+ {
+   return mImpl->mHandle[handleType].position;
+ }
+ void Decorator::SwapSelectionHandlesEnabled( bool enable )
+ {
+   mImpl->mSwapSelectionHandles = enable;
+   mImpl->FlipSelectionHandleImages();
+ }
  void Decorator::AddHighlight( float x1, float y1, float x2, float y2 )
  {
    mImpl->mHighlightQuadList.push_back( QuadCoordinates(x1, y1, x2, y2) );
  void Decorator::ClearHighlights()
  {
    mImpl->mHighlightQuadList.clear();
+   mImpl->mHighlightPosition = Vector2::ZERO;
  }
  
  void Decorator::SetHighlightColor( const Vector4& color )
@@@ -1236,6 -1417,16 +1425,16 @@@ bool Decorator::IsPopupActive() cons
    return mImpl->mActiveCopyPastePopup ;
  }
  
+ void Decorator::SetEnabledPopupButtons( TextSelectionPopup::Buttons& enabledButtonsBitMask )
+ {
+    mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
+ }
+ TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons()
+ {
+   return mImpl->mEnabledPopupButtons;
+ }
  /** Scroll **/
  
  void Decorator::SetScrollThreshold( float threshold )
@@@ -1258,15 -1449,21 +1457,21 @@@ float Decorator::GetScrollSpeed() cons
    return mImpl->GetScrollSpeed();
  }
  
+ void Decorator::NotifyEndOfScroll()
+ {
+   mImpl->NotifyEndOfScroll();
+ }
  Decorator::~Decorator()
  {
    delete mImpl;
  }
  
- Decorator::Decorator( Dali::Toolkit::Internal::Control& parent, Observer& observer )
+ Decorator::Decorator( ControllerInterface& controller,
+                       TextSelectionPopupCallbackInterface& callbackInterface )
  : mImpl( NULL )
  {
-   mImpl = new Decorator::Impl( parent, observer );
+   mImpl = new Decorator::Impl( controller, callbackInterface );
  }
  
  } // namespace Text
  #include <dali/public-api/actors/image-actor.h>
  #include <dali/public-api/common/stage.h>
  
 +#define MAKE_SHADER(A)#A
 +
 +namespace
 +{
 +const char* VERTEX_SHADER = MAKE_SHADER(
 +attribute mediump vec2    aPosition;
 +attribute mediump vec2    aTexCoord;
 +uniform   mediump mat4    uMvpMatrix;
 +uniform   mediump vec3    uSize;
 +varying   mediump vec2    vTexCoord;
 +
 +void main()
 +{
 +  mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
 +  position.xyz *= uSize;
 +  gl_Position = uMvpMatrix * position;
 +  vTexCoord = aTexCoord;
 +}
 +);
 +
 +const char* FRAGMENT_SHADER = MAKE_SHADER(
 +uniform         sampler2D sTexture;
 +varying mediump vec2      vTexCoord;
 +
 +void main()
 +{
 +  gl_FragColor = texture2D( sTexture, vTexCoord );
 +}
 +);
 +
 +const char* VERTEX_SHADER_SHADOW = MAKE_SHADER(
 +attribute mediump vec2    aPosition;
 +attribute mediump vec2    aTexCoord;
 +uniform   mediump vec3    uSize;
 +varying   mediump vec2    vTexCoord;
 +
 +void main()
 +{
 +  mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
 +  position.xyz *= uSize;
 +  gl_Position = position;
 +  vTexCoord = aTexCoord;
 +}
 +);
 +
 +const char* FRAGMENT_SHADER_SHADOW = MAKE_SHADER(
 +uniform         sampler2D sTexture;
 +uniform lowp    vec4      uColor;
 +varying mediump vec2      vTexCoord;
 +
 +void main()
 +{
 +  mediump vec4 color = texture2D( sTexture, vTexCoord );
 +  gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
 +}
 +);
 +}
 +
  namespace Dali
  {
  
@@@ -88,15 -30,28 +88,27 @@@ namespace Toolki
  namespace Internal
  {
  
 -//#define DISPLAY_ATLAS
 -
  AtlasGlyphManager::AtlasGlyphManager()
 -: mCount( 0 )
  {
    mAtlasManager = Dali::Toolkit::AtlasManager::New();
 +  mEffectBufferShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
 +  mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
  }
  
  AtlasGlyphManager::~AtlasGlyphManager()
  {
+   // Clear up any remaining references
+   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+         fontGlyphRecordIt != mFontGlyphRecords.end();
+         ++fontGlyphRecordIt )
+   {
+     for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+           glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
+           ++glyphRecordEntryIt )
+     {
+       mAtlasManager.Remove( glyphRecordEntryIt->mImageId );
+     }
+   }
  }
  
  AtlasGlyphManagerPtr AtlasGlyphManager::New()
    return internal;
  }
  
- void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ void AtlasGlyphManager::Add( Text::FontId fontId,
+                              const Text::GlyphInfo& glyph,
                               const BufferImage& bitmap,
                               Dali::Toolkit::AtlasManager::AtlasSlot& slot )
  {
-   GlyphRecord record;
-   record.mFontId = glyph.fontId;
-   record.mIndex = glyph.index;
    mAtlasManager.Add( bitmap, slot );
+   GlyphRecordEntry record;
+   record.mIndex = glyph.index;
    record.mImageId = slot.mImageId;
-   mGlyphRecords.PushBack( record );
+   record.mCount = 1;
+   // Have glyph records been created for this fontId ?
+   bool foundGlyph = false;
+   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+         fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
+   {
+     if ( fontGlyphRecordIt->mFontId == fontId )
+     {
+       fontGlyphRecordIt->mGlyphRecords.PushBack( record );
+       foundGlyph = true;
+       break;
+     }
+   }
+   if ( !foundGlyph )
+   {
+     // We need to add a new font entry
+     FontGlyphRecord fontGlyphRecord;
+     fontGlyphRecord.mFontId = fontId;
+     fontGlyphRecord.mGlyphRecords.PushBack( record );
+     mFontGlyphRecords.push_back( fontGlyphRecord );
+   }
 -
 -#ifdef DISPLAY_ATLAS
 -  {
 -    uint32_t atlasCount = mAtlasManager.GetAtlasCount();
 -    if ( atlasCount > mCount )
 -    {
 -      for ( uint32_t i = 0; i < atlasCount; ++i )
 -      {
 -        ImageActor actor = ImageActor::New( mAtlasManager.GetAtlasContainer( i + 1u ) );
 -        actor.SetParentOrigin( Vector3( 0.5f, 0.25f + ( static_cast< float >( i ) * 0.25f ), 0.5f ) );
 -        actor.SetAnchorPoint( AnchorPoint::CENTER );
 -        actor.SetSize( 256.0f, 256.0f );
 -        Stage::GetCurrent().Add( actor );
 -      }
 -    }
 -    mCount = atlasCount;
 -  }
 -#endif
  }
  
  void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
                                            const Vector2& position,
 -                                          MeshData& meshData )
 +                                          Toolkit::AtlasManager::Mesh2D& mesh )
  {
-   mAtlasManager.GenerateMeshData( imageId, position, mesh );
+   // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
 -  mAtlasManager.GenerateMeshData( imageId, position, meshData, false );
++  mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
  }
  
 -void AtlasGlyphManager::StitchMesh( MeshData& first,
 -                                    const MeshData& second )
 +void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
 +                                    const Toolkit::AtlasManager::Mesh2D& second )
  {
    mAtlasManager.StitchMesh( first, second );
  }
  
void AtlasGlyphManager::Cached( Text::FontId fontId,
bool AtlasGlyphManager::Cached( Text::FontId fontId,
                                  uint32_t index,
                                  Dali::Toolkit::AtlasManager::AtlasSlot& slot )
  {
-   for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+         fontGlyphRecordIt != mFontGlyphRecords.end();
+         ++fontGlyphRecordIt )
    {
-     if ( fontId == mGlyphRecords[ i ].mFontId && index == mGlyphRecords[ i ].mIndex )
+     if ( fontGlyphRecordIt->mFontId == fontId )
      {
-       slot.mImageId = mGlyphRecords[ i ].mImageId;
-       slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
-       return;
+       for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+             glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+             ++glyphRecordIt )
+       {
+         if ( glyphRecordIt->mIndex == index )
+         {
+           slot.mImageId = glyphRecordIt->mImageId;
+           slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
+           return true;
+         }
+       }
      }
    }
    slot.mImageId = 0;
+   return false;
  }
  
  Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
@@@ -163,43 -170,45 +209,55 @@@ void AtlasGlyphManager::SetNewAtlasSize
    mAtlasManager.SetNewAtlasSize( size );
  }
  
- void AtlasGlyphManager::Remove( uint32_t imageId )
+ Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
+ {
+   return mAtlasManager.GetPixelFormat( atlasId );
+ }
+ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
+ {
+   mMetrics.mGlyphCount = mFontGlyphRecords.size();
+   mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
+   return mMetrics;
+ }
+ void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
  {
-   if ( mAtlasManager.Remove( imageId ) )
+   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+         fontGlyphRecordIt != mFontGlyphRecords.end();
+         ++fontGlyphRecordIt )
    {
-     for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+     if ( fontGlyphRecordIt->mFontId == fontId )
      {
-       if ( mGlyphRecords[ i ].mImageId == imageId )
+       for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+             glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+             ++glyphRecordIt )
        {
-         mGlyphRecords.Remove( mGlyphRecords.Begin() + i );
-         return;
+         if ( glyphRecordIt->mImageId == imageId )
+         {
+           glyphRecordIt->mCount += delta;
+           if ( !glyphRecordIt->mCount )
+           {
+             mAtlasManager.Remove( glyphRecordIt->mImageId );
+             fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+           }
+           return;
+         }
        }
      }
    }
  }
  
- Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
- {
-   return mAtlasManager.GetPixelFormat( atlasId );
- }
 +Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
 +{
 +  return mAtlasManager.GetMaterial( atlasId );
 +}
 +
 +Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
 +{
 +  return mAtlasManager.GetSampler( atlasId );
 +}
 +
- const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
- {
-   mMetrics.mGlyphCount = mGlyphRecords.Size();
-   mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
-   return mMetrics;
- }
  } // namespace Internal
  
  } // namespace Toolkit
@@@ -49,11 -49,17 +49,17 @@@ class AtlasGlyphManager : public Dali::
  {
  public:
  
-   struct GlyphRecord
+   struct GlyphRecordEntry
    {
-     Text::FontId mFontId;
      Text::GlyphIndex mIndex;
      uint32_t mImageId;
+     int32_t mCount;
+   };
+   struct FontGlyphRecord
+   {
+     Text::FontId mFontId;
+     Vector< GlyphRecordEntry > mGlyphRecords;
    };
  
    AtlasGlyphManager();
@@@ -68,7 -74,8 +74,8 @@@
    /**
     * @copydoc Toolkit::AtlasGlyphManager::Add
     */
-   void Add( const Text::GlyphInfo& glyph,
+   void Add( Text::FontId fontId,
+             const Text::GlyphInfo& glyph,
              const BufferImage& bitmap,
              Dali::Toolkit::AtlasManager::AtlasSlot& slot );
  
     */
    void GenerateMeshData( uint32_t imageId,
                           const Vector2& position,
 -                         MeshData& meshData );
 +                         Toolkit::AtlasManager::Mesh2D& mesh );
  
    /**
     * @copydoc Toolkit::AtlasGlyphManager::StitchMesh
     */
 -  void StitchMesh( MeshData& first,
 -                   const MeshData& second );
 +  void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
 +                   const Toolkit::AtlasManager::Mesh2D& second );
  
    /**
     * @copydoc Toolkit::AtlasGlyphManager::Cached
     */
-   void Cached( Text::FontId fontId,
+   bool Cached( Text::FontId fontId,
                 Text::GlyphIndex index,
                 Dali::Toolkit::AtlasManager::AtlasSlot& slot );
  
    void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight );
  
    /**
-    * @copydoc Toolkit::AtlasGlyphManager::Remove
 -   * @copydoc toolkit::AtlasGlyphManager::GetPixelFormat
++   * @copydoc Toolkit::AtlasGlyphManager::GetPixelFormat
     */
-   void Remove( uint32_t imageId );
+   Pixel::Format GetPixelFormat( uint32_t atlasId );
  
    /**
-    * @copydoc Toolkit::AtlasGlyphManager::GetPixelFormat
 -   * @copydoc toolkit::AtlasGlyphManager::GetMetrics
++   * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
 +   */
-   Pixel::Format GetPixelFormat( uint32_t atlasId );
++  void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
 +
 +  /**
 +   * @copydoc Toolkit::AtlasGlyphManager::GetMaterial
 +   */
 +  Material GetMaterial( uint32_t atlasId ) const;
 +
 +  /**
 +   * @copydoc Toolkit::AtlasGlyphManager::GetMaterial
 +   */
 +  Sampler GetSampler( uint32_t atlasId ) const;
 +
 +  /**
 +   * @copydoc Toolkit::AtlasGlyphManager::GetMetrics
     */
    const Toolkit::AtlasGlyphManager::Metrics& GetMetrics();
  
    /**
 -   * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
 +   * @copydoc Toolkit::AtlasGlyphManager::GetEffectBufferShader
     */
 -  void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
 +  Shader GetEffectBufferShader() const
 +  {
 +    return mEffectBufferShader;
 +  }
 +
 +  /**
 +   * @copydoc Toolkit::AtlasGlyphManager::GetGlyphShadowShader
 +   */
 +  Shader GetGlyphShadowShader() const
 +  {
 +    return mShadowShader;
 +  }
  
  private:
  
 -  Dali::Toolkit::AtlasManager mAtlasManager;
 +  Dali::Toolkit::AtlasManager mAtlasManager;          ///> Atlas Manager created by GlyphManager
-   Vector< GlyphRecord > mGlyphRecords;                ///> Cached glyph information
+   std::vector< FontGlyphRecord > mFontGlyphRecords;
 -  uint32_t mCount;
 -  Toolkit::AtlasGlyphManager::Metrics mMetrics;
 +  Toolkit::AtlasGlyphManager::Metrics mMetrics;       ///> Metrics to pass back on GlyphManager status
 +  Shader mEffectBufferShader;                         ///> Shader used to render drop shadow buffer textures
 +  Shader mShadowShader;                               ///> Shader used to render drop shadow into buffer
  };
  
  } // namespace Internal
@@@ -177,4 -157,4 +184,4 @@@ inline Internal::AtlasGlyphManager& Get
  } // namespace Dali
  
  
-- #endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
++ #endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
@@@ -69,33 -69,34 +69,34 @@@ AtlasGlyphManager::AtlasGlyphManager(In
  {
  }
  
- void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ void AtlasGlyphManager::Add( Text::FontId fontId,
+                              const Text::GlyphInfo& glyph,
                               const BufferImage& bitmap,
                               AtlasManager::AtlasSlot& slot )
  {
-   GetImplementation(*this).Add( glyph, bitmap, slot );
+   GetImplementation(*this).Add( fontId, glyph, bitmap, slot );
  }
  
  void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
                                            const Vector2& position,
 -                                          MeshData& meshData )
 +                                          Toolkit::AtlasManager::Mesh2D& mesh )
  {
    GetImplementation(*this).GenerateMeshData( imageId,
                                               position,
 -                                             meshData );
 +                                             mesh );
  }
  
 -void AtlasGlyphManager::StitchMesh( MeshData& first,
 -                                    const MeshData& second )
 +void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
 +                                    const Toolkit::AtlasManager::Mesh2D& second )
  {
    GetImplementation(*this).StitchMesh( first, second );
  }
  
void AtlasGlyphManager::Cached( Text::FontId fontId,
bool AtlasGlyphManager::Cached( Text::FontId fontId,
                                  Text::GlyphIndex index,
                                  AtlasManager::AtlasSlot& slot )
  {
-   GetImplementation(*this).Cached( fontId, index, slot );
+   return GetImplementation(*this).Cached( fontId, index, slot );
  }
  
  void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
@@@ -108,41 -109,21 +109,41 @@@ Vector2 AtlasGlyphManager::GetAtlasSize
    return GetImplementation(*this).GetAtlasSize( atlasId );
  }
  
- void AtlasGlyphManager::Remove( uint32_t imageId )
- {
-   GetImplementation(*this).Remove( imageId );
- }
  Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
  {
    return GetImplementation(*this).GetPixelFormat( atlasId );
  }
  
 +Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
 +{
 +  return GetImplementation(*this).GetMaterial( atlasId );
 +}
 +
 +Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
 +{
 +  return GetImplementation(*this).GetSampler( atlasId );
 +}
 +
  const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
  {
    return GetImplementation(*this).GetMetrics();
  }
  
+ void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+ {
+   GetImplementation(*this).AdjustReferenceCount( fontId, imageId, delta );
+ }
 +Shader AtlasGlyphManager::GetEffectBufferShader() const
 +{
 +  return GetImplementation(*this).GetEffectBufferShader();
 +}
 +
 +Shader AtlasGlyphManager::GetGlyphShadowShader() const
 +{
 +  return GetImplementation(*this).GetGlyphShadowShader();
 +}
 +
  } // namespace Toolkit
  
  } // namespace Dali
@@@ -71,11 -71,13 +71,13 @@@ public
    /**
     * @brief Ask Atlas Manager to add a glyph
     *
+    * @param[in] fontId fontId glyph comes from
     * @param[in] glyph glyph to add to an atlas
     * @param[in] bitmap bitmap to use for glyph addition
     * @param[out] slot information returned by atlas manager for addition
     */
-   void Add( const Text::GlyphInfo& glyph,
+   void Add( Text::FontId fontId,
+             const Text::GlyphInfo& glyph,
              const BufferImage& bitmap,
              AtlasManager::AtlasSlot& slot );
  
@@@ -88,7 -90,7 +90,7 @@@
     */
    void GenerateMeshData( uint32_t imageId,
                           const Vector2& position,
 -                         MeshData& meshData );
 +                         Toolkit::AtlasManager::Mesh2D& mesh );
  
    /**
     * @brief Stitch Two Meshes together
@@@ -96,8 -98,8 +98,8 @@@
     * @param[in] first first mesh
     * @param[in] second second mesh
     */
 -  void StitchMesh( MeshData& first,
 -                   const MeshData& second );
 +  void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
 +                   const Toolkit::AtlasManager::Mesh2D& second );
  
    /**
     * @brief Check to see if a glyph is being cached
     * @param[in] fontId The font that this glyph comes from
     * @param[in] index The GlyphIndex of this glyph
     * @param[out] slot container holding information about the glyph( mImage = 0 indicates not being cached )
+    *
+    * @return Whether glyph is cached or not ?
     */
-   void Cached( Text::FontId fontId,
+   bool Cached( Text::FontId fontId,
                 Text::GlyphIndex index,
                 AtlasManager::AtlasSlot& slot );
  
    void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight );
  
    /**
-    * @brief Unreference an image from the atlas and remove from cache if no longer needed
-    *
-    * @param[in] imageId ID of the image
-    */
-   void Remove( uint32_t imageId );
-   /**
     * @brief Get the Pixel Format used by an atlas
     *
     * @param[in] atlasId Id of atlas to check
    Pixel::Format GetPixelFormat( uint32_t atlasId );
  
    /**
 +   * @brief Get the material used by an atlas
 +   *
 +   * @param[in] atlasId Id of an atlas
 +   *
 +   * @return The material used by the atlas
 +   */
 +  Material GetMaterial( uint32_t atlasId ) const;
 +
 +  /**
 +   * @brief Get the sampler used by an atlas
 +   *
 +   * @param[in] atlasId Id of an atlas
 +   *
 +   * @return The sampler used by the atlas
 +   */
 +  Sampler GetSampler( uint32_t atlasId ) const;
 +
 +  /**
     * @brief Get Glyph Manager metrics
     *
     * @return const reference to glyph manager metrics
    const Metrics& GetMetrics();
  
    /**
+    * @brief Adjust the reference count for an imageId and remove cache entry if it becomes free
+    *
+    * @param[in] fontId the font this image came from
+    * @param[in] imageId The imageId
+    * @param[in] delta adjustment to make to reference count
+    */
+   void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
++  /**
 +   * @brief Get Shader used for rendering glyph effect buffers
 +   *
 +   * @return Handle of shader needed
 +   */
 +  Shader GetEffectBufferShader() const;
 +
 +  /**
 +   * @brief Get Shader used rendering Glyph Shadows
 +   *
 +   * @return Handle of shader needed
 +   */
 +  Shader GetGlyphShadowShader() const;
 +
  private:
  
    explicit DALI_INTERNAL AtlasGlyphManager(Internal::AtlasGlyphManager *impl);
  
  // EXTERNAL INCLUDES
  #include <dali/dali.h>
 -#include <dali/integration-api/debug.h>
 +#include <dali/devel-api/object/property-buffer.h>
 +#include <dali/devel-api/rendering/geometry.h>
 +#include <dali/devel-api/rendering/renderer.h>
 +#include <dali/devel-api/rendering/sampler.h>
 +#include <dali/devel-api/rendering/shader.h>
  #include <dali/devel-api/text-abstraction/font-client.h>
 -#include <dali/devel-api/actors/mesh-actor.h>
 -#include <dali/devel-api/geometry/mesh.h>
 -
 -
 +#include <dali/integration-api/debug.h>
  // INTERNAL INCLUDES
 -#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
 -#include <dali-toolkit/internal/text/line-run.h>
 +#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
  #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
 -#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shader.h>
 -#include <dali-toolkit/internal/text/rendering/shaders/text-bgra-shader.h>
 -#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.h>
  
  using namespace Dali;
  using namespace Dali::Toolkit;
@@@ -41,13 -44,14 +41,13 @@@ namespac
    Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
  #endif
  
 -  const float ZERO( 0.0f );
 -  const float HALF( 0.5f );
 -  const float ONE( 1.0f );
 -  const float TWO( 2.0f );
 -  const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
 -  const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
 +const float ZERO( 0.0f );
 +const float HALF( 0.5f );
 +const float ONE( 1.0f );
 +const float TWO( 2.0f );
 +const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
 +const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
  }
 -
  struct AtlasRenderer::Impl : public ConnectionTracker
  {
  
@@@ -61,7 -65,7 +61,7 @@@
    {
      Vector4 mColor;
      uint32_t mAtlasId;
 -    MeshData mMeshData;
 +    AtlasManager::Mesh2D mMesh;
      FrameBufferImage mBuffer;
      bool mIsUnderline;
    };
      uint32_t mMeshRecordIndex;
    };
  
-   struct AtlasRecord
+   struct MaxBlockSize
    {
-     uint32_t mImageId;
+     FontId mFontId;
+     uint32_t mNeededBlockWidth;
+     uint32_t mNeededBlockHeight;
+   };
+   struct CheckEntry
+   {
+     FontId mFontId;
      Text::GlyphIndex mIndex;
    };
  
-   struct MaxBlockSize
+   struct TextCacheEntry
    {
      FontId mFontId;
-     uint32_t mNeededBlockWidth;
-     uint32_t mNeededBlockHeight;
+     Text::GlyphIndex mIndex;
+     uint32_t mImageId;
    };
  
    Impl()
    {
      mGlyphManager = AtlasGlyphManager::Get();
      mFontClient = TextAbstraction::FontClient::Get();
 -    mBasicShader = BasicShader::New();
 -    mBgraShader = BgraShader::New();
 -    mBasicShadowShader = BasicShadowShader::New();
  
 -    mFace.reserve( 6u );
 -    mFace.push_back( 0 ); mFace.push_back( 2u ); mFace.push_back( 1u );
 -    mFace.push_back( 1u ); mFace.push_back( 2u ); mFace.push_back( 3u );
 +    mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
 +    mQuadVertexFormat[ "aTexCoord" ] = Property::VECTOR2;
 +    mQuadIndexFormat[ "indices" ] = Property::UNSIGNED_INTEGER;
    }
  
    void AddGlyphs( const std::vector<Vector2>& positions,
                    const Vector4& shadowColor,
                    bool underlineEnabled,
                    const Vector4& underlineColor,
 -                  float underlineHeight )
 +                  float underlineHeight,
 +                  unsigned int depth )
    {
      AtlasManager::AtlasSlot slot;
      std::vector< MeshRecord > meshContainer;
      Vector< Extent > extents;
+     TextCacheEntry textCacheEntry;
 +    mDepth = static_cast< int >( depth );
  
      float currentUnderlinePosition = ZERO;
      float currentUnderlineThickness = underlineHeight;
        style = STYLE_DROP_SHADOW;
      }
  
-     if ( mImageIds.Size() )
+     if ( mTextCache.Size() )
      {
-       // Unreference any currently used glyphs
-       RemoveText();
+       // Update the glyph cache with any changes to current text
+       RemoveText( glyphs );
      }
  
      CalculateBlocksSize( glyphs );
          }
  
          const Vector2& position = positions[ i ];
 -        MeshData newMeshData;
 +        AtlasManager::Mesh2D newMesh;
-         mGlyphManager.Cached( glyph.fontId, glyph.index, slot );
  
-         if ( slot.mImageId )
-         {
-           // This glyph already exists so generate mesh data plugging in our supplied position
-           mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
-           mImageIds.PushBack( slot.mImageId );
-         }
-         else
+         if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) )
          {
            // Select correct size for new atlas if needed....?
            if ( lastFontId != glyph.fontId )
            {
              }
  
              // Locate a new slot for our glyph
-             mGlyphManager.Add( glyph, bitmap, slot );
-             // Generate mesh data for this quad, plugging in our supplied position
-             if ( slot.mImageId )
-             {
-               mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
-               mImageIds.PushBack( slot.mImageId );
-             }
+             mGlyphManager.Add( glyph.fontId, glyph, bitmap, slot );
            }
          }
 -        mGlyphManager.GenerateMeshData( slot.mImageId, position, newMeshData );
+         // Generate mesh data for this quad, plugging in our supplied position
++        mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
+         textCacheEntry.mFontId = glyph.fontId;
+         textCacheEntry.mImageId = slot.mImageId;
+         textCacheEntry.mIndex = glyph.index;
+         mTextCache.PushBack( textCacheEntry );
          // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
          StitchTextMesh( meshContainer,
 -                        newMeshData,
 +                        newMesh,
                          extents,
                          textColor,
                          position.y + glyph.yBearing,
                          currentUnderlinePosition,
                          currentUnderlineThickness,
                          slot );
 -        lastFontId = glyph.fontId;
 +       lastFontId = glyph.fontId;
        }
      }
  
      {
        for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt )
        {
 -        MeshActor actor = MeshActor::New( Mesh::New( mIt->mMeshData ) );
 -        actor.SetColor( mIt->mColor );
 +        Actor actor = CreateMeshActor( *mIt );
  
 -        // Ensure that text rendering is unfiltered
 -        actor.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
 -        if ( mIt->mIsUnderline )
 +        // Create an effect if necessary
 +        if ( style == STYLE_DROP_SHADOW )
          {
 -          actor.SetColorMode( USE_OWN_COLOR );
 -        }
 -        else
 -        {
 -          actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
 -        }
 -
 -        // Check to see what pixel format the shader should be
 -        if ( mGlyphManager.GetPixelFormat( mIt->mAtlasId ) == Pixel::L8 )
 -        {
 -          // Create an effect if necessary
 -          if ( style == STYLE_DROP_SHADOW )
 -          {
 -            actor.Add( GenerateShadow( *mIt, shadowOffset, shadowColor ) );
 -          }
 -          actor.SetShaderEffect( mBasicShader );
 -        }
 -        else
 -        {
 -          actor.SetShaderEffect( mBgraShader );
 +          actor.Add( GenerateShadow( *mIt, shadowOffset, shadowColor ) );
          }
  
          if ( mActor )
            mActor = actor;
          }
        }
-       mActor.OffStageSignal().Connect( this, &AtlasRenderer::Impl::OffStageDisconnect );
      }
  #if defined(DEBUG_ENABLED)
      Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
  #endif
    }
  
 +  Actor CreateMeshActor( const MeshRecord& meshRecord )
 +  {
 +    PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, meshRecord.mMesh.mVertices.Size() );
 +    PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
 +    quadVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &meshRecord.mMesh.mVertices[ 0 ] ) );
 +    quadIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
 +
 +    Geometry quadGeometry = Geometry::New();
 +    quadGeometry.AddVertexBuffer( quadVertices );
 +    quadGeometry.SetIndexBuffer( quadIndices );
 +
 +    Material material = mGlyphManager.GetMaterial( meshRecord.mAtlasId );
 +    Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
 +    renderer.SetDepthIndex( mDepth );
 +    Actor actor = Actor::New();
 +    actor.AddRenderer( renderer );
 +    actor.SetSize( 1.0f, 1.0f );
 +    actor.SetColor( meshRecord.mColor );
 +
 +    if ( meshRecord.mIsUnderline )
 +    {
 +      actor.SetColorMode( USE_OWN_COLOR );
 +    }
 +    else
 +    {
 +      actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
 +    }
 +    return actor;
 +  }
 +
    void StitchTextMesh( std::vector< MeshRecord >& meshContainer,
 -                       MeshData& newMeshData,
 +                       AtlasManager::Mesh2D& newMesh,
                         Vector< Extent >& extents,
                         const Vector4& color,
                         float baseLine,
    {
      if ( slot.mImageId )
      {
 -      MeshData::VertexContainer verts = newMeshData.GetVertices();
 -      float left = verts[ 0 ].x;
 -      float right = verts[ 1 ].x;
 +      float left = newMesh.mVertices[ 0 ].mPosition.x;
 +      float right = newMesh.mVertices[ 1 ].mPosition.x;
  
        // Check to see if there's a mesh data object that references the same atlas ?
        uint32_t index = 0;
          if ( slot.mAtlasId == mIt->mAtlasId && color == mIt->mColor )
          {
            // Stitch the mesh to the existing mesh and adjust any extents
 -          mGlyphManager.StitchMesh( mIt->mMeshData, newMeshData );
 +          mGlyphManager.StitchMesh( mIt->mMesh, newMesh );
            AdjustExtents( extents,
                           meshContainer,
                           index,
        // No mesh data object currently exists that references this atlas, so create a new one
        MeshRecord meshRecord;
        meshRecord.mAtlasId = slot.mAtlasId;
 -      meshRecord.mMeshData = newMeshData;
 +      meshRecord.mMesh = newMesh;
        meshRecord.mColor = color;
        meshRecord.mIsUnderline = false;
        meshContainer.push_back( meshRecord );
      }
    }
  
-   // Unreference any glyphs that were used with this actor
-   void OffStageDisconnect( Dali::Actor actor )
+   void RemoveText( const Vector<GlyphInfo>& glyphs )
    {
-     RemoveText();
-   }
+     Vector< CheckEntry > checked;
+     CheckEntry checkEntry;
  
-   void RemoveText()
-   {
-     for ( uint32_t i = 0; i < mImageIds.Size(); ++i )
+     for ( Vector< TextCacheEntry >::Iterator tCit = mTextCache.Begin(); tCit != mTextCache.End(); ++tCit )
      {
-       mGlyphManager.Remove( mImageIds[ i ] );
+       uint32_t index = tCit->mIndex;
+       uint32_t fontId = tCit->mFontId;
+       // Check that this character has not already been checked...
+       bool wasChecked = false;
+       for ( Vector< CheckEntry >::Iterator cEit = checked.Begin(); cEit != checked.End(); ++cEit )
+       {
+         if ( fontId == cEit->mFontId && index == cEit->mIndex )
+         {
+           wasChecked = true;
+         }
+       }
+       if ( !wasChecked )
+       {
+         int32_t newCount = 0;
+         int32_t oldCount = 0;
+         // How many times does this character occur in the old text ?
+         for ( Vector< TextCacheEntry >::Iterator oTcit = mTextCache.Begin(); oTcit != mTextCache.End(); ++oTcit )
+         {
+           if ( fontId == oTcit->mFontId && index == oTcit->mIndex )
+           {
+             oldCount++;
+           }
+         }
+         // And how many times in the new ?
+         for ( Vector< GlyphInfo >::Iterator cGit = glyphs.Begin(); cGit != glyphs.End(); ++cGit )
+         {
+           if ( fontId == cGit->fontId && index == cGit->index )
+           {
+             newCount++;
+           }
+         }
+         mGlyphManager.AdjustReferenceCount( fontId, tCit->mImageId, newCount - oldCount );
+         checkEntry.mIndex = index;
+         checkEntry.mFontId = fontId;
+         checked.PushBack( checkEntry );
+       }
      }
-     mImageIds.Resize( 0 );
+     mTextCache.Resize( 0 );
    }
  
    void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
                             const Vector4& underlineColor,
                             const Vector4& textColor )
    {
 -    MeshData newMeshData;
 +    AtlasManager::Mesh2D newMesh;
 +    unsigned short faceIndex = 0;
      for ( Vector< Extent >::ConstIterator eIt = extents.Begin(); eIt != extents.End(); ++eIt )
      {
 -      MeshData::VertexContainer newVerts;
 -      newVerts.reserve( 4u );
 +      AtlasManager::Vertex2D vert;
        uint32_t index = eIt->mMeshRecordIndex;
        Vector2 uv = mGlyphManager.GetAtlasSize( meshRecords[ index ].mAtlasId );
  
        float tlx = eIt->mLeft;
        float brx = eIt->mRight;
  
 -      newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine, ZERO ),
 -                                            Vector2::ZERO,
 -                                            Vector3::ZERO ) );
 -
 -      newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine, ZERO ),
 -                                            Vector2( u, ZERO ),
 -                                            Vector3::ZERO ) );
 -
 -      newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine + thickness, ZERO ),
 -                                            Vector2( ZERO, v ),
 -                                            Vector3::ZERO ) );
 -
 -      newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine + thickness, ZERO ),
 -                                            Vector2( u, v ),
 -                                            Vector3::ZERO ) );
 -
 -      newMeshData.SetVertices( newVerts );
 -      newMeshData.SetFaceIndices( mFace );
 +      vert.mPosition.x = tlx;
 +      vert.mPosition.y = baseLine;
 +      vert.mTexCoords.x = ZERO;
 +      vert.mTexCoords.y = ZERO;
 +      newMesh.mVertices.PushBack( vert );
 +
 +      vert.mPosition.x = brx;
 +      vert.mPosition.y = baseLine;
 +      vert.mTexCoords.x = u;
 +      newMesh.mVertices.PushBack( vert );
 +
 +      vert.mPosition.x = tlx;
 +      vert.mPosition.y = baseLine + thickness;
 +      vert.mTexCoords.x = ZERO;
 +      vert.mTexCoords.y = v;
 +      newMesh.mVertices.PushBack( vert );
 +
 +      vert.mPosition.x = brx;
 +      vert.mPosition.y = baseLine + thickness;
 +      vert.mTexCoords.x = u;
 +      newMesh.mVertices.PushBack( vert );
 +
 +      // Six indices in counter clockwise winding
 +      newMesh.mIndices.PushBack( faceIndex + 1u );
 +      newMesh.mIndices.PushBack( faceIndex );
 +      newMesh.mIndices.PushBack( faceIndex + 2u );
 +      newMesh.mIndices.PushBack( faceIndex + 2u );
 +      newMesh.mIndices.PushBack( faceIndex + 3u );
 +      newMesh.mIndices.PushBack( faceIndex + 1u );
 +      faceIndex += 4;
  
        if ( underlineColor == textColor )
        {
 -        mGlyphManager.StitchMesh( meshRecords[ index ].mMeshData, newMeshData );
 +        mGlyphManager.StitchMesh( meshRecords[ index ].mMesh, newMesh );
        }
        else
        {
          MeshRecord record;
 -        newMeshData.SetMaterial( meshRecords[ index ].mMeshData.GetMaterial() );
 -        newMeshData.SetHasNormals( true );
 -        newMeshData.SetHasColor( false );
 -        newMeshData.SetHasTextureCoords( true );
 -        record.mMeshData = newMeshData;
 +        record.mMesh = newMesh;
          record.mAtlasId = meshRecords[ index ].mAtlasId;
          record.mColor = underlineColor;
          record.mIsUnderline = true;
      }
    }
  
 -  MeshActor GenerateShadow( MeshRecord& meshRecord,
 -                            const Vector2& shadowOffset,
 -                            const Vector4& shadowColor )
 +  Actor GenerateShadow( MeshRecord& meshRecord,
 +                        const Vector2& shadowOffset,
 +                        const Vector4& shadowColor )
    {
      // Scan vertex buffer to determine width and height of effect buffer needed
 -    MeshData::VertexContainer verts = meshRecord.mMeshData.GetVertices();
 -    float tlx = verts[ 0 ].x;
 -    float tly = verts[ 0 ].y;
 +    const Vector< AtlasManager::Vertex2D >& verts = meshRecord.mMesh.mVertices;
 +    float tlx = verts[ 0 ].mPosition.x;
 +    float tly = verts[ 0 ].mPosition.y;
      float brx = ZERO;
      float bry = ZERO;
  
 -    for ( uint32_t i = 0; i < verts.size(); ++i )
 +    for ( uint32_t i = 0; i < verts.Size(); ++i )
      {
 -      if ( verts[ i ].x < tlx )
 +      if ( verts[ i ].mPosition.x < tlx )
        {
 -        tlx = verts[ i ].x;
 +        tlx = verts[ i ].mPosition.x;
        }
 -      if ( verts[ i ].y < tly )
 +      if ( verts[ i ].mPosition.y < tly )
        {
 -        tly = verts[ i ].y;
 +        tly = verts[ i ].mPosition.y;
        }
 -      if ( verts[ i ].x > brx )
 +      if ( verts[ i ].mPosition.x > brx )
        {
 -        brx = verts[ i ].x;
 +        brx = verts[ i ].mPosition.x;
        }
 -      if ( verts[ i ].y > bry )
 +      if ( verts[ i ].mPosition.y > bry )
        {
 -        bry = verts[ i ].y;
 +        bry = verts[ i ].mPosition.y;
        }
      }
  
      // Create a buffer to render to
      meshRecord.mBuffer = FrameBufferImage::New( width, height );
  
 -    // Create a mesh actor to contain the post-effect render
 -    MeshData::VertexContainer vertices;
 -    MeshData::FaceIndices face;
 -
 -    vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, tly + shadowOffset.y, ZERO ),
 -                                          Vector2::ZERO,
 -                                          Vector3::ZERO ) );
 -
 -    vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, tly + shadowOffset.y, ZERO ),
 -                                          Vector2( ONE, ZERO ),
 -                                          Vector3::ZERO ) );
 -
 -    vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, bry + shadowOffset.y, ZERO ),
 -                                          Vector2( ZERO, ONE ),
 -                                          Vector3::ZERO ) );
 -
 -    vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, bry + shadowOffset.y, ZERO ),
 -                                          Vector2::ONE,
 -                                          Vector3::ZERO ) );
 -
 -    MeshData meshData;
 -    Material newMaterial = Material::New("effect buffer");
 -    newMaterial.SetDiffuseTexture( meshRecord.mBuffer );
 -    meshData.SetMaterial( newMaterial );
 -    meshData.SetVertices( vertices );
 -    meshData.SetFaceIndices( mFace );
 -    meshData.SetHasNormals( true );
 -    meshData.SetHasColor( false );
 -    meshData.SetHasTextureCoords( true );
 -    MeshActor actor = MeshActor::New( Mesh::New( meshData ) );
 -    actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
 -    actor.SetShaderEffect( mBgraShader );
 -    actor.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
 -    actor.SetSortModifier( 0.1f ); // force behind main text
 -
 -    // Create a sub actor to render once with normalized vertex positions
 -    MeshData newMeshData;
 -    MeshData::VertexContainer newVerts;
 -    MeshData::FaceIndices newFaces;
 -    MeshData::FaceIndices faces = meshRecord.mMeshData.GetFaces();
 -    for ( uint32_t i = 0; i < verts.size(); ++i )
 -    {
 -      MeshData::Vertex vertex = verts[ i ];
 -      vertex.x = ( ( vertex.x - tlx ) * divWidth ) - ONE;
 -      vertex.y = ( ( vertex.y - tly ) * divHeight ) - ONE;
 -      newVerts.push_back( vertex );
 -    }
 +    // We will render a quad into this buffer
 +    unsigned int indices[ 6 ] = { 1, 0, 2, 2, 3, 1 };
 +    PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, 4u );
 +    PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, sizeof(indices)/sizeof(indices[0]) );
 +
 +    AtlasManager::Vertex2D vertices[ 4 ] = {
 +    { Vector2( tlx + shadowOffset.x, tly + shadowOffset.y ), Vector2( ZERO, ZERO ) },
 +    { Vector2( brx + shadowOffset.x, tly + shadowOffset.y ), Vector2( ONE, ZERO ) },
 +    { Vector2( tlx + shadowOffset.x, bry + shadowOffset.y ), Vector2( ZERO, ONE ) },
 +    { Vector2( brx + shadowOffset.x, bry + shadowOffset.y ), Vector2( ONE, ONE ) } };
 +
 +    quadVertices.SetData( vertices );
 +    quadIndices.SetData( indices );
 +
 +    Geometry quadGeometry = Geometry::New();
 +    quadGeometry.AddVertexBuffer( quadVertices );
 +    quadGeometry.SetIndexBuffer( quadIndices );
 +
 +    Sampler sampler = Sampler::New( meshRecord.mBuffer, "sTexture" );
 +    Material material = Material::New( mGlyphManager.GetEffectBufferShader() );
 +    material.AddSampler( sampler );
  
 -    // Reverse triangle winding order
 -    uint32_t faceCount = faces.size() / 3;
 -    for ( uint32_t i = 0; i < faceCount; ++i )
 +    Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
 +
 +    // Ensure shadow is behind the text...
 +    renderer.SetDepthIndex( mDepth + CONTENT_DEPTH_INDEX - 1 );
 +    Actor actor = Actor::New();
 +    actor.AddRenderer( renderer );
 +    actor.SetSize( 1.0f, 1.0f );
 +
 +    // Create a sub actor to render the source with normalized vertex positions
 +    Vector< AtlasManager::Vertex2D > normVertexList;
 +    for ( uint32_t i = 0; i < verts.Size(); ++i )
      {
 -      uint32_t index = i * 3;
 -      newFaces.push_back( faces[ index + 2 ] );
 -      newFaces.push_back( faces[ index + 1 ] );
 -      newFaces.push_back( faces[ index ] );
 +      AtlasManager::Vertex2D vertex = verts[ i ];
 +      vertex.mPosition.x = ( ( vertex.mPosition.x - tlx ) * divWidth ) - ONE;
 +      vertex.mPosition.y = ( ( vertex.mPosition.y - tly ) * divHeight ) - ONE;
 +      normVertexList.PushBack( vertex );
      }
  
 -    newMeshData.SetMaterial( meshRecord.mMeshData.GetMaterial() );
 -    newMeshData.SetVertices( newVerts );
 -    newMeshData.SetFaceIndices( newFaces );
 -    newMeshData.SetHasNormals( true );
 -    newMeshData.SetHasColor( false );
 -    newMeshData.SetHasTextureCoords( true );
 -
 -    MeshActor subActor = MeshActor::New( Mesh::New( newMeshData ) );
 +    PropertyBuffer normVertices = PropertyBuffer::New( mQuadVertexFormat, normVertexList.Size() );
 +    PropertyBuffer normIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
 +    normVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &normVertexList[ 0 ] ) );
 +    normIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
 +
 +    Geometry normGeometry = Geometry::New();
 +    normGeometry.AddVertexBuffer( normVertices );
 +    normGeometry.SetIndexBuffer( normIndices );
 +
 +    Material normMaterial = Material::New( mGlyphManager.GetGlyphShadowShader() );
 +    Sampler normSampler =  mGlyphManager.GetSampler( meshRecord.mAtlasId );
 +    normMaterial.AddSampler( normSampler );
 +    Dali::Renderer normRenderer = Dali::Renderer::New( normGeometry, normMaterial );
 +    Actor subActor = Actor::New();
 +    subActor.AddRenderer( normRenderer );
 +    subActor.SetSize( 1.0f, 1.0f );
      subActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
      subActor.SetColor( shadowColor );
 -    subActor.SetShaderEffect( mBasicShadowShader );
 -    subActor.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
  
      // Create a render task to render the effect
      RenderTask task = Stage::GetCurrent().GetRenderTaskList().CreateTask();
      task.SetRefreshRate( RenderTask::REFRESH_ONCE );
      task.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete );
      actor.Add( subActor );
 +
      return actor;
    }
  
      }
    }
  
 -  RenderableActor mActor;                             ///< The actor parent which renders the text
 +  Actor mActor;                                       ///< The actor parent which renders the text
    AtlasGlyphManager mGlyphManager;                    ///< Glyph Manager to handle upload and caching
-   Vector< uint32_t > mImageIds;                       ///< A list of imageIDs used by the renderer
    TextAbstraction::FontClient mFontClient;            ///> The font client used to supply glyph information
 -  ShaderEffect mBasicShader;                          ///> Shader used to render L8 glyphs
 -  ShaderEffect mBgraShader;                           ///> Shader used to render BGRA glyphs
 -  ShaderEffect mBasicShadowShader;                    ///> Shader used to render drop shadow into buffer
    std::vector< MaxBlockSize > mBlockSizes;            ///> Maximum size needed to contain a glyph in a block within a new atlas
 -  std::vector< MeshData::FaceIndex > mFace;           ///> Face indices for a quad
 +  std::vector< uint32_t > mFace;                      ///> Face indices for a quad
+   Vector< TextCacheEntry > mTextCache;
 +  Property::Map mQuadVertexFormat;
 +  Property::Map mQuadIndexFormat;
 +  int mDepth;
  };
  
  Text::RendererPtr AtlasRenderer::New()
    return Text::RendererPtr( new AtlasRenderer() );
  }
  
 -RenderableActor AtlasRenderer::Render( Text::ViewInterface& view )
 +Actor AtlasRenderer::Render( Text::ViewInterface& view, unsigned int depth )
  {
    UnparentAndReset( mImpl->mActor );
  
                        view.GetShadowColor(),
                        view.IsUnderlineEnabled(),
                        view.GetUnderlineColor(),
 -                      view.GetUnderlineHeight() );
 +                      view.GetUnderlineHeight(),
 +                      depth );
    }
  
    return mImpl->mActor;
@@@ -737,5 -773,7 +774,7 @@@ AtlasRenderer::AtlasRenderer(
  
  AtlasRenderer::~AtlasRenderer()
  {
+   Vector< GlyphInfo > emptyGlyphs;
+   mImpl->RemoveText( emptyGlyphs );
    delete mImpl;
  }
  #include <limits>
  #include <stack>
  #include <dali/public-api/actors/image-actor.h>
 -#include <dali/devel-api/actors/mesh-actor.h>
  #include <dali/public-api/animation/constraint.h>
  #include <dali/public-api/animation/constraints.h>
 -#include <dali/devel-api/geometry/mesh.h>
  #include <dali/public-api/object/type-registry.h>
 +#include <dali/public-api/size-negotiation/relayout-container.h>
  #include <dali/devel-api/object/type-registry-helper.h>
 +#include <dali/devel-api/rendering/renderer.h>
  #include <dali/devel-api/scripting/scripting.h>
 -#include <dali/public-api/size-negotiation/relayout-container.h>
  #include <dali/integration-api/debug.h>
  
  // INTERNAL INCLUDES
 +#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
  #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
  #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
  #include <dali-toolkit/public-api/controls/control.h>
@@@ -167,7 -167,7 +167,7 @@@ DALI_TYPE_REGISTRATION_END(
   */
  struct Background
  {
 -  Actor actor;   ///< Either a MeshActor or an ImageActor
 +  Actor actor;   ///< Background actor
    Vector4 color; ///< The color of the actor.
  
    /**
    }
  };
  
 -/**
 - * Creates a white coloured Mesh.
 - */
 -Mesh CreateMesh()
 -{
 -  Vector3 white( Color::WHITE );
 -
 -  MeshData meshData;
 +unsigned int gQuadIndex[6] = { 0, 2, 1, 1, 2, 3 };
  
 -  // Create vertices with a white color (actual color is set by actor color)
 -  MeshData::VertexContainer vertices(4);
 -  vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
 -  vertices[ 1 ] = MeshData::Vertex( Vector3(  0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
 -  vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
 -  vertices[ 3 ] = MeshData::Vertex( Vector3(  0.5f,  0.5f, 0.0f ), Vector2::ZERO, white );
 +Vector2 gQuad[] = {
 +                   Vector2( -0.5f, -0.5f ),
 +                   Vector2(  0.5f, -0.5f ),
 +                   Vector2( -0.5f,  0.5f ),
 +                   Vector2(  0.5f,  0.5f )
 +};
  
 -  // Specify all the faces
 -  MeshData::FaceIndices faces;
 -  faces.reserve( 6 ); // 2 triangles in Quad
 -  faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 );
 -  faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 );
 +struct VertexWithTexture
 +{
 +  Vector2 position;
 +  Vector2 texCoord;
 +};
  
 -  // Create the mesh data from the vertices and faces
 -  meshData.SetMaterial( Material::New( "ControlMaterial" ) );
 -  meshData.SetVertices( vertices );
 -  meshData.SetFaceIndices( faces );
 -  meshData.SetHasColor( true );
 +VertexWithTexture gQuadWithTexture[] = {
 +                                        { Vector2( -0.5f, -0.5f ), Vector2( 0.0f, 0.0f ) },
 +                                        { Vector2(  0.5f, -0.5f ), Vector2( 1.0f, 0.0f ) },
 +                                        { Vector2( -0.5f,  0.5f ), Vector2( 0.0f, 1.0f ) },
 +                                        { Vector2(  0.5f,  0.5f ), Vector2( 1.0f, 1.0f ) }
 +};
  
 -  return Mesh::New( meshData );
 -}
 +const char* VERTEX_SHADER_COLOR = DALI_COMPOSE_SHADER(
 +    attribute mediump vec2 aPosition;\n
 +    uniform mediump mat4 uMvpMatrix;\n
 +    void main()\n
 +    {\n
 +      gl_Position = uMvpMatrix * vec4( aPosition, 0.0, 1.0 );\n
 +    }\n
 +);
 +
 +const char* FRAGMENT_SHADER_COLOR = DALI_COMPOSE_SHADER(
 +    uniform lowp vec4 uBackgroundColor;\n
 +    uniform lowp vec4 uColor;\n
 +    void main()\n
 +    {\n
 +      gl_FragColor = uBackgroundColor * uColor;\n
 +    }\n
 +);
 +
 +const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
 +    attribute mediump vec2 aPosition;\n
 +    attribute mediump vec2 aTexCoord;\n
 +    uniform mediump mat4 uMvpMatrix;\n
 +    varying mediump vec2 vTexCoord;\n
 +    void main()\n
 +    {\n
 +      gl_Position = uMvpMatrix * vec4( aPosition, 0.0, 1.0 );\n
 +      vTexCoord = aTexCoord;\n
 +    }\n
 +);
 +
 +const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
 +    uniform lowp vec4 uBackgroundColor;\n
 +    uniform lowp vec4 uColor;\n
 +    uniform sampler2D sTexture;\n
 +    varying mediump vec2 vTexCoord;\n
 +
 +    void main()\n
 +    {\n
 +      gl_FragColor = texture2D( sTexture, vTexCoord ) * uBackgroundColor * uColor;\n
 +    }\n
 +);
  
  /**
 - * Sets all the required properties for the background actor.
 + * @brief Create the background actor for the control.
   *
 - * @param[in]  actor              The actor to set the properties on.
 - * @param[in]  color              The required color of the actor.
 - */
 -void SetupBackgroundActor( Actor actor, const Vector4& color )
 -{
 -  actor.SetColor( color );
 -  actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
 -  actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
 -  actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
 -}
 -
 -/**
 - * Sets all the required properties for the background actor.
 + * @param[in] actor The parent actor of the background
 + * @param[in] color The background color
 + * @param[in] image If a valid image is supplied this will be the texture used by the background
 + *
 + * @return An actor which will render the background
   *
 - * @param[in]  actor              The actor to set the properties on.
 - * @param[in]  constrainingIndex  The property index to constrain the parent's size on.
 - * @param[in]  color              The required color of the actor.
   */
 -void SetupBackgroundActorConstrained( Actor actor, Property::Index constrainingIndex, const Vector4& color )
 +Actor CreateBackground( Actor parent, const Vector4& color, Image image = Image() )
  {
 -  actor.SetColor( color );
 -  actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
 -  actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
 +  PropertyBuffer vertexBuffer;
 +  Shader shader;
 +  Material material;
 +  if( image )
 +  {
 +    Property::Map vertexFormat;
 +    vertexFormat["aPosition"] = Property::VECTOR2;
 +    vertexFormat["aTexCoord"] = Property::VECTOR2;
 +
 +    //Create a vertex buffer for vertex positions and texture coordinates
 +    vertexBuffer = PropertyBuffer::New( vertexFormat, 4u );
 +    vertexBuffer.SetData( gQuadWithTexture );
 +
 +    shader = Shader::New( VERTEX_SHADER_TEXTURE, FRAGMENT_SHADER_TEXTURE );
 +    Sampler textureSampler = Sampler::New( image, "sTexture" );
 +    material = Material::New( shader );
 +    material.AddSampler(textureSampler);
 +  }
 +  else
 +  {
 +    Property::Map vertexFormat;
 +    vertexFormat["aPosition"] = Property::VECTOR2;
 +
 +    //Create a vertex buffer for vertex positions
 +    vertexBuffer = PropertyBuffer::New( vertexFormat, 4u );
 +    vertexBuffer.SetData( gQuad );
 +
 +    shader = Shader::New( VERTEX_SHADER_COLOR, FRAGMENT_SHADER_COLOR );
 +    material = Material::New( shader );
 +  }
  
 -  Constraint constraint = Constraint::New<Vector3>( actor,
 -                                                    constrainingIndex,
 +  //Create the index buffer
 +  Property::Map indexFormat;
 +  indexFormat["indices"] = Property::UNSIGNED_INTEGER;
 +  PropertyBuffer indexBuffer = PropertyBuffer::New( indexFormat, 6u );
 +  indexBuffer.SetData(gQuadIndex);
 +
 +  //Create the geometry
 +  Geometry mesh = Geometry::New();
 +  mesh.AddVertexBuffer( vertexBuffer );
 +  mesh.SetIndexBuffer( indexBuffer );
 +
 +  //Add uniforms to the shader
 +  shader.RegisterProperty( "uBackgroundColor", color );
 +
 +  //Create the renderer
 +  Renderer renderer = Renderer::New( mesh, material );
 +  renderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
 +
 +  //Create the actor
 +  Actor meshActor = Actor::New();
 +  meshActor.SetSize( Vector3::ONE );
 +  meshActor.AddRenderer( renderer );
 +  meshActor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
 +  meshActor.SetColorMode( USE_PARENT_COLOR );
 +
 +  //Constraint scale of the mesh actor to the size of the control
 +  Constraint constraint = Constraint::New<Vector3>( meshActor,
 +                                                    Actor::Property::SCALE,
                                                      EqualToConstraint() );
    constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
    constraint.Apply();
 +
 +  return meshActor;
  }
  
  } // unnamed namespace
@@@ -333,21 -256,21 +333,21 @@@ public
  
    // Construction & Destruction
    Impl(Control& controlImpl)
 -  : mControlImpl( controlImpl ),
 -    mStyleName(""),
 -    mBackground( NULL ),
 -    mStartingPinchScale( NULL ),
 -    mKeyEventSignal(),
 -    mPinchGestureDetector(),
 -    mPanGestureDetector(),
 -    mTapGestureDetector(),
 -    mLongPressGestureDetector(),
 -    mFlags( Control::ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
 -    mIsKeyboardNavigationSupported( false ),
 -    mIsKeyboardFocusGroup( false ),
 -    mAddRemoveBackgroundChild( false )
 -  {
 -  }
 +: mControlImpl( controlImpl ),
 +  mStyleName(""),
 +  mBackground( NULL ),
 +  mStartingPinchScale( NULL ),
 +  mKeyEventSignal(),
 +  mPinchGestureDetector(),
 +  mPanGestureDetector(),
 +  mTapGestureDetector(),
 +  mLongPressGestureDetector(),
 +  mFlags( Control::ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
 +  mIsKeyboardNavigationSupported( false ),
 +  mIsKeyboardFocusGroup( false ),
 +  mAddRemoveBackgroundChild( false )
 +{
 +}
  
    ~Impl()
    {
  
          case Toolkit::Control::Property::BACKGROUND_IMAGE:
          {
-           if ( value.HasKey( "image" ) )
+           Image image = Scripting::NewImage( value );
+           if ( image )
            {
-             Property::Map imageMap = value.GetValue( "image" ).Get< Property::Map >();
-             Image image = Scripting::NewImage( imageMap );
-             if ( image )
-             {
-               controlImpl.SetBackgroundImage( image );
-             }
+             controlImpl.SetBackgroundImage( image );
            }
-           else if ( value.Get< Property::Map >().Empty() )
+           else
            {
              // An empty map means the background is no longer required
              controlImpl.ClearBackground();
            Property::Map map;
  
            Background* back = controlImpl.mImpl->mBackground;
 -          if( back )
 +          if ( back && back->actor && back->actor.GetRendererAt(0).GetMaterial().GetNumberOfSamplers() > 0)
            {
 -            ImageActor imageActor = ImageActor::DownCast( back->actor );
 -            if ( imageActor )
 +            Image image = back->actor.GetRendererAt(0).GetMaterial().GetSamplerAt(0).GetImage();
 +            if ( image )
              {
-               Property::Map imageMap;
-               Scripting::CreatePropertyMap( image, imageMap );
-               map[ "image" ] = imageMap;
 -              Image image = imageActor.GetImage();
+               Scripting::CreatePropertyMap( image, map );
              }
            }
  
@@@ -597,17 -514,21 +590,17 @@@ void Control::SetBackgroundColor( cons
  
    if ( background.actor )
    {
 -    // Just set the actor color
 -    background.actor.SetColor( color );
 +    Shader shader = background.actor.GetRendererAt(0).GetMaterial().GetShader();
 +    shader.SetProperty( shader.GetPropertyIndex("uBackgroundColor"), color );
    }
    else
    {
      // Create Mesh Actor
 -    MeshActor meshActor = MeshActor::New( CreateMesh() );
 -
 -    SetupBackgroundActorConstrained( meshActor, Actor::Property::SCALE, color );
 -
 -    background.actor = meshActor;
 -    // Set the flag to avoid notifying children
 +    Actor actor = CreateBackground(Self(), color );
 +    background.actor = actor;
      mImpl->mAddRemoveBackgroundChild = true;
      // use insert to guarantee its the first child (so that OVERLAY mode works)
 -    Self().Insert( 0, meshActor );
 +    Self().Insert( 0, actor );
      mImpl->mAddRemoveBackgroundChild = false;
    }
  
@@@ -626,31 -547,25 +619,31 @@@ Vector4 Control::GetBackgroundColor() c
  void Control::SetBackgroundImage( Image image )
  {
    Background& background( mImpl->GetBackground() );
 -
 -  if ( background.actor )
 +  if( !background.actor || background.actor.GetRendererAt(0).GetMaterial().GetNumberOfSamplers() == 0)
    {
 -    // Remove Current actor, unset AFTER removal
 +    // Remove current actor as it has not texture coordinates
 +    if( background.actor )
 +    {
 +      mImpl->mAddRemoveBackgroundChild = true;
 +      Self().Remove( background.actor );
 +      mImpl->mAddRemoveBackgroundChild = false;
 +      background.actor.Reset();
 +    }
 +
 +    //Create a new actor with texture coordinates
 +    Actor actor = CreateBackground(Self(), background.color, image);
      mImpl->mAddRemoveBackgroundChild = true;
 -    Self().Remove( background.actor );
 +    // use insert to guarantee its the first child (so that OVERLAY mode works)
 +    Self().Insert( 0, actor );
      mImpl->mAddRemoveBackgroundChild = false;
 -    background.actor.Reset();
 +    background.actor = actor;
 +  }
 +  else
 +  {
 +    //Change sampler image
 +    Sampler sampler =  background.actor.GetRendererAt(0).GetMaterial().GetSamplerAt(0);
 +    sampler.SetImage(image);
    }
 -
 -  ImageActor imageActor = ImageActor::New( image );
 -  SetupBackgroundActor( imageActor, background.color );
 -
 -  // Set the background actor before adding so that we do not inform derived classes
 -  background.actor = imageActor;
 -  mImpl->mAddRemoveBackgroundChild = true;
 -  // use insert to guarantee its the first child (so that OVERLAY mode works)
 -  Self().Insert( 0, imageActor );
 -  mImpl->mAddRemoveBackgroundChild = false;
  }
  
  void Control::ClearBackground()
@@@ -875,6 -790,9 +868,9 @@@ Control::Control( ControlBehaviour beha
  
  void Control::Initialize()
  {
+   // Call deriving classes so initialised before styling is applied to them.
+   OnInitialize();
    if( mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS )
    {
      Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
      // Register for style changes
      styleManager.StyleChangeSignal().Connect( this, &Control::OnStyleChange );
  
-     // SetTheme
+     // Apply the current style
      GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
    }
  
    {
      SetKeyboardNavigationSupport( true );
    }
-   // Calling deriving classes
-   OnInitialize();
  }
  
  void Control::OnInitialize()
@@@ -950,11 -865,11 +943,11 @@@ void Control::EmitKeyInputFocusSignal( 
  
    if ( focusGained )
    {
 -     // signals are allocated dynamically when someone connects
 -     if ( !mImpl->mKeyInputFocusGainedSignal.Empty() )
 -     {
 +    // signals are allocated dynamically when someone connects
 +    if ( !mImpl->mKeyInputFocusGainedSignal.Empty() )
 +    {
        mImpl->mKeyInputFocusGainedSignal.Emit( handle );
 -     }
 +    }
    }
    else
    {
    }
  }
  
 -void Control::OnStageConnection()
 +void Control::OnStageConnection( unsigned int depth )
  {
 +  unsigned int controlRendererCount = Self().GetRendererCount();
 +  for( unsigned int i(0); i<controlRendererCount; ++i )
 +  {
 +    Renderer controlRenderer = Self().GetRendererAt(i);
 +    if( controlRenderer )
 +    {
 +      controlRenderer.SetDepthIndex( CONTENT_DEPTH_INDEX+depth );
 +    }
 +  }
 +
 +  if( mImpl->mBackground )
 +  {
 +    Renderer backgroundRenderer = mImpl->mBackground->actor.GetRendererAt( 0 );
 +    if(backgroundRenderer)
 +    {
 +      backgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth );
 +    }
 +  }
  }
  
  void Control::OnStageDisconnection()
@@@ -1070,23 -967,15 +1063,23 @@@ void Control::OnSetResizePolicy( Resize
  
  Vector3 Control::GetNaturalSize()
  {
 +  //Control's natural size is the size of its background image if it has been set, or ZERO otherwise
 +  Vector3 naturalSize = Vector3::ZERO;
    if( mImpl->mBackground )
    {
 -    Actor actor = mImpl->mBackground->actor;
 -    if( actor )
 +    Material backgroundMaterial = mImpl->mBackground->actor.GetRendererAt(0).GetMaterial();
 +    if( backgroundMaterial.GetNumberOfSamplers() > 0 )
      {
 -      return actor.GetNaturalSize();
 +      Image backgroundImage =  backgroundMaterial.GetSamplerAt(0).GetImage();
 +      if( backgroundImage )
 +      {
 +        naturalSize.x = backgroundImage.GetWidth();
 +        naturalSize.y = backgroundImage.GetHeight();
 +      }
      }
    }
 -  return Vector3();
 +
 +  return naturalSize;
  }
  
  float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
@@@ -270,7 -270,7 +270,7 @@@ protected: // From CustomActorImpl, no
    /**
     * @copydoc CustomActorImpl::OnStageConnection()
     */
 -  virtual void OnStageConnection();
 +  virtual void OnStageConnection( unsigned int depth );
  
    /**
     * @copydoc CustomActorImpl::OnStageDisconnection()
@@@ -597,7 -597,7 +597,7 @@@ private
   * @param handle
   * @return implementation
   */
- Internal::Control& GetImplementation( Dali::Toolkit::Control& handle );
DALI_IMPORT_API Internal::Control& GetImplementation( Dali::Toolkit::Control& handle );
  
  /**
   * @brief Get implementation from the handle
   * @param handle
   * @return implementation
   */
- const Internal::Control& GetImplementation( const Dali::Toolkit::Control& handle );
DALI_IMPORT_API const Internal::Control& GetImplementation( const Dali::Toolkit::Control& handle );
  
  } // namespace Internal