diff --git a/java/builder.go b/java/builder.go
new file mode 100644
index 0000000..2f9d701
--- /dev/null
+++ b/java/builder.go
@@ -0,0 +1,189 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+// This file generates the final rules for compiling all Java.  All properties related to
+// compiling should have been translated into javaBuilderFlags or another argument to the Transform*
+// functions.
+
+import (
+	"path/filepath"
+	"strings"
+
+	"android/soong/common"
+
+	"github.com/google/blueprint"
+	"github.com/google/blueprint/bootstrap"
+)
+
+var (
+	pctx = blueprint.NewPackageContext("android/soong/java")
+
+	// Compiling java is not conducive to proper dependency tracking.  The path-matches-class-name
+	// requirement leads to unpredictable generated source file names, and a single .java file
+	// will get compiled into multiple .class files if it contains inner classes.  To work around
+	// this, all java rules write into separate directories and then a post-processing step lists
+	// the files in the the directory into a list file that later rules depend on (and sometimes
+	// read from directly using @<listfile>)
+	cc = pctx.StaticRule("javac",
+		blueprint.RuleParams{
+			Command: `$javacCmd -encoding UTF-8 $javacFlags $bootClasspath $classpath ` +
+				`-extdirs "" -d $outDir @$out.rsp || ( rm -rf $outDir; exit 41 ) && ` +
+				`find $outDir -name "*.class" > $out`,
+			Rspfile:        "$out.rsp",
+			RspfileContent: "$in",
+			Description:    "javac $outDir",
+		},
+		"javacCmd", "javacFlags", "bootClasspath", "classpath", "outDir")
+
+	jar = pctx.StaticRule("jar",
+		blueprint.RuleParams{
+			Command:     `$jarCmd -o $out $jarArgs`,
+			Description: "jar $out",
+		},
+		"jarCmd", "jarArgs")
+
+	dx = pctx.StaticRule("dx",
+		blueprint.RuleParams{
+			Command:     "$dxCmd --dex --output=$out $dxFlags $in",
+			Description: "dex $out",
+		},
+		"outDir", "dxFlags")
+)
+
+func init() {
+	pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
+	pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
+	pctx.StaticVariable("jarCmd", filepath.Join(bootstrap.BinDir, "soong_jar"))
+	pctx.VariableFunc("dxCmd", func(c interface{}) (string, error) {
+		return c.(Config).HostBinTool("dx")
+	})
+}
+
+type javaBuilderFlags struct {
+	javacFlags    string
+	dxFlags       string
+	bootClasspath string
+	classpath     string
+}
+
+type jarSpec struct {
+	fileList, dir string
+}
+
+func (j jarSpec) soongJarArgs() string {
+	return "-C " + j.dir + " -l " + j.fileList
+}
+
+func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string,
+	flags javaBuilderFlags, deps []string) jarSpec {
+
+	classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
+	classFileList := filepath.Join(classDir, "classes.list")
+
+	ctx.Build(pctx, blueprint.BuildParams{
+		Rule:      cc,
+		Outputs:   []string{classFileList},
+		Inputs:    srcFiles,
+		Implicits: deps,
+		Args: map[string]string{
+			"javacFlags":    flags.javacFlags,
+			"bootClasspath": flags.bootClasspath,
+			"classpath":     flags.classpath,
+			"outDir":        classDir,
+		},
+	})
+
+	return jarSpec{classFileList, classDir}
+}
+
+func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
+	manifest string) string {
+
+	outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-full-debug.jar")
+
+	deps := []string{}
+	jarArgs := []string{}
+
+	for _, j := range classes {
+		deps = append(deps, j.fileList)
+		jarArgs = append(jarArgs, j.soongJarArgs())
+	}
+
+	if manifest != "" {
+		deps = append(deps, manifest)
+		jarArgs = append(jarArgs, "-m "+manifest)
+	}
+
+	deps = append(deps, "$jarCmd")
+
+	ctx.Build(pctx, blueprint.BuildParams{
+		Rule:      jar,
+		Outputs:   []string{outputFile},
+		Implicits: deps,
+		Args: map[string]string{
+			"jarArgs": strings.Join(jarArgs, " "),
+		},
+	})
+
+	return outputFile
+}
+
+func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string,
+	flags javaBuilderFlags) string {
+
+	outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes.dex")
+
+	ctx.Build(pctx, blueprint.BuildParams{
+		Rule:      dx,
+		Outputs:   []string{outputFile},
+		Inputs:    []string{classesJar},
+		Implicits: []string{"$dxCmd"},
+		Args: map[string]string{
+			"dxFlags": flags.dxFlags,
+		},
+	})
+
+	return outputFile
+}
+
+func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
+	dexFile string) string {
+
+	outputFile := filepath.Join(common.ModuleOutDir(ctx), "javalib.jar")
+	var deps []string
+	var jarArgs []string
+
+	for _, j := range resources {
+		deps = append(deps, j.fileList)
+		jarArgs = append(jarArgs, j.soongJarArgs())
+	}
+
+	dexDir, _ := filepath.Split(dexFile)
+	jarArgs = append(jarArgs, "-C "+dexDir+" -f "+dexFile)
+
+	deps = append(deps, "$jarCmd", dexFile)
+
+	ctx.Build(pctx, blueprint.BuildParams{
+		Rule:      jar,
+		Outputs:   []string{outputFile},
+		Implicits: deps,
+		Args: map[string]string{
+			"jarArgs": strings.Join(jarArgs, " "),
+		},
+	})
+
+	return outputFile
+}
diff --git a/java/java.go b/java/java.go
new file mode 100644
index 0000000..67bde04
--- /dev/null
+++ b/java/java.go
@@ -0,0 +1,403 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+// This file contains the module types for compiling Java for Android, and converts the properties
+// into the flags and filenames necessary to pass to the compiler.  The final creation of the rules
+// is handled in builder.go
+
+import (
+	"fmt"
+	"path/filepath"
+	"strings"
+
+	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
+
+	"android/soong/common"
+)
+
+type Config interface {
+	SrcDir() string
+	PrebuiltOS() string
+	HostBinTool(string) (string, error)
+	Getenv(string) string
+}
+
+// TODO:
+// Autogenerated files:
+//  AIDL
+//  Proto
+//  Renderscript
+// Post-jar passes:
+//  Proguard
+//  Emma
+//  Jarjar
+//  Dex
+// Rmtypedefs
+// Jack
+// DroidDoc
+// Findbugs
+
+// javaBase contains the properties and members used by all java module types, and implements
+// the blueprint.Module interface.
+type javaBase struct {
+	common.AndroidModuleBase
+	module JavaModuleType
+
+	properties struct {
+		// srcs: list of source files used to compile the Java module.  May be .java, .logtags, .proto,
+		// or .aidl files.
+		Srcs []string `android:"arch_variant,arch_subtract"`
+
+		// resource_dirs: list of directories containing resources
+		Resource_dirs []string `android:"arch_variant"`
+
+		// no_standard_libraries: don't build against the default libraries (core-libart, core-junit,
+		// ext, and framework for device targets)
+		No_standard_libraries bool
+
+		// javacflags: list of module-specific flags that will be used for javac compiles
+		Javacflags []string `android:"arch_variant"`
+
+		// dxflags: list of module-specific flags that will be used for dex compiles
+		Dxflags []string `android:"arch_variant"`
+
+		// java_libs: list of of java libraries that will be in the classpath
+		Java_libs []string `android:"arch_variant"`
+
+		// java_static_libs: list of java libraries that will be compiled into the resulting jar
+		Java_static_libs []string `android:"arch_variant"`
+
+		// manifest: manifest file to be included in resulting jar
+		Manifest string
+
+		// sdk_version: if not blank, set to the version of the sdk to compile against
+		Sdk_version string
+
+		// Set for device java libraries, and for host versions of device java libraries
+		// built for testing
+		Dex bool `blueprint:"mutated"`
+	}
+
+	// output file suitable for inserting into the classpath of another compile
+	classpathFile string
+
+	// jarSpecs suitable for inserting classes from a static library into another jar
+	classJarSpecs []jarSpec
+
+	// jarSpecs suitable for inserting resources from a static library into another jar
+	resourceJarSpecs []jarSpec
+
+	// installed file for binary dependency
+	installFile string
+}
+
+type JavaModuleType interface {
+	GenerateJavaBuildActions(ctx common.AndroidModuleContext)
+}
+
+type JavaDependency interface {
+	ClasspathFile() string
+	ClassJarSpecs() []jarSpec
+	ResourceJarSpecs() []jarSpec
+}
+
+func NewJavaBase(base *javaBase, module JavaModuleType, hod common.HostOrDeviceSupported,
+	props ...interface{}) (blueprint.Module, []interface{}) {
+
+	base.module = module
+
+	props = append(props, &base.properties)
+
+	return common.InitAndroidArchModule(base, hod, common.MultilibCommon, props...)
+}
+
+func (j *javaBase) BootClasspath(ctx common.AndroidBaseContext) string {
+	if ctx.Device() {
+		if j.properties.Sdk_version == "" {
+			return "core-libart"
+		} else if j.properties.Sdk_version == "current" {
+			// TODO: !TARGET_BUILD_APPS
+			return "android_stubs_current"
+		} else if j.properties.Sdk_version == "system_current" {
+			return "android_system_stubs_current"
+		} else {
+			return "sdk_v" + j.properties.Sdk_version
+		}
+	} else {
+		if j.properties.Dex {
+			return "core-libart"
+		} else {
+			return ""
+		}
+	}
+}
+
+func (j *javaBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
+	var deps []string
+
+	if !j.properties.No_standard_libraries {
+		bootClasspath := j.BootClasspath(ctx)
+		if bootClasspath != "" {
+			deps = append(deps, bootClasspath)
+		}
+	}
+	deps = append(deps, j.properties.Java_libs...)
+	deps = append(deps, j.properties.Java_static_libs...)
+
+	return deps
+}
+
+func (j *javaBase) collectDeps(ctx common.AndroidModuleContext) (classpath []string,
+	bootClasspath string, classJarSpecs, resourceJarSpecs []jarSpec) {
+
+	ctx.VisitDirectDeps(func(module blueprint.Module) {
+		otherName := ctx.OtherModuleName(module)
+		if javaDep, ok := module.(JavaDependency); ok {
+			if inList(otherName, j.properties.Java_libs) {
+				classpath = append(classpath, javaDep.ClasspathFile())
+			} else if inList(otherName, j.properties.Java_static_libs) {
+				classpath = append(classpath, javaDep.ClasspathFile())
+				classJarSpecs = append(classJarSpecs, javaDep.ClassJarSpecs()...)
+				resourceJarSpecs = append(resourceJarSpecs, javaDep.ResourceJarSpecs()...)
+			} else if otherName == j.BootClasspath(ctx) {
+				bootClasspath = javaDep.ClasspathFile()
+			} else {
+				panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
+			}
+		} else {
+			ctx.ModuleErrorf("unknown dependency module type for %q", otherName)
+		}
+	})
+
+	return classpath, bootClasspath, classJarSpecs, resourceJarSpecs
+}
+
+func (j *javaBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
+	j.module.GenerateJavaBuildActions(ctx)
+}
+
+func (j *javaBase) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
+	flags := javaBuilderFlags{
+		javacFlags: strings.Join(j.properties.Javacflags, " "),
+	}
+
+	var javacDeps []string
+
+	srcFiles := j.properties.Srcs
+	srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
+	srcFiles = common.ExpandGlobs(ctx, srcFiles)
+
+	classpath, bootClasspath, classJarSpecs, resourceJarSpecs := j.collectDeps(ctx)
+
+	if bootClasspath != "" {
+		flags.bootClasspath = "-bootclasspath " + bootClasspath
+		javacDeps = append(javacDeps, bootClasspath)
+	}
+
+	if len(classpath) > 0 {
+		flags.classpath = "-classpath " + strings.Join(classpath, ":")
+		javacDeps = append(javacDeps, classpath...)
+	}
+
+	// Compile java sources into .class files
+	classes := TransformJavaToClasses(ctx, srcFiles, flags, javacDeps)
+	if ctx.Failed() {
+		return
+	}
+
+	resourceJarSpecs = append(ResourceDirsToJarSpecs(ctx, j.properties.Resource_dirs), resourceJarSpecs...)
+	classJarSpecs = append([]jarSpec{classes}, classJarSpecs...)
+
+	manifest := j.properties.Manifest
+	if manifest != "" {
+		manifest = filepath.Join(common.ModuleSrcDir(ctx), manifest)
+	}
+
+	allJarSpecs := append([]jarSpec(nil), classJarSpecs...)
+	allJarSpecs = append(allJarSpecs, resourceJarSpecs...)
+
+	// Combine classes + resources into classes-full-debug.jar
+	outputFile := TransformClassesToJar(ctx, allJarSpecs, manifest)
+	if ctx.Failed() {
+		return
+	}
+	j.classJarSpecs = classJarSpecs
+	j.resourceJarSpecs = resourceJarSpecs
+	j.classpathFile = outputFile
+
+	if j.properties.Dex {
+		dxFlags := j.properties.Dxflags
+		if false /* emma enabled */ {
+			// If you instrument class files that have local variable debug information in
+			// them emma does not correctly maintain the local variable table.
+			// This will cause an error when you try to convert the class files for Android.
+			// The workaround here is to build different dex file here based on emma switch
+			// then later copy into classes.dex. When emma is on, dx is run with --no-locals
+			// option to remove local variable information
+			dxFlags = append(dxFlags, "--no-locals")
+		}
+
+		if ctx.Config().(Config).Getenv("NO_OPTIMIZE_DX") != "" {
+			dxFlags = append(dxFlags, "--no-optimize")
+		}
+
+		if ctx.Config().(Config).Getenv("GENERATE_DEX_DEBUG") != "" {
+			dxFlags = append(dxFlags,
+				"--debug",
+				"--verbose",
+				"--dump-to="+filepath.Join(common.ModuleOutDir(ctx), "classes.lst"),
+				"--dump-width=1000")
+		}
+
+		flags.dxFlags = strings.Join(dxFlags, " ")
+
+		// Compile classes.jar into classes.dex
+		dexFile := TransformClassesJarToDex(ctx, outputFile, flags)
+		if ctx.Failed() {
+			return
+		}
+
+		// Combine classes.dex + resources into javalib.jar
+		outputFile = TransformDexToJavaLib(ctx, resourceJarSpecs, dexFile)
+	}
+
+	j.installFile = ctx.InstallFileName("framework", ctx.ModuleName()+".jar", outputFile)
+}
+
+var _ JavaDependency = (*JavaLibrary)(nil)
+
+func (j *javaBase) ClasspathFile() string {
+	return j.classpathFile
+}
+
+func (j *javaBase) ClassJarSpecs() []jarSpec {
+	return j.classJarSpecs
+}
+
+func (j *javaBase) ResourceJarSpecs() []jarSpec {
+	return j.resourceJarSpecs
+}
+
+//
+// Java libraries (.jar file)
+//
+
+type JavaLibrary struct {
+	javaBase
+}
+
+func JavaLibraryFactory() (blueprint.Module, []interface{}) {
+	module := &JavaLibrary{}
+
+	module.properties.Dex = true
+
+	return NewJavaBase(&module.javaBase, module, common.HostAndDeviceSupported)
+}
+
+func JavaLibraryHostFactory() (blueprint.Module, []interface{}) {
+	module := &JavaLibrary{}
+
+	return NewJavaBase(&module.javaBase, module, common.HostSupported)
+}
+
+//
+// Java Binaries (.jar file plus wrapper script)
+//
+
+type JavaBinary struct {
+	JavaLibrary
+
+	binaryProperties struct {
+		// wrapper: installable script to execute the resulting jar
+		Wrapper string
+	}
+}
+
+func (j *JavaBinary) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
+	j.JavaLibrary.GenerateJavaBuildActions(ctx)
+
+	// Depend on the installed jar (j.installFile) so that the wrapper doesn't get executed by
+	// another build rule before the jar has been installed.
+	ctx.InstallFile("bin", filepath.Join(common.ModuleSrcDir(ctx), j.binaryProperties.Wrapper),
+		j.installFile)
+}
+
+func JavaBinaryFactory() (blueprint.Module, []interface{}) {
+	module := &JavaBinary{}
+
+	module.properties.Dex = true
+
+	return NewJavaBase(&module.javaBase, module, common.HostAndDeviceSupported, &module.binaryProperties)
+}
+
+func JavaBinaryHostFactory() (blueprint.Module, []interface{}) {
+	module := &JavaBinary{}
+
+	return NewJavaBase(&module.javaBase, module, common.HostSupported, &module.binaryProperties)
+}
+
+//
+// Java prebuilts
+//
+
+type JavaPrebuilt struct {
+	common.AndroidModuleBase
+
+	properties struct {
+		Srcs []string
+	}
+
+	classpathFile string
+}
+
+func (j *JavaPrebuilt) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
+	if len(j.properties.Srcs) != 1 {
+		ctx.ModuleErrorf("expected exactly one jar in srcs")
+		return
+	}
+	j.classpathFile = filepath.Join(common.ModuleSrcDir(ctx), j.properties.Srcs[0])
+}
+
+var _ JavaDependency = (*JavaPrebuilt)(nil)
+
+func (j *JavaPrebuilt) ClasspathFile() string {
+	return j.classpathFile
+}
+
+func (j *JavaPrebuilt) ClassJarSpecs() []jarSpec {
+	return nil
+}
+
+func (j *JavaPrebuilt) ResourceJarSpecs() []jarSpec {
+	return nil
+}
+
+func JavaPrebuiltFactory() (blueprint.Module, []interface{}) {
+	module := &JavaPrebuilt{}
+
+	return common.InitAndroidArchModule(module, common.HostAndDeviceSupported,
+		common.MultilibCommon, &module.properties)
+}
+
+func inList(s string, l []string) bool {
+	for _, e := range l {
+		if e == s {
+			return true
+		}
+	}
+	return false
+}
diff --git a/java/resources.go b/java/resources.go
new file mode 100644
index 0000000..2fbf54b
--- /dev/null
+++ b/java/resources.go
@@ -0,0 +1,45 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+	"path/filepath"
+
+	"android/soong/common"
+)
+
+var resourceExcludes = []string{
+	"*.java",
+	"package.html",
+	"overview.html",
+	".*.swp",
+	".DS_Store",
+	"*~",
+}
+
+func ResourceDirsToJarSpecs(ctx common.AndroidModuleContext, dirs []string) []jarSpec {
+	jarSpecs := make([]jarSpec, len(dirs))
+
+	for i, dir := range dirs {
+		fileListFile := filepath.Join(common.ModuleOutDir(ctx), "res", dir, "resources.list")
+		depFile := fileListFile + ".d"
+		dir := filepath.Join(common.ModuleSrcDir(ctx), dir)
+		glob := filepath.Join(dir, "**/*")
+		common.GlobRule(ctx, glob, resourceExcludes, fileListFile, depFile)
+		jarSpecs[i] = jarSpec{fileListFile, dir}
+	}
+
+	return jarSpecs
+}
