diff --git a/.gitignore b/.gitignore
index 123ae94..e526281 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,9 @@ build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
+
+# Compiled output
+built/
+
+# Typescript typings
+typings/
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..07fe76f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,99 @@
+## Intro
+
+This repository is an example Angular2 application, with a focus on showing how
+unit tests can be written and run.
+
+For a full-service starter application, try [angular-cli](https://github.com/angular/angular-cli).
+
+## Software Prerequisites
+
+In order to run this seed, the following software is required
+
+### Git
+
+See [Setting Up Git](https://help.github.com/articles/set-up-git/) from the GitHub guides.
+
+### Node.js and npm
+
+Node.js and Node's package manager, npm, are used for installing dependencies,
+running the build steps, and running tests.
+
+
+## Getting Started
+
+Begin by cloning the repository.
+
+Use npm to get dependencies:
+
+`npm install`
+
+Take a look at the `src` folder. All application and test code, as well as
+some configuration files, are in here. The `app` folder contains the actual
+application code, written in TypeScript, as well as associated template and
+css files. The `test` folder contains unit tests.
+
+## The Build/Test Pipeline
+
+To be as minimal as possible, this repo uses npm scripts for all building
+and testing steps. You can see exactly what the scripts do in `package.json`. A
+more complex application would probably consider using a tool such as grunt
+or gulp to manage development pipelines.
+
+### Build
+
+The build step invokes the TypeScript compiler to create ES5 javascript
+files and source maps from the `.ts` files. Run with:
+
+`npm run build`
+
+You can examine the configuration for the TypeScript compiler in `tsconfig.json`.
+The generated files are output in the `built/` folder.
+
+To remove all generated files, run:
+
+`npm run clean`.
+
+### Watch
+
+The watch step can be run with:
+
+`npm run watch`
+
+This runs the TypeScript compiler with the additional `--watch` flag, which
+sets up a persistent process that recompiles new `.js` files whenever a `.ts`
+file changes.
+
+Run this process indefinitely in a different tab or in the background, since
+the following commands will use it.
+
+### Serve
+
+To see the app, run
+
+`npm run serve`
+
+and navigate to `localhost:9090/built/index.html`.
+
+### Test
+
+We use Karma with the Jasmine test framework to run unit tests. Try them with
+
+`npm run test`
+
+This will start a persistent process which will re-run tests whenever the `.js`
+compiled files are changed. If you have the watch process running, that will
+trigger the tests to run whenever you change the `.ts` source files.
+
+You can see the Karma configuration at `karma.conf.js`. A few things are notable:
+
+ - It grabs Angular by including the `angular2` and `testing.js` files from
+ `node_modules/angular2/bundles/`.
+
+ - The compiled JavaScript files at `src/**/*.js` are served and watched but _not_ included.
+ This means that Karma will not run them automatically.
+
+ - To get file imports to work correctly in Karma, we must include `systemjs`
+ from the node_modules folder, as well as the helper file `karma-test-shim.js`.
+ This shim file uses System.js to load the JavaScript files which Karma served
+ but did not automatically run.
+
\ No newline at end of file
diff --git a/karma-test-shim.js b/karma-test-shim.js
new file mode 100644
index 0000000..ac4c94c
--- /dev/null
+++ b/karma-test-shim.js
@@ -0,0 +1,67 @@
+// Tun on full stack traces in errors to help debugging
+Error.stackTraceLimit = Infinity;
+
+
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
+
+// // Cancel Karma's synchronous start,
+// // we will call `__karma__.start()` later, once all the specs are loaded.
+__karma__.loaded = function() {};
+
+
+System.config({
+ packages: {
+ 'base/built/app': {
+ defaultExtension: false,
+ format: 'register',
+ map: Object.keys(window.__karma__.files).
+ filter(onlyAppFiles).
+ reduce(function createPathRecords(pathsMapping, appPath) {
+ // creates local module name mapping to global path with karma's fingerprint in path, e.g.:
+ // './hero.service': '/base/src/app/hero.service.js?f4523daf879cfb7310ef6242682ccf10b2041b3e'
+ var moduleName = appPath.replace(/^\/base\/built\/app\//, './').replace(/\.js$/, '');
+ pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath];
+ return pathsMapping;
+ }, {})
+
+ }
+ }
+});
+
+System.import('angular2/testing').then(function(testing) {
+ return System.import('angular2/platform/testing/browser').then(function(providers) {
+ testing.setBaseTestProviders(providers.TEST_BROWSER_PLATFORM_PROVIDERS,
+ providers.TEST_BROWSER_APPLICATION_PROVIDERS);
+ });
+}).then(function() {
+ return Promise.all(
+ Object.keys(window.__karma__.files) // All files served by Karma.
+ .filter(onlySpecFiles)
+ // .map(filePath2moduleName) // Normalize paths to module names.
+ .map(function(moduleName) {
+ // loads all spec files via their global module names (e.g. 'base/src/app/hero.service.spec')
+ return System.import(moduleName);
+ }));
+})
+.then(function() {
+ __karma__.start();
+}, function(error) {
+ __karma__.error(error.stack || error);
+});
+
+
+function filePath2moduleName(filePath) {
+ return filePath.
+ replace(/^\//, ''). // remove / prefix
+ replace(/\.\w+$/, ''); // remove suffix
+}
+
+
+function onlyAppFiles(filePath) {
+ return /^\/base\/built\/app\/.*\.js$/.test(filePath)
+}
+
+
+function onlySpecFiles(path) {
+ return /_test\.js$/.test(path);
+}
diff --git a/karma.conf.js b/karma.conf.js
new file mode 100644
index 0000000..53b8e02
--- /dev/null
+++ b/karma.conf.js
@@ -0,0 +1,62 @@
+module.exports = function(config) {
+ config.set({
+
+ basePath: '',
+
+ frameworks: ['jasmine'],
+
+ files: [
+ // System.js for module loading
+ 'node_modules/systemjs/dist/system-polyfills.js',
+ 'node_modules/systemjs/dist/system.src.js',
+
+ // Polyfills.
+ 'node_modules/es6-shim/es6-shim.js',
+ 'node_modules/angular2/bundles/angular2-polyfills.js',
+
+ // Zone.js dependencies
+ // Note - do not include zone.js itself here, it is already
+ // included in angular2-polyfills
+ 'node_modules/zone.js/dist/jasmine-patch.js',
+ 'node_modules/zone.js/dist/async-test.js',
+ 'node_modules/zone.js/dist/fake-async-test.js',
+
+ // RxJs.
+ 'node_modules/rxjs/bundles/Rx.js',
+
+ // Angular 2 itself and the testing library.
+ 'node_modules/angular2/bundles/angular2.js',
+ 'node_modules/angular2/bundles/testing.dev.js',
+
+
+ {pattern: 'karma-test-shim.js', included: true, watched: true},
+ {pattern: 'built/test/matchers.js', included: true, watched: true},
+
+ // paths loaded via module imports
+ {pattern: 'built/**/*.js', included: false, watched: true},
+
+ // paths loaded via Angular's component compiler
+ // (these paths need to be rewritten, see proxies section)
+ {pattern: 'built/**/*.html', included: false, watched: true},
+ {pattern: 'built/**/*.css', included: false, watched: true},
+
+ // paths to support debugging with source maps in dev tools
+ {pattern: 'src/**/*.ts', included: false, watched: false},
+ {pattern: 'built/**/*.js.map', included: false, watched: false}
+ ],
+
+ // proxied base paths
+ proxies: {
+ // required for component assests fetched by Angular's compiler
+ "/app/": "/base/built/app/"
+ },
+
+ reporters: ['progress'],
+ port: 9876,
+ colors: true,
+ logLevel: config.LOG_INFO,
+ autoWatch: true,
+ browsers: ['Chrome'],
+ singleRun: false
+ })
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..1c042ba
--- /dev/null
+++ b/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "ng2-test-seed",
+ "version": "0.0.2",
+ "description": "Setup seed for Angular 2 application",
+ "license": "Apache-2.0",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/angular/ng-test-seed.git"
+ },
+ "scripts": {
+ "postinstall": "typings install --ambient",
+ "clean": "rimraf built/",
+ "copy": "cp src/{index.html,styles.css} built/",
+ "copytemplates": "cp src/app/{*.html,*.css} built/app/",
+ "build": "tsc && npm run copy && npm run copytemplates",
+ "watch": "tsc --watch",
+ "serve": "http-server -p 9090 -c-1",
+ "test": "karma start karma.conf.js"
+ },
+ "dependencies": {
+ "angular2": "2.0.0-beta.16",
+ "clang-format": "^1.0.35",
+ "es6-promise": "^3.0.2",
+ "es6-shim": "^0.35.0",
+ "reflect-metadata": "0.1.2",
+ "rxjs": "5.0.0-beta.2",
+ "systemjs": "0.19.20",
+ "zone.js": "0.6.12"
+ },
+ "devDependencies": {
+ "http-server": "^0.8.5",
+ "jasmine": "2.3.2",
+ "karma": "^0.13.22",
+ "karma-chrome-launcher": "^0.2.1",
+ "karma-cli": "^0.0.4",
+ "karma-jasmine": "^0.3.6",
+ "rimraf": "^2.4.3",
+ "systemjs": "^0.19.4",
+ "typescript": "1.8.10",
+ "typings": "^0.6.6"
+ }
+}
diff --git a/src/app/app-component.ts b/src/app/app-component.ts
new file mode 100644
index 0000000..fecf2d9
--- /dev/null
+++ b/src/app/app-component.ts
@@ -0,0 +1,17 @@
+import {Component} from 'angular2/core';
+import {GreetingComponent} from './greeting-component';
+import {BorderComponent} from './border-component';
+import {FormComponent} from './form-component';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+
+
+
+ `,
+ directives: [GreetingComponent, BorderComponent, FormComponent]
+})
+export class AppComponent {
+}
diff --git a/src/app/bootstrap.ts b/src/app/bootstrap.ts
new file mode 100644
index 0000000..35ab866
--- /dev/null
+++ b/src/app/bootstrap.ts
@@ -0,0 +1,7 @@
+import {bootstrap} from 'angular2/platform/browser';
+import {UserService} from './user-service';
+import {AppComponent} from './app-component';
+import {LoginService} from './login-service';
+
+
+bootstrap(AppComponent, [LoginService, UserService]);
diff --git a/src/app/border-component.css b/src/app/border-component.css
new file mode 100644
index 0000000..5d8aa41
--- /dev/null
+++ b/src/app/border-component.css
@@ -0,0 +1,4 @@
+div {border: 5px solid #EDF3F3; border-radius: 1em; text-align: center}
+span {font-size: 10px;display: inline-block}
+.inner {padding: 5px; margin: 5px}
+.outer {width: 400px}
diff --git a/src/app/border-component.html b/src/app/border-component.html
new file mode 100644
index 0000000..0dce192
--- /dev/null
+++ b/src/app/border-component.html
@@ -0,0 +1,7 @@
+