Create Script.java and use it internally in ClientFunction.java
diff --git a/bundles/org.eclipse.rap.clientscripting.demo/ClientScripting Demo.launch b/bundles/org.eclipse.rap.clientscripting.demo/ClientScripting Demo.launch
index bb802c8..e5a7b87 100644
--- a/bundles/org.eclipse.rap.clientscripting.demo/ClientScripting Demo.launch
+++ b/bundles/org.eclipse.rap.clientscripting.demo/ClientScripting Demo.launch
@@ -1,44 +1,44 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.rap.ui.launch.RAPLauncher">
-<booleanAttribute key="append.args" value="true"/>
-<booleanAttribute key="askclear" value="false"/>
-<booleanAttribute key="automaticAdd" value="false"/>
-<booleanAttribute key="automaticValidate" value="true"/>
-<stringAttribute key="bootstrap" value=""/>
-<stringAttribute key="checked" value="[NONE]"/>
-<booleanAttribute key="clearConfig" value="false"/>
-<booleanAttribute key="clearws" value="false"/>
-<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/ClientScripting Demo"/>
-<booleanAttribute key="default" value="true"/>
-<booleanAttribute key="default_auto_start" value="true"/>
-<intAttribute key="default_start_level" value="4"/>
-<booleanAttribute key="includeOptional" value="false"/>
-<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console"/>
-<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dorg.eclipse.equinox.http.jetty.log.stderr.threshold=info"/>
-<stringAttribute key="org.eclipse.rap.launch.browserMode" value="INTERNAL"/>
-<stringAttribute key="org.eclipse.rap.launch.contextpath" value=""/>
-<stringAttribute key="org.eclipse.rap.launch.dataLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.rap.tools.launch/ClientScriptingDemo"/>
-<booleanAttribute key="org.eclipse.rap.launch.developmentMode" value="true"/>
-<stringAttribute key="org.eclipse.rap.launch.entryPoint" value=""/>
-<stringAttribute key="org.eclipse.rap.launch.libraryVariant" value="DEBUG"/>
-<stringAttribute key="org.eclipse.rap.launch.logLevel" value="OFF"/>
-<booleanAttribute key="org.eclipse.rap.launch.openBrowser" value="false"/>
-<intAttribute key="org.eclipse.rap.launch.port" value="9096"/>
-<stringAttribute key="org.eclipse.rap.launch.servletName" value="clientscripting"/>
-<stringAttribute key="org.eclipse.rap.launch.servletPath" value="/scripting"/>
-<intAttribute key="org.eclipse.rap.launch.sessionTimeout" value="0"/>
-<booleanAttribute key="org.eclipse.rap.launch.terminatePrevious" value="true"/>
-<booleanAttribute key="org.eclipse.rap.launch.useDefaultDataLocation" value="true"/>
-<booleanAttribute key="org.eclipse.rap.launch.useManualContextPath" value="false"/>
-<booleanAttribute key="org.eclipse.rap.launch.useManualPort" value="true"/>
-<booleanAttribute key="org.eclipse.rap.launch.useSessionTimeout" value="false"/>
-<stringAttribute key="pde.version" value="3.3"/>
-<booleanAttribute key="show_selected_only" value="true"/>
-<stringAttribute key="target_bundles" value="javax.servlet@default:default,javax.xml@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.eclipse.equinox.console@default:default,org.eclipse.equinox.http.jetty@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true"/>
-<booleanAttribute key="tracing" value="false"/>
-<booleanAttribute key="useCustomFeatures" value="false"/>
-<booleanAttribute key="useDefaultConfigArea" value="true"/>
-<stringAttribute key="workspace_bundles" value="org.eclipse.rap.clientscripting.demo@default:default,org.eclipse.rap.clientscripting@default:default,org.eclipse.rap.rwt.osgi@default:default,org.eclipse.rap.rwt@default:default"/>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<launchConfiguration type="org.eclipse.rap.ui.launch.RAPLauncher">

+<booleanAttribute key="append.args" value="true"/>

+<booleanAttribute key="askclear" value="false"/>

+<booleanAttribute key="automaticAdd" value="false"/>

+<booleanAttribute key="automaticValidate" value="false"/>

+<stringAttribute key="bootstrap" value=""/>

+<stringAttribute key="checked" value="[NONE]"/>

+<booleanAttribute key="clearConfig" value="false"/>

+<booleanAttribute key="clearws" value="false"/>

+<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/ClientScripting Demo"/>

+<booleanAttribute key="default" value="true"/>

+<booleanAttribute key="default_auto_start" value="true"/>

+<intAttribute key="default_start_level" value="4"/>

+<booleanAttribute key="includeOptional" value="false"/>

+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>

+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console"/>

+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>

+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dorg.eclipse.equinox.http.jetty.log.stderr.threshold=info"/>

+<stringAttribute key="org.eclipse.rap.launch.browserMode" value="INTERNAL"/>

+<stringAttribute key="org.eclipse.rap.launch.contextpath" value=""/>

+<stringAttribute key="org.eclipse.rap.launch.dataLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.rap.tools.launch/ClientScriptingDemo"/>

+<booleanAttribute key="org.eclipse.rap.launch.developmentMode" value="true"/>

+<stringAttribute key="org.eclipse.rap.launch.entryPoint" value=""/>

+<stringAttribute key="org.eclipse.rap.launch.libraryVariant" value="DEBUG"/>

+<stringAttribute key="org.eclipse.rap.launch.logLevel" value="OFF"/>

+<booleanAttribute key="org.eclipse.rap.launch.openBrowser" value="false"/>

+<intAttribute key="org.eclipse.rap.launch.port" value="9096"/>

+<stringAttribute key="org.eclipse.rap.launch.servletName" value="clientscripting"/>

+<stringAttribute key="org.eclipse.rap.launch.servletPath" value="/scripting"/>

+<intAttribute key="org.eclipse.rap.launch.sessionTimeout" value="0"/>

+<booleanAttribute key="org.eclipse.rap.launch.terminatePrevious" value="true"/>

+<booleanAttribute key="org.eclipse.rap.launch.useDefaultDataLocation" value="true"/>

+<booleanAttribute key="org.eclipse.rap.launch.useManualContextPath" value="false"/>

+<booleanAttribute key="org.eclipse.rap.launch.useManualPort" value="true"/>

+<booleanAttribute key="org.eclipse.rap.launch.useSessionTimeout" value="false"/>

+<stringAttribute key="pde.version" value="3.3"/>

+<booleanAttribute key="show_selected_only" value="false"/>

+<stringAttribute key="target_bundles" value="javax.servlet@default:default,javax.xml@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.eclipse.equinox.console@default:default,org.eclipse.equinox.http.jetty@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.rap.rwt.osgi@default:default"/>

+<booleanAttribute key="tracing" value="false"/>

+<booleanAttribute key="useCustomFeatures" value="false"/>

+<booleanAttribute key="useDefaultConfigArea" value="true"/>

+<stringAttribute key="workspace_bundles" value="org.eclipse.rap.clientscripting.demo@default:default,org.eclipse.rap.clientscripting@default:default,org.eclipse.rap.rwt@default:default"/>

+</launchConfiguration>

diff --git a/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/Script.java b/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/Script.java
new file mode 100644
index 0000000..26eecef
--- /dev/null
+++ b/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/Script.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2013 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    EclipseSource - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.clientscripting;
+
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.remote.Connection;
+import org.eclipse.rap.rwt.remote.RemoteObject;
+
+
+public class Script {
+
+  private static final String REMOTE_TYPE = "rwt.clientscripting.Script";
+  private RemoteObject remoteObject;
+
+  public Script( String text ) {
+    if( text == null ) {
+      throw new NullPointerException( "Text must not be null" );
+    }
+    Connection connection = RWT.getUISession().getConnection();
+    remoteObject = connection.createRemoteObject( REMOTE_TYPE );
+    remoteObject.set( "text", text );
+  }
+
+  public String getId() {
+    return remoteObject.getId();
+  }
+
+  public void dispose() {
+    remoteObject.destroy();
+  }
+
+}
diff --git a/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/ClientFunction.java b/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/ClientFunction.java
index 45fc332..95e1d11 100644
--- a/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/ClientFunction.java
+++ b/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/ClientFunction.java
@@ -13,6 +13,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 
+import org.eclipse.rap.clientscripting.Script;
 import org.eclipse.rap.clientscripting.internal.resources.ClientScriptingResources;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.rap.rwt.remote.RemoteObject;
@@ -24,6 +25,7 @@
 
   private final RemoteObject remoteObject;
   private final Collection<ClientListenerBinding> bindings;
+  private final Script script;
 
   public ClientFunction( String scriptCode ) {
     if( scriptCode == null ) {
@@ -31,8 +33,9 @@
     }
     ClientScriptingResources.ensure();
     bindings = new ArrayList<ClientListenerBinding>();
+    script = new Script( scriptCode );
     remoteObject = RWT.getUISession().getConnection().createRemoteObject( REMOTE_TYPE );
-    remoteObject.set( "code", scriptCode );
+    remoteObject.set( "script", script.getId() );
   }
 
   protected String getRemoteId() {
diff --git a/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/resources/ClientScriptingResources.java b/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/resources/ClientScriptingResources.java
index 55c5872..4238945 100644
--- a/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/resources/ClientScriptingResources.java
+++ b/bundles/org.eclipse.rap.clientscripting/src/org/eclipse/rap/clientscripting/internal/resources/ClientScriptingResources.java
@@ -33,7 +33,8 @@
     "Function.js",
     "ListenerAdapter.js",
     "SWT.js",
-    "WidgetProxy.js"
+    "WidgetProxy.js",
+    "ScriptHandler.js"
   };
 
   public static void ensure() {
diff --git a/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/Script_Test.java b/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/Script_Test.java
new file mode 100644
index 0000000..325300e
--- /dev/null
+++ b/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/Script_Test.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    EclipseSource - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.clientscripting;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.eclipse.rap.rwt.remote.Connection;
+import org.eclipse.rap.rwt.remote.RemoteObject;
+import org.eclipse.rap.rwt.testfixture.Fixture;
+import org.junit.*;
+
+
+public class Script_Test {
+
+  private static final String REMOTE_TYPE = "rwt.clientscripting.Script";
+  private Connection connection;
+  private RemoteObject remoteObject;
+
+  @Before
+  public void setUp() throws Exception {
+    Fixture.setUp();
+    connection = mock( Connection.class );
+    remoteObject = mock( RemoteObject.class );
+    when( remoteObject.getId() ).thenReturn( "foo" );
+    when( connection.createRemoteObject( REMOTE_TYPE ) ).thenReturn( remoteObject );
+    Fixture.fakeConnection( connection );
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    Fixture.tearDown();
+  }
+
+  @Test( expected = NullPointerException.class )
+  public void testConstructor_nullArgumenFails() {
+    new Script( null );
+  }
+
+  @Test
+  public void testConstructor_createsRemoteObject() {
+    new Script( "1+1;" );
+
+    verify( connection ).createRemoteObject( eq( REMOTE_TYPE ) );
+  }
+
+  @Test
+  public void testConstructor_setsTextOnRemoteObject() {
+    new Script( "1+1;" );
+
+    verify( remoteObject ).set( eq( "text" ), eq( "1+1;" ) );
+  }
+
+  @Test
+  public void testGetId() {
+    Script script = new Script( "1+1;" );
+
+    assertEquals( "foo", script.getId() );
+  }
+
+  @Test
+  public void testDispose_callsDestroyOnRemoteObject() {
+    Script script = new Script( "1+1;" );
+
+    script.dispose();
+
+    verify( remoteObject ).destroy();
+  }
+
+}
diff --git a/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/ClientFunction_Test.java b/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/ClientFunction_Test.java
index afd334c..f54ca6e 100644
--- a/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/ClientFunction_Test.java
+++ b/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/ClientFunction_Test.java
@@ -21,6 +21,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import org.eclipse.rap.rwt.remote.Connection;
 import org.eclipse.rap.rwt.remote.RemoteObject;
@@ -32,6 +33,7 @@
 
   private static final String CLIENT_LISTENER_TYPE =  "rwt.clientscripting.Listener";
   private static final String LISTENER_BINDING_TYPE =  "rwt.clientscripting.EventBinding";
+  private static final String SCRIPT_TYPE = "rwt.clientscripting.Script";
 
   private ClientFunction function;
 
@@ -67,12 +69,18 @@
 
   @Test
   public void testCreation_initializesRemoteObject() {
-    RemoteObject remoteObject = mock( RemoteObject.class );
-    fakeConnection( remoteObject, CLIENT_LISTENER_TYPE );
+    RemoteObject listenerRemoteObject = mock( RemoteObject.class );
+    RemoteObject scriptRemoteObject = mock( RemoteObject.class );
+    Connection connection = mock( Connection.class );
+    when( connection.createRemoteObject( eq( CLIENT_LISTENER_TYPE ) ) )
+      .thenReturn( listenerRemoteObject );
+    when( connection.createRemoteObject( eq( SCRIPT_TYPE ) ) ).thenReturn( scriptRemoteObject );
+    when( scriptRemoteObject.getId() ).thenReturn( "fooId" );
+    Fixture.fakeConnection( connection );
 
     new ClientFunction( "script code" );
 
-    verify( remoteObject ).set( eq( "code" ), eq( "script code" ) );
+    verify( listenerRemoteObject ).set( eq( "script" ), eq( "fooId" ) );
   }
 
 
diff --git a/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/TestUtil.java b/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/TestUtil.java
index 507af28..9477e21 100644
--- a/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/TestUtil.java
+++ b/tests/org.eclipse.rap.clientscripting.test/src/org/eclipse/rap/clientscripting/internal/TestUtil.java
@@ -10,7 +10,7 @@
  ******************************************************************************/
 package org.eclipse.rap.clientscripting.internal;
 
-import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -20,13 +20,30 @@
 import org.eclipse.rap.rwt.remote.RemoteObject;
 import org.eclipse.rap.rwt.testfixture.Fixture;
 import org.eclipse.swt.widgets.Widget;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 
 public class TestUtil {
 
-  public static Connection fakeConnection( RemoteObject remoteObject, String remoteType ) {
+  public static Connection fakeConnection(
+    final RemoteObject remoteObject,
+    final String remoteType
+  ) {
     Connection connection = mock( Connection.class );
-    when( connection.createRemoteObject( eq( remoteType ) ) ).thenReturn( remoteObject );
+    when( connection.createRemoteObject( anyString()) ).thenAnswer( new Answer<RemoteObject>() {
+
+      public RemoteObject answer( InvocationOnMock invocation ) throws Throwable {
+        String type = ( String )invocation.getArguments()[ 0 ];
+        RemoteObject result;
+        if( remoteType.equals( type ) ) {
+          result = remoteObject;
+        } else {
+          result = mock( RemoteObject.class );
+        }
+        return result;
+      }
+    } );
     Fixture.fakeConnection( connection );
     return connection;
   }