merge in mnc-release history after reset to mnc-dev
diff --git a/.gitignore b/.gitignore
index 5b1b439..448ab8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 local.properties
 .gradle
 maven-repo
+.caches
diff --git a/baseLibrary/build.gradle b/baseLibrary/build.gradle
index 3b383ca..241e4a8 100644
--- a/baseLibrary/build.gradle
+++ b/baseLibrary/build.gradle
@@ -16,22 +16,10 @@
 
 apply plugin: 'java'
 apply plugin: 'application'
-apply plugin: 'com.android.databinding.bintray'
 
 sourceCompatibility = config.javaTargetCompatibility
 targetCompatibility = config.javaSourceCompatibility
 
-buildscript {
-    repositories {
-        mavenLocal()
-        mavenCentral()
-    }
-}
-
-repositories {
-    mavenCentral()
-}
-
 sourceSets {
     main {
         java {
@@ -46,7 +34,7 @@
 }
 
 dependencies {
-    testCompile 'junit:junit:4.11'
+    testCompile 'junit:junit:4.12'
 }
 
 def javadocTask = project.tasks.create(name: "javadocBaseLibrary", type: Javadoc) {
diff --git a/baseLibrary/src/main/java/android/databinding/Bindable.java b/baseLibrary/src/main/java/android/databinding/Bindable.java
index 3dcebdd..45436d6 100644
--- a/baseLibrary/src/main/java/android/databinding/Bindable.java
+++ b/baseLibrary/src/main/java/android/databinding/Bindable.java
@@ -15,11 +15,20 @@
  */
 package android.databinding;
 
+import android.databinding.Observable.OnPropertyChangedCallback;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * The Bindable annotation should be applied to any getter accessor method of an
+ * {@link Observable} class. Bindable will generate a field in the BR class to identify
+ * the field that has changed.
+ *
+ * @see OnPropertyChangedCallback#onPropertyChanged(Observable, int)
+ */
 @Target({ElementType.FIELD, ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME) // this is necessary for java analyzer to work
 public @interface Bindable {
diff --git a/baseLibrary/src/main/java/android/databinding/BindingAdapter.java b/baseLibrary/src/main/java/android/databinding/BindingAdapter.java
index 8e88377..09bc482 100644
--- a/baseLibrary/src/main/java/android/databinding/BindingAdapter.java
+++ b/baseLibrary/src/main/java/android/databinding/BindingAdapter.java
@@ -18,7 +18,58 @@
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Target;
 
+/**
+ * BindingAdapter is applied to methods that are used to manipulate how values with expressions
+ * are set to views. The simplest example is to have a public static method that takes the view
+ * and the value to set:
+ * <p><pre>
+ *<code>@BindingAdapter("android:bufferType")
+ * public static void setBufferType(TextView view, TextView.BufferType bufferType) {
+ *     view.setText(view.getText(), bufferType);
+ * }</code></pre>
+ * In the above example, when android:bufferType is used on a TextView, the method
+ * setBufferType is called.
+ * <p>
+ * It is also possible to take previously set values, if the old values are listed first:
+ * <p><pre>
+ *<code>@BindingAdapter("android:onLayoutChange")
+ * public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue,
+ *                                              View.OnLayoutChangeListener newValue) {
+ *     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ *         if (oldValue != null) {
+ *             view.removeOnLayoutChangeListener(oldValue);
+ *         }
+ *         if (newValue != null) {
+ *             view.addOnLayoutChangeListener(newValue);
+ *         }
+ *     }
+ * }</code></pre>
+ * When a binding adapter may also take multiple attributes, it will only be called when all
+ * attributes associated with the binding adapter have binding expressions associated with them.
+ * This is useful when there are unusual interactions between attributes. For example:
+ * <p><pre>
+ *<code>@BindingAdapter({"android:onClick", "android:clickable"})
+ * public static void setOnClick(View view, View.OnClickListener clickListener,
+ *                               boolean clickable) {
+ *     view.setOnClickListener(clickListener);
+ *     view.setClickable(clickable);
+ * }</code></pre>
+ * The order of the parameters must match the order of the attributes in values in the
+ * BindingAdapter.
+ * <p>
+ * A binding adapter may optionally take a class extending DataBindingComponent as the first
+ * parameter as well. If it does, it will be passed the value passed in during binding, either
+ * directly in the inflate method or indirectly, using the value from
+ * {@link DataBindingUtil#getDefaultComponent()}.
+ * <p>
+ * If a binding adapter is an instance method, the generated DataBindingComponent will have
+ * a getter to retrieve an instance of the BindingAdapter's class to use to call the method.
+ */
 @Target(ElementType.METHOD)
 public @interface BindingAdapter {
+
+    /**
+     * @return The attributes associated with this binding adapter.
+     */
     String[] value();
 }
diff --git a/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java b/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java
index 5b0c0b4..a67c97b 100644
--- a/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java
+++ b/baseLibrary/src/main/java/android/databinding/BindingBuildInfo.java
@@ -20,6 +20,9 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * @hide
+ */
 @Target({ElementType.TYPE})
 @Retention(RetentionPolicy.SOURCE)
 public @interface BindingBuildInfo {
diff --git a/baseLibrary/src/main/java/android/databinding/BindingConversion.java b/baseLibrary/src/main/java/android/databinding/BindingConversion.java
index 9942f5c..053ab39 100644
--- a/baseLibrary/src/main/java/android/databinding/BindingConversion.java
+++ b/baseLibrary/src/main/java/android/databinding/BindingConversion.java
@@ -19,6 +19,12 @@
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Target;
 
+/**
+ * Annotate methods that are used to automatically convert from the expression type to the value
+ * used in the setter. The converter should take one parameter, the expression type, and the
+ * return value should be the target value type used in the setter. Converters are used
+ * whenever they can be applied and are not specific to any attribute.
+ */
 @Target({ElementType.METHOD})
 public @interface BindingConversion {
 }
diff --git a/baseLibrary/src/main/java/android/databinding/BindingMethod.java b/baseLibrary/src/main/java/android/databinding/BindingMethod.java
index c10d4af..3585c0c 100644
--- a/baseLibrary/src/main/java/android/databinding/BindingMethod.java
+++ b/baseLibrary/src/main/java/android/databinding/BindingMethod.java
@@ -15,8 +15,26 @@
  */
 package android.databinding;
 
+/**
+ * Used within an {@link BindingMethods} annotation to describe a renaming of an attribute to
+ * the setter used to set that attribute. By default, an attribute attr will be associated with
+ * setter setAttr.
+ */
 public @interface BindingMethod {
+
+    /**
+     * @return the View Class that the attribute is associated with.
+     */
     Class type();
+
+    /**
+     * @return The attribute to rename. Use android: namespace for all android attributes or
+     * no namespace for application attributes.
+     */
     String attribute();
+
+    /**
+     * @return The method to call to set the attribute value.
+     */
     String method();
 }
diff --git a/baseLibrary/src/main/java/android/databinding/BindingMethods.java b/baseLibrary/src/main/java/android/databinding/BindingMethods.java
index a3d39f8..552b1ba 100644
--- a/baseLibrary/src/main/java/android/databinding/BindingMethods.java
+++ b/baseLibrary/src/main/java/android/databinding/BindingMethods.java
@@ -18,6 +18,11 @@
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Target;
 
+/**
+ * Used to enumerate attribute-to-setter renaming. By default, an attribute is associated with
+ * setAttribute setter. If there is a simple rename, enumerate them in an array of
+ * {@link BindingMethod} annotations in the value.
+ */
 @Target({ElementType.TYPE})
 public @interface BindingMethods {
     BindingMethod[] value();
diff --git a/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java b/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java
index 002692f..0cd7b43 100644
--- a/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java
+++ b/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java
@@ -19,7 +19,7 @@
 import java.util.List;
 
 /**
- * Tracks callbacks for the event. This class supports reentrant modification
+ * A utility for storing and notifying callbacks. This class supports reentrant modification
  * of the callbacks during notification without adversely disrupting notifications.
  * A common pattern for callbacks is to receive a notification and then remove
  * themselves. This class handles this behavior with constant memory under
@@ -27,11 +27,13 @@
  *
  * <p>A subclass of {@link CallbackRegistry.NotifierCallback} must be passed to
  * the constructor to define how notifications should be called. That implementation
- * does the actual notification on the listener.</p>
+ * does the actual notification on the listener. It is typically a static instance
+ * that can be reused for all similar CallbackRegistries.</p>
  *
- * <p>This class supports only callbacks with at most two parameters.
- * Typically, these are the notification originator and a parameter, but these may
- * be used as required. If more than two parameters are required or primitive types
+ * <p>This class supports only callbacks with at most three parameters.
+ * Typically, these are the notification originator and a parameter, with another to
+ * indicate which method to call, but these may be used as required. If more than
+ * three parameters are required or primitive types other than the single int provided
  * must be used, <code>A</code> should be some kind of containing structure that
  * the subclass may reuse between notifications.</p>
  *
@@ -78,11 +80,11 @@
      * Notify all callbacks.
      *
      * @param sender The originator. This is an opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg2 An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      */
     public synchronized void notifyCallbacks(T sender, int arg, A arg2) {
         mNotificationLevel++;
@@ -109,11 +111,11 @@
      * Notify up to the first Long.SIZE callbacks that don't have a bit set in <code>removed</code>.
      *
      * @param sender The originator. This is an opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg2 An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      */
     private void notifyFirst64(T sender, int arg, A arg2) {
         final int maxNotified = Math.min(Long.SIZE, mCallbacks.size());
@@ -128,11 +130,11 @@
      * <p>Recursion is used to avoid allocating temporary state on the heap.</p>
      *
      * @param sender The originator. This is an opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg2 An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      */
     private void notifyRecurse(T sender, int arg, A arg2) {
         final int callbackCount = mCallbacks.size();
@@ -155,11 +157,11 @@
      * remainderIndex is -1, the first 64 will be notified instead.
      *
      * @param sender The originator. This is an opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg2 An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param remainderIndex The index into mRemainderRemoved that should be notified.
      */
     private void notifyRemainder(T sender, int arg, A arg2, int remainderIndex) {
@@ -181,11 +183,11 @@
      * endIndex should be notified.
      *
      * @param sender The originator. This is an opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param arg2 An opaque parameter passed to
-     *      {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, A)}
+     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
      * @param startIndex The index into the mCallbacks to start notifying.
      * @param endIndex One past the last index into mCallbacks to notify.
      * @param bits A bit field indicating which callbacks have been removed and shouldn't
@@ -245,6 +247,7 @@
     /**
      * Removes callbacks from startIndex to startIndex + Long.SIZE, based
      * on the bits set in removed.
+     *
      * @param startIndex The index into the mCallbacks to start removing callbacks.
      * @param removed The bits indicating removal, where each bit is set for one callback
      *                to be removed.
@@ -264,6 +267,7 @@
 
     /**
      * Remove a callback. This callback won't be notified after this call completes.
+     *
      * @param callback The callback to remove.
      */
     public synchronized void remove(C callback) {
@@ -297,29 +301,12 @@
         }
     }
 
-    /*
-    private void clearRemovalBit(int index) {
-        if (index < Long.SIZE) {
-            // It is in the first 64 callbacks, just check the bit.
-            final long bitMask = 1L << index;
-            mFirst64Removed &= ~bitMask;
-        } else if (mRemainderRemoved != null) {
-            final int maskIndex = (index / Long.SIZE) - 1;
-            if (maskIndex < mRemainderRemoved.length) {
-                // There is something marked for removal, so we have to check the bit.
-                final long bitMask = 1L << (index % Long.SIZE);
-                mRemainderRemoved[maskIndex] &= ~bitMask;
-            }
-        }
-    }
-    */
-
     /**
      * Makes a copy of the registered callbacks and returns it.
      *
      * @return a copy of the registered callbacks.
      */
-    public synchronized ArrayList<C> copyListeners() {
+    public synchronized ArrayList<C> copyCallbacks() {
         ArrayList<C> callbacks = new ArrayList<C>(mCallbacks.size());
         int numListeners = mCallbacks.size();
         for (int i = 0; i < numListeners; i++) {
@@ -331,6 +318,21 @@
     }
 
     /**
+     * Modifies <code>callbacks</code> to contain all callbacks in the CallbackRegistry.
+     *
+     * @param callbacks modified to contain all callbacks registered to receive events.
+     */
+    public synchronized void copyCallbacks(List<C> callbacks) {
+        callbacks.clear();
+        int numListeners = mCallbacks.size();
+        for (int i = 0; i < numListeners; i++) {
+            if (!isRemoved(i)) {
+                callbacks.add(mCallbacks.get(i));
+            }
+        }
+    }
+
+    /**
      * Returns true if there are no registered callbacks or false otherwise.
      *
      * @return true if there are no registered callbacks or false otherwise.
@@ -364,6 +366,10 @@
         }
     }
 
+    /**
+     * @return A copy of the CallbackRegistry with all callbacks listening to both instances.
+     */
+    @SuppressWarnings("unchecked")
     public synchronized CallbackRegistry<C, T, A> clone() {
         CallbackRegistry<C, T, A> clone = null;
         try {
@@ -393,7 +399,8 @@
      */
     public abstract static class NotifierCallback<C, T, A> {
         /**
-         * Used to notify the callback.
+         * Called by CallbackRegistry during
+         * {@link CallbackRegistry#notifyCallbacks(Object, int, Object)}} to notify the callback.
          *
          * @param callback The callback to notify.
          * @param sender The opaque sender object.
diff --git a/baseLibrary/src/main/java/android/databinding/Untaggable.java b/baseLibrary/src/main/java/android/databinding/Untaggable.java
index a1ce3ac..c6b1c3d 100644
--- a/baseLibrary/src/main/java/android/databinding/Untaggable.java
+++ b/baseLibrary/src/main/java/android/databinding/Untaggable.java
@@ -18,6 +18,9 @@
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Target;
 
+/**
+ * @hide
+ */
 @Target({ElementType.TYPE})
 public @interface Untaggable {
     String[] value();
diff --git a/bintrayPlugin/settings.gradle b/bintrayPlugin/settings.gradle
deleted file mode 100644
index 0a47e83..0000000
--- a/bintrayPlugin/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-include 'bintrayPlugin'
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 01e3c42..acf68f4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,41 +1,22 @@
-Properties databindingProperties = new Properties()
-databindingProperties.load(new FileInputStream("${projectDir}/databinding.properties"))
-def repoBase = databindingProperties.mavenRepoAbsolutePath == "." ? projectDir : databindingProperties.mavenRepoAbsolutePath
-databindingProperties.mavenRepoDir = "${repoBase}/${databindingProperties.mavenRepoName}"
-databindingProperties.extraPluginsRepoDir = "${projectDir}/${databindingProperties.extraPluginsRepoName}"
 
-databindingProperties.eapOutDir = "${projectDir}/${databindingProperties.eapOutFolderName}"
-databindingProperties.prebuildFolder = "${projectDir}/${databindingProperties.prebuildFolderName}" +
-        "/${databindingProperties.releaseVersion}"
-ext.config = databindingProperties
-
-println "local maven repo is ${ext.config.mavenRepoDir}."
-println "local pre-build folder is ${ext.config.prebuildFolder}."
-
-new File(ext.config.mavenRepoDir).mkdir()
-new File(ext.config.prebuildFolder).mkdir()
-
+buildscript {
+    ext.rootFolder = project.projectDir
+    apply from: 'propLoader.gradle'
+    ext.addRepos(repositories)
+    if (ext.config.addRemoteRepos) {
+        dependencies {
+            classpath "com.android.databinding:localizemaven:${config.extraPluginsVersion}"
+        }
+    }
+}
 subprojects {
     apply plugin: 'maven'
-    group = config.group
-    version = config.version
-    buildscript {
-        repositories {
-            maven {
-                url "file://${config.extraPluginsRepoDir}"
-            }
-        }
-        dependencies {
-            classpath "com.android.databinding:bintray:${config.extraPluginsVersion}"
-        }
+    if (config.addRemoteRepos) {
+        apply plugin: 'com.android.databinding.localizemaven'
     }
 
-    repositories {
-        mavenCentral()
-        maven {
-            url "file://${config.mavenRepoDir}"
-        }
-    }
+    group = config.group
+    version = config.version
     uploadArchives {
         repositories {
             mavenDeployer {
@@ -43,6 +24,19 @@
             }
         }
     }
+    buildscript {
+        addRepos(repositories)
+        dependencies {
+            classpath "com.android.databinding:bintray:${config.extraPluginsVersion}"
+        }
+    }
+}
+
+if (config.addRemoteRepos) {
+    localizeMaven {
+        localRepoDir = file(config.megaRepoDir)
+        otherRepoDirs = config.localRepositories
+    }
 }
 
 task deleteRepo(type: Delete) {
@@ -145,4 +139,4 @@
     dependsOn copyMavenRepoToEap
     dependsOn copySamplesToEap
     dependsOn createEapConfigFile
-}
\ No newline at end of file
+}
diff --git a/buildSrc/src/main/groovy/android.databinding/LicenseCollector.groovy b/buildSrc/src/main/groovy/android.databinding/LicenseCollector.groovy
deleted file mode 100644
index ef6321e..0000000
--- a/buildSrc/src/main/groovy/android.databinding/LicenseCollector.groovy
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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 android.databinding
-import org.apache.commons.io.IOUtils
-import java.util.jar.JarFile
-import org.gradle.api.artifacts.ResolvedArtifact
-
-class LicenseCollector {
-    List<ResolvedArtifact> artifacts = new ArrayList();
-    def knownLicenses = [
-            [
-    libraries : ["kotlin-stdlib", "kotlin-runtime"],
-    licenses : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/LICENSE.txt",
-            "http://www.apache.org/licenses/LICENSE-2.0.txt"],
-    notices : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/NOTICE.txt"]
-            ],
-            [
-    libraries : ["antlr4", "antlr4-runtime", "antlr-runtime", "antlr4-annotations"],
-    licenses : ["https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt"]
-            ],
-            [
-    libraries : ["java.g4"],
-    licenses : ["https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt"]
-            ],
-            [
-    libraries : ["ST4"],
-    licenses : ["https://raw.githubusercontent.com/antlr/stringtemplate4/master/LICENSE.txt"]
-            ],
-            [
-    libraries : ["org.abego.treelayout.core"],
-    licenses: ["http://treelayout.googlecode.com/files/LICENSE.TXT"]
-            ],
-            [
-    libraries : ["junit"],
-    licenses : ["https://raw.githubusercontent.com/junit-team/junit/master/LICENSE-junit.txt"],
-    notices: ["https://raw.githubusercontent.com/junit-team/junit/master/NOTICE.txt"]
-            ],
-            [
-    libraries : ["commons-lang3", "commons-io", "commons-codec"],
-    licenses : ["http://svn.apache.org/viewvc/commons/proper/lang/trunk/LICENSE.txt?revision=560660&view=co"],
-    notices : ["http://svn.apache.org/viewvc/commons/proper/lang/trunk/NOTICE.txt?view=co"]
-            ],
-            [
-    libraries : ["guava"],
-    licenses : ["http://www.apache.org/licenses/LICENSE-2.0.txt"]
-            ],
-            [
-    libraries : ["hamcrest-core"],
-    licenses : ["https://raw.githubusercontent.com/hamcrest/JavaHamcrest/master/LICENSE.txt"]
-            ]
-            ]
-
-    Set<String> licenseLookup = new HashSet();
-
-    LicenseCollector() {
-        knownLicenses.each {
-            licenseLookup.addAll(it.libraries)
-        }
-    }
-
-    def skipLicenses = ['baseLibrary', 'grammarBuilder', 'xmlGrammar', 'compiler']
-    public void add(ResolvedArtifact artifact) {
-        artifacts.add(artifact)
-    }
-
-    public String buildNotice() {
-        artifacts.each { artifact ->
-            if (!skipLicenses.contains(artifact.getName())) {
-                if (!licenseLookup.contains(artifact.getName())) {
-                    throw new RuntimeException("Cannot find license for ${artifact.getName()} in ${artifact.getFile()}")
-                }
-            }
-        }
-
-        // now build the output
-        StringBuilder notice = new StringBuilder();
-        notice.append("List of 3rd party licenses:")
-        knownLicenses.each {
-            notice.append("\n-----------------------------------------------------------------------------")
-            it.libraries.each {
-                notice.append("\n* $it")
-            }
-            notice.append("\n")
-            if (it.notices != null) {
-                it.notices.each {
-                    notice.append("\n ****** NOTICE:\n${new URL(it).getText()}")
-                }
-            }
-            it.licenses.each {
-                notice.append("\n ****** LICENSE:\n${new URL(it).getText()}")
-            }
-            notice.append("\n\n\n")
-        }
-        return notice.toString()
-    }
-}
\ No newline at end of file
diff --git a/compilationTests/build.gradle b/compilationTests/build.gradle
index e8b56dd..743050c 100644
--- a/compilationTests/build.gradle
+++ b/compilationTests/build.gradle
@@ -3,12 +3,8 @@
 sourceCompatibility = 1.7
 version = '1.0'
 
-repositories {
-    mavenCentral()
-}
-
 dependencies {
-    testCompile group: 'junit', name: 'junit', version: '4.11'
+    testCompile group: 'junit', name: 'junit', version: '4.12'
     testCompile 'org.apache.commons:commons-lang3:3.3.2'
     testCompile 'commons-io:commons-io:2.4'
     testCompile 'commons-codec:commons-codec:1.10'
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java
index c9cf2a0..814f4aa 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/BaseCompilationTest.java
@@ -216,6 +216,7 @@
         if (localProperties.exists()) {
             FileUtils.copyFile(localProperties, new File(testFolder, "local.properties"));
         }
+        FileUtils.copyFile(new File("../propLoader.gradle"), new File(testFolder, "propLoaderClone.gradle"));
         FileUtils.copyFile(new File("../gradlew"), new File(testFolder, "gradlew"));
         FileUtils.copyDirectory(new File("../gradle"), new File(testFolder, "gradle"));
     }
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java b/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
index f50755b..f6d1f5e 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
@@ -47,7 +47,7 @@
         if (errors.isEmpty()) {
             return null;
         }
-        assertEquals(1, errors.size());
+        assertEquals(error, 1, errors.size());
         return errors.get(0);
     }
 
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
index e627c99..43efbb8 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
@@ -52,7 +52,7 @@
     public void testEmptyCompilation() throws IOException, URISyntaxException, InterruptedException {
         prepareProject();
         CompilationResult result = runGradle("assembleDebug");
-        assertEquals(0, result.resultCode);
+        assertEquals(result.error, 0, result.resultCode);
         assertTrue("there should not be any errors " + result.error, StringUtils.isEmpty(result.error));
         assertTrue("Test sanity, should compile fine",
                 result.resultContainsText("BUILD SUCCESSFUL"));
@@ -94,9 +94,9 @@
         copyResourceTo("/layout/invalid_setter_binding.xml",
                 "/app/src/main/res/layout/invalid_setter.xml");
         CompilationResult result = runGradle("assembleDebug");
-        assertNotEquals(0, result.resultCode);
+        assertNotEquals(result.output, 0, result.resultCode);
         List<ScopedException> bindingExceptions = result.getBindingExceptions();
-        assertEquals(2, bindingExceptions.size());
+        assertEquals(result.error, 2, bindingExceptions.size());
         File broken = new File(testFolder, "/app/src/main/res/layout/broken.xml");
         File invalidSetter = new File(testFolder, "/app/src/main/res/layout/invalid_setter.xml");
         for (ScopedException exception : bindingExceptions) {
diff --git a/compilationTests/src/test/resources/project_build.gradle b/compilationTests/src/test/resources/project_build.gradle
index b859755..fcf1b75 100644
--- a/compilationTests/src/test/resources/project_build.gradle
+++ b/compilationTests/src/test/resources/project_build.gradle
@@ -1,24 +1,18 @@
 buildscript {
-    def Properties dataBindingProperties = new Properties()
-    dataBindingProperties.load(new FileInputStream("${projectDir}/../../../databinding.properties"))
-    dataBindingProperties.mavenRepoDir = "${projectDir}/../../../${dataBindingProperties.mavenRepoName}"
-    ext.config = dataBindingProperties
-    println "loaded config"
-
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
+    ext.rootFolder = new File(project.projectDir, "../../..")
+    apply from: "${project.projectDir}/propLoaderClone.gradle"
+    ext.addRepos(repositories)
     dependencies {
-        classpath "com.android.tools.build:gradle:${config.androidPluginVersion}"
         classpath "com.android.databinding:dataBinder:${config.version}"
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
     }
 }
 
+subprojects {
+    apply plugin: 'maven'
+    group = config.group
+    version = config.version
+}
+
 allprojects {
     repositories {
         jcenter()
diff --git a/compiler/build.gradle b/compiler/build.gradle
index f59fe5a..711bb39 100644
--- a/compiler/build.gradle
+++ b/compiler/build.gradle
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import android.databinding.LicenseCollector
 apply plugin: 'java'
 apply plugin: "kotlin"
 apply plugin: 'com.android.databinding.bintray'
@@ -23,12 +22,9 @@
 targetCompatibility = config.javaSourceCompatibility
 
 buildscript {
-    repositories {
-        mavenCentral()
-    }
     dependencies {
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${config.kotlinVersion}"
-        classpath 'org.apache.commons:commons-io:1.3.2'
+        classpath 'commons-io:commons-io:2.4'
     }
 }
 
@@ -70,15 +66,7 @@
 task fatJar(type: Jar) {
     baseName = project.name + '-all'
     doFirst {
-        def LicenseCollector allLicenses = new LicenseCollector();
-        configurations.compile.getResolvedConfiguration().getResolvedArtifacts().each {
-            allLicenses.add(it)
-        }
-        def notice = allLicenses.buildNotice()
-        def noticeFile = new File(project.buildDir,'NOTICE.txt')
-        noticeFile.delete()
-        println ("writing notice file to: ${noticeFile.getAbsolutePath()}")
-        noticeFile << notice
+        tasks.findByName("buildLicenseNoticeFor${project.name.capitalize()}").execute()
     }
     from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
     from new File(project.buildDir,'NOTICE.txt')
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
index 61e6365..ab2b8bf 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
@@ -120,9 +120,9 @@
             final int minSdk, String exportClassNamesTo)
             throws JAXBException {
         final CompilerChef compilerChef = CompilerChef.createChef(resourceBundle, getWriter());
+        compilerChef.sealModels();
+        compilerChef.writeComponent();
         if (compilerChef.hasAnythingToGenerate()) {
-            compilerChef.sealModels();
-            compilerChef.writeComponent();
             compilerChef.writeViewBinderInterfaces(forLibraryModule);
             if (!forLibraryModule) {
                 compilerChef.writeViewBinders(minSdk);
diff --git a/compiler/src/test/java/android/databinding/CallbackRegistryTest.java b/compiler/src/test/java/android/databinding/CallbackRegistryTest.java
index fd1562d..f4cb59d 100644
--- a/compiler/src/test/java/android/databinding/CallbackRegistryTest.java
+++ b/compiler/src/test/java/android/databinding/CallbackRegistryTest.java
@@ -59,29 +59,29 @@
         registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier);
         Integer callback = 0;
 
-        assertNotNull(registry.copyListeners());
-        assertEquals(0, registry.copyListeners().size());
+        assertNotNull(registry.copyCallbacks());
+        assertEquals(0, registry.copyCallbacks().size());
 
         registry.add(callback);
-        ArrayList<Integer> callbacks = registry.copyListeners();
+        ArrayList<Integer> callbacks = registry.copyCallbacks();
         assertEquals(1, callbacks.size());
         assertEquals(callback, callbacks.get(0));
 
         registry.add(callback);
-        callbacks = registry.copyListeners();
+        callbacks = registry.copyCallbacks();
         assertEquals(1, callbacks.size());
         assertEquals(callback, callbacks.get(0));
 
         Integer otherListener = 1;
         registry.add(otherListener);
-        callbacks = registry.copyListeners();
+        callbacks = registry.copyCallbacks();
         assertEquals(2, callbacks.size());
         assertEquals(callback, callbacks.get(0));
         assertEquals(otherListener, callbacks.get(1));
 
         registry.remove(callback);
         registry.add(callback);
-        callbacks = registry.copyListeners();
+        callbacks = registry.copyCallbacks();
         assertEquals(2, callbacks.size());
         assertEquals(callback, callbacks.get(1));
         assertEquals(otherListener, callbacks.get(0));
@@ -130,7 +130,7 @@
         assertEquals(1, notify2);
         assertEquals(1, notify3);
 
-        ArrayList<Integer> callbacks = registry.copyListeners();
+        ArrayList<Integer> callbacks = registry.copyCallbacks();
         assertEquals(1, callbacks.size());
         assertEquals(callback3, callbacks.get(0));
     }
@@ -156,7 +156,7 @@
         assertEquals(2, notify2);
         assertEquals(3, notify3);
 
-        ArrayList<Integer> callbacks = registry.copyListeners();
+        ArrayList<Integer> callbacks = registry.copyCallbacks();
         assertEquals(0, callbacks.size());
     }
 
@@ -183,7 +183,7 @@
         registry.add(callback3);
         registry.notifyCallbacks(this, 0, null);
 
-        ArrayList<Integer> callbacks = registry.copyListeners();
+        ArrayList<Integer> callbacks = registry.copyCallbacks();
         assertEquals(3, callbacks.size());
         assertEquals(callback1, callbacks.get(0));
         assertEquals(callback3, callbacks.get(1));
@@ -220,7 +220,7 @@
             assertEquals(expectedCount, deepNotifyCount[i]);
         }
 
-        ArrayList<Integer> callbackList = registry.copyListeners();
+        ArrayList<Integer> callbackList = registry.copyCallbacks();
         assertEquals(0, callbackList.size());
     }
 
@@ -240,7 +240,7 @@
         }
         registry.clear();
 
-        ArrayList<Integer> callbackList = registry.copyListeners();
+        ArrayList<Integer> callbackList = registry.copyCallbacks();
         assertEquals(0, callbackList.size());
 
         registry.notifyCallbacks(this, 0, null);
@@ -269,7 +269,7 @@
             assertEquals(1, deepNotifyCount[i]);
         }
 
-        ArrayList<Integer> callbackList = registry.copyListeners();
+        ArrayList<Integer> callbackList = registry.copyCallbacks();
         assertEquals(0, callbackList.size());
     }
 
diff --git a/compilerCommon/build.gradle b/compilerCommon/build.gradle
index 4a5577c..61477da 100644
--- a/compilerCommon/build.gradle
+++ b/compilerCommon/build.gradle
@@ -19,9 +19,6 @@
 
 sourceCompatibility = config.javaTargetCompatibility
 targetCompatibility = config.javaSourceCompatibility
-repositories {
-    mavenCentral()
-}
 
 sourceSets {
     main {
@@ -40,7 +37,7 @@
 }
 
 dependencies {
-    testCompile group: 'junit', name: 'junit', version: '4.11'
+    testCompile group: 'junit', name: 'junit', version: '4.12'
     compile project(':baseLibrary')
     compile 'org.apache.commons:commons-lang3:3.3.2'
     compile 'com.tunnelvisionlabs:antlr4:4.5'
diff --git a/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java b/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java
index 35668cd..c723c80 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java
@@ -24,6 +24,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -97,8 +98,13 @@
             return;
         }
         StringBuilder sb = new StringBuilder();
+        HashSet<String> messages = new HashSet<String>();
         for (ScopedException ex : sDeferredExceptions) {
-            sb.append(ex.getMessage()).append("\n");
+            final String message = ex.getMessage();
+            if (!messages.contains(message)) {
+                sb.append(message).append("\n");
+                messages.add(message);
+            }
         }
         throw new RuntimeException("Found data binding errors.\n" + sb.toString());
     }
diff --git a/databinding.properties b/databinding.properties
index 1a8365f..2a8a107 100644
--- a/databinding.properties
+++ b/databinding.properties
@@ -1,8 +1,8 @@
 # global settings for projects
 kotlinVersion = 0.12.613
-version = 1.0-rc1
-releaseVersion = 1.0-rc1
-androidPluginVersion = 1.2.3
+version = 1.0-rc2-SNAPSHOT
+releaseVersion = 1.0-rc2-SNAPSHOT
+androidPluginVersion = 1.3.0-beta4
 javaTargetCompatibility = 1.7
 javaSourceCompatibility = 1.7
 
@@ -21,3 +21,4 @@
 mavenRepoName=maven-repo
 extraPluginsRepoName=plugins-repo
 extraPluginsVersion=1.0
+
diff --git a/bintrayPlugin/build.gradle b/developmentPlugins/bintrayPlugin/build.gradle
similarity index 66%
rename from bintrayPlugin/build.gradle
rename to developmentPlugins/bintrayPlugin/build.gradle
index 7b53e34..364a5bb 100644
--- a/bintrayPlugin/build.gradle
+++ b/developmentPlugins/bintrayPlugin/build.gradle
@@ -14,21 +14,14 @@
  * limitations under the License.
  */
 apply plugin: 'groovy'
-apply plugin: 'maven'
-Properties databindingProperties = new Properties()
-databindingProperties.load(new FileInputStream("${projectDir}/../databinding.properties"))
-databindingProperties.extraPluginsRepoDir = "${projectDir}/../${databindingProperties.extraPluginsRepoName}"
 
-version databindingProperties.extraPluginsVersion
-group databindingProperties.group
-ext.config = databindingProperties
 repositories {
     mavenCentral()
 }
 
 dependencies {
     compile gradleApi()
-    testCompile group: 'junit', name: 'junit', version: '4.11'
+    testCompile group: 'junit', name: 'junit', version: '4.12'
 }
 
 uploadArchives {
diff --git a/bintrayPlugin/gradle/wrapper/gradle-wrapper.jar b/developmentPlugins/bintrayPlugin/gradle/wrapper/gradle-wrapper.jar
similarity index 100%
rename from bintrayPlugin/gradle/wrapper/gradle-wrapper.jar
rename to developmentPlugins/bintrayPlugin/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/bintrayPlugin/gradle/wrapper/gradle-wrapper.properties b/developmentPlugins/bintrayPlugin/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from bintrayPlugin/gradle/wrapper/gradle-wrapper.properties
rename to developmentPlugins/bintrayPlugin/gradle/wrapper/gradle-wrapper.properties
diff --git a/bintrayPlugin/gradlew b/developmentPlugins/bintrayPlugin/gradlew
similarity index 100%
rename from bintrayPlugin/gradlew
rename to developmentPlugins/bintrayPlugin/gradlew
diff --git a/bintrayPlugin/gradlew.bat b/developmentPlugins/bintrayPlugin/gradlew.bat
similarity index 100%
rename from bintrayPlugin/gradlew.bat
rename to developmentPlugins/bintrayPlugin/gradlew.bat
diff --git a/bintrayPlugin/src/main/groovy/android/databinding/BintrayPlugin.groovy b/developmentPlugins/bintrayPlugin/src/main/groovy/android/databinding/BintrayPlugin.groovy
similarity index 98%
rename from bintrayPlugin/src/main/groovy/android/databinding/BintrayPlugin.groovy
rename to developmentPlugins/bintrayPlugin/src/main/groovy/android/databinding/BintrayPlugin.groovy
index 35f4e02..fe9d1b1 100644
--- a/bintrayPlugin/src/main/groovy/android/databinding/BintrayPlugin.groovy
+++ b/developmentPlugins/bintrayPlugin/src/main/groovy/android/databinding/BintrayPlugin.groovy
@@ -17,7 +17,6 @@
 
 import org.gradle.api.Plugin
 import org.gradle.api.Project
-import org.gradle.api.Task
 import org.gradle.api.publication.maven.internal.ant.DefaultGroovyMavenDeployer
 import org.gradle.api.tasks.Upload
 
diff --git a/bintrayPlugin/src/main/groovy/android/databinding/UploadToBintrayTask.groovy b/developmentPlugins/bintrayPlugin/src/main/groovy/android/databinding/UploadToBintrayTask.groovy
similarity index 100%
rename from bintrayPlugin/src/main/groovy/android/databinding/UploadToBintrayTask.groovy
rename to developmentPlugins/bintrayPlugin/src/main/groovy/android/databinding/UploadToBintrayTask.groovy
diff --git a/bintrayPlugin/src/main/resources/META-INF/gradle-plugins/com.android.databinding.bintray.properties b/developmentPlugins/bintrayPlugin/src/main/resources/META-INF/gradle-plugins/com.android.databinding.bintray.properties
similarity index 100%
rename from bintrayPlugin/src/main/resources/META-INF/gradle-plugins/com.android.databinding.bintray.properties
rename to developmentPlugins/bintrayPlugin/src/main/resources/META-INF/gradle-plugins/com.android.databinding.bintray.properties
diff --git a/developmentPlugins/build.gradle b/developmentPlugins/build.gradle
new file mode 100644
index 0000000..a99d215
--- /dev/null
+++ b/developmentPlugins/build.gradle
@@ -0,0 +1,14 @@
+ext.rootFolder = "${project.projectDir}/.."
+apply from: '../propLoader.gradle'
+subprojects {
+    apply plugin: 'maven'
+    group = config.group
+    version = config.extraPluginsVersion
+    uploadArchives {
+        repositories {
+            mavenDeployer {
+                repository(url: "file://${config.extraPluginsRepoDir}")
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/bintrayPlugin/gradle/wrapper/gradle-wrapper.jar b/developmentPlugins/gradle/wrapper/gradle-wrapper.jar
similarity index 100%
copy from bintrayPlugin/gradle/wrapper/gradle-wrapper.jar
copy to developmentPlugins/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/developmentPlugins/gradle/wrapper/gradle-wrapper.properties b/developmentPlugins/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..c2fda82
--- /dev/null
+++ b/developmentPlugins/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jul 10 16:16:18 PDT 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/bintrayPlugin/gradlew b/developmentPlugins/gradlew
similarity index 100%
copy from bintrayPlugin/gradlew
copy to developmentPlugins/gradlew
diff --git a/bintrayPlugin/gradlew.bat b/developmentPlugins/gradlew.bat
similarity index 100%
copy from bintrayPlugin/gradlew.bat
copy to developmentPlugins/gradlew.bat
diff --git a/bintrayPlugin/build.gradle b/developmentPlugins/localizeMavenPlugin/build.gradle
similarity index 63%
copy from bintrayPlugin/build.gradle
copy to developmentPlugins/localizeMavenPlugin/build.gradle
index 7b53e34..02d9b16 100644
--- a/bintrayPlugin/build.gradle
+++ b/developmentPlugins/localizeMavenPlugin/build.gradle
@@ -13,28 +13,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-apply plugin: 'groovy'
-apply plugin: 'maven'
-Properties databindingProperties = new Properties()
-databindingProperties.load(new FileInputStream("${projectDir}/../databinding.properties"))
-databindingProperties.extraPluginsRepoDir = "${projectDir}/../${databindingProperties.extraPluginsRepoName}"
 
-version databindingProperties.extraPluginsVersion
-group databindingProperties.group
-ext.config = databindingProperties
+apply plugin: 'groovy'
+
 repositories {
     mavenCentral()
 }
 
 dependencies {
     compile gradleApi()
-    testCompile group: 'junit', name: 'junit', version: '4.11'
+    compile localGroovy()
+    compile 'commons-io:commons-io:2.4'
+    compile 'org.apache.maven:maven-aether-provider:3.3.3'
+    compile 'org.eclipse.aether:aether-transport-http:1.0.2.v20150114'
+    compile 'org.eclipse.aether:aether:1.0.2.v20150114'
+    compile 'org.eclipse.aether:aether-connector-basic:1.0.2.v20150114'
+    compile 'org.eclipse.aether:aether-transport-file:1.0.2.v20150114'
+
 }
 
 uploadArchives {
     repositories {
         mavenDeployer {
-            pom.artifactId = 'bintray'
+            pom.artifactId = 'localizemaven'
             repository(url: "file://${config.extraPluginsRepoDir}")
         }
     }
diff --git a/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy
new file mode 100644
index 0000000..cf3ef59
--- /dev/null
+++ b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding
+
+import org.gradle.api.DefaultTask;
+import org.gradle.api.artifacts.ResolvedArtifact
+import org.gradle.api.tasks.TaskAction;
+
+class ExportLicensesTask extends DefaultTask {
+    List<ResolvedArtifact> artifacts = new ArrayList();
+
+    static def knownLicenses = [
+            [
+                    libraries: ["kotlin-stdlib", "kotlin-runtime", "kotlin-annotation-processing", "kotlin-gradle-plugin", "kotlin-gradle-plugin-api"],
+                    licenses : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/LICENSE.txt",
+                                "http://www.apache.org/licenses/LICENSE-2.0.txt"],
+                    notices  : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/NOTICE.txt"]
+            ],
+            [
+                    libraries: ["antlr4", "antlr4-runtime", "antlr-runtime", "antlr4-annotations"],
+                    licenses : ["https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt"]
+            ],
+            [
+                    libraries: ["antlr"],
+                    licenses: ["http://www.antlr3.org/license.html", "http://www.antlr2.org/license.html"]
+            ],
+            [
+                    libraries: ["java.g4"],
+                    licenses : ["https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt"]
+            ],
+            [
+                    libraries: ["ST4", "stringtemplate"],
+                    licenses : ["https://raw.githubusercontent.com/antlr/stringtemplate4/master/LICENSE.txt"]
+            ],
+            [
+                    libraries: ["org.abego.treelayout.core"],
+                    licenses : ["http://treelayout.googlecode.com/files/LICENSE.TXT"]
+            ],
+            [
+                    libraries: ["junit"],
+                    licenses : ["https://raw.githubusercontent.com/junit-team/junit/master/LICENSE-junit.txt"],
+                    notices  : ["https://raw.githubusercontent.com/junit-team/junit/master/NOTICE.txt"]
+            ],
+            [
+                    libraries: ["commons-io"],
+                    licenses : ["http://svn.apache.org/viewvc/commons/proper/io/trunk/LICENSE.txt?view=co"],
+                    notices  : ["http://svn.apache.org/viewvc/commons/proper/io/trunk/NOTICE.txt?view=co"]
+            ],
+            [
+                    libraries: ["commons-codec"],
+                    licenses: ["http://svn.apache.org/viewvc/commons/proper/codec/trunk/LICENSE.txt?view=co"],
+                    notices: ["http://svn.apache.org/viewvc/commons/proper/codec/trunk/NOTICE.txt?view=co"]
+            ],
+            [
+                    libraries: ["commons-lang3"],
+                    licenses : ["https://git-wip-us.apache.org/repos/asf?p=commons-lang.git;a=blob_plain;f=LICENSE.txt;hb=refs/heads/master"],
+                    notices  : ["https://git-wip-us.apache.org/repos/asf?p=commons-lang.git;a=blob_plain;f=NOTICE.txt;hb=refs/heads/master"]
+            ],
+            [
+                    libraries: ["guava"],
+                    licenses : ["http://www.apache.org/licenses/LICENSE-2.0.txt"]
+            ],
+            [
+                    libraries: ["hamcrest-core"],
+                    licenses : ["https://raw.githubusercontent.com/hamcrest/JavaHamcrest/master/LICENSE.txt"]
+            ],
+            [
+                    libraries: ["avalon-framework"],
+                    licenses : ["http://archive.apache.org/dist/avalon/LICENSE.txt"]
+            ],
+            [
+                    libraries: ["log4j"],
+                    licenses: ["https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=blob_plain;f=LICENSE.txt;hb=HEAD"],
+                    notices: ["https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=blob_plain;f=NOTICE.txt;hb=HEAD"]
+            ],
+            [
+                    libraries: ["ant", "ant-launcher"],
+                    licenses: ["http://www.apache.org/licenses/LICENSE-2.0.html"]
+            ],
+            [
+                    libraries: ["xz"],
+                    licenses: ["http://git.tukaani.org/?p=xz-java.git;a=blob_plain;f=COPYING;hb=HEAD"]
+            ],
+            [
+                    libraries: ["logkit"],
+                    licenses: ["unknown. see: http://commons.apache.org/proper/commons-logging/dependencies.html"]
+            ]
+
+    ]
+
+    Map<String, Object> usedLicenses = new HashMap<>();
+    static Map<String, Object> licenseLookup = new HashMap<>();
+    static {
+        knownLicenses.each {license ->
+            license.libraries.each {
+                licenseLookup.put(it, license)
+            }
+        }
+    }
+
+    ExportLicensesTask() {
+    }
+
+    public void add(ResolvedArtifact artifact) {
+        artifacts.add(artifact)
+        println("adding artifact $artifact")
+    }
+
+    @TaskAction
+    public void exportNotice() {
+        project.configurations.compile.getResolvedConfiguration().getResolvedArtifacts().each {
+            add(it)
+        }
+        resolveLicenses()
+        def notice = buildNotice(usedLicenses)
+        def noticeFile = new File(project.buildDir,'NOTICE.txt')
+        noticeFile.delete()
+        println ("writing notice file to: ${noticeFile.getAbsolutePath()}")
+        noticeFile << notice
+    }
+
+    public void resolveLicenses() {
+        artifacts.each { artifact ->
+            if (!shouldSkip(artifact)) {
+                def license = licenseLookup.get(artifact.name)
+                if (license  == null) {
+                    throw new RuntimeException("Cannot find license for ${artifact.getModuleVersion().id} in ${artifact.getFile()}")
+                }
+                usedLicenses.put(artifact, license)
+            }
+        }
+    }
+
+    public static Object findLicenseFor(String artifactId) {
+        return licenseLookup.get(artifactId)
+    }
+
+    public static String urlToText(String url) {
+        //return new URL(url).getText()
+        return url
+    }
+
+    public boolean shouldSkip(ResolvedArtifact artifact) {
+        return artifact.getModuleVersion().id.group.startsWith("com.android");
+    }
+
+    public static String buildNotice(Map<String, Object> licenses) {
+        // now build the output
+        StringBuilder notice = new StringBuilder();
+        notice.append("List of 3rd party licenses:")
+        licenses.each {
+            notice.append("\n-----------------------------------------------------------------------------")
+            notice.append("\n* ${it.key}")
+            notice.append("\n")
+            def license = it.value
+            if (license.notices != null) {
+                license.notices.each {
+                    notice.append("\n ****** NOTICE:\n${urlToText(it)}")
+                }
+            }
+            license.licenses.each {
+                notice.append("\n ****** LICENSE:\n${urlToText(it)}")
+            }
+            notice.append("\n\n\n")
+        }
+        return notice.toString()
+    }
+}
\ No newline at end of file
diff --git a/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/LocalizeDependenciesTask.groovy b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/LocalizeDependenciesTask.groovy
new file mode 100644
index 0000000..a9e8d05
--- /dev/null
+++ b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/LocalizeDependenciesTask.groovy
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding
+
+import groovy.io.FileType
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils
+import org.eclipse.aether.DefaultRepositorySystemSession
+import org.eclipse.aether.RepositorySystem
+import org.eclipse.aether.RepositorySystemSession
+import org.eclipse.aether.artifact.Artifact
+import org.eclipse.aether.artifact.DefaultArtifact
+import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory
+import org.eclipse.aether.graph.Dependency
+import org.eclipse.aether.impl.DefaultServiceLocator
+import org.eclipse.aether.repository.LocalRepository
+import org.eclipse.aether.repository.RemoteRepository
+import org.eclipse.aether.resolution.ArtifactDescriptorRequest
+import org.eclipse.aether.resolution.ArtifactDescriptorResult
+import org.eclipse.aether.resolution.ArtifactRequest
+import org.eclipse.aether.spi.connector.RepositoryConnectorFactory
+import org.eclipse.aether.spi.connector.transport.TransporterFactory
+import org.eclipse.aether.transport.file.FileTransporterFactory
+import org.eclipse.aether.transport.http.HttpTransporterFactory
+import org.gradle.api.DefaultTask
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.ModuleVersionIdentifier
+import org.gradle.api.tasks.TaskAction
+
+class LocalizeDependenciesTask extends DefaultTask {
+
+    private Set<String> ids = new HashSet<>();
+
+    private Set<String> fetchTestDependencies = new HashSet<>();
+
+    List<Artifact> artifactsToResolve = new LinkedList<>();
+
+    Set<String> resolvedArtifacts = new HashSet<>();
+
+    Set<String> failed = new HashSet<>();
+
+    HashMap<String, Object> licenses = new HashMap<>();
+
+    Set<String> missingLicenses = new HashSet<>();
+
+    File localRepoDir;
+
+    @TaskAction
+    doIt() {
+        println(ids)
+        LocalizePluginExtension extension = project.extensions.
+                getByName(MavenDependencyCollectorPlugin.EXTENSION_NAME)
+        if (extension.localRepoDir == null || extension.otherRepoDirs == null) {
+            throw new IllegalArgumentException("you must configure " +
+                    "${MavenDependencyCollectorPlugin.EXTENSION_NAME} with localRepoDir and" +
+                    " otherRepoDirs")
+        }
+        localRepoDir = extension.localRepoDir
+        downloadAll(extension.localRepoDir, extension.otherRepoDirs)
+
+        if (!missingLicenses.isEmpty()) {
+            throw new RuntimeException("Missing licenses for $missingLicenses")
+        }
+        println("List of new licenses:")
+        println(ExportLicensesTask.buildNotice(licenses))
+    }
+
+    public void add(MavenDependencyCollectorTask task, ModuleVersionIdentifier id, Configuration conf) {
+        def key = toStringIdentifier(id)
+        ids.add(key)
+        println("adding $key in $conf by $task")
+    }
+
+    public static String toStringIdentifier(ModuleVersionIdentifier id) {
+        return id.group + ":" + id.name + ":" + id.version;
+    }
+
+    private static String artifactKey(Artifact artifact) {
+        return artifact.groupId + ":" + artifact.artifactId + ":" + artifact.version;
+    }
+
+    public downloadAll(File localRepoDir, List<String> otherRepoDirs) {
+        println("downloading all dependencies to $localRepoDir")
+        def mavenCentral = new RemoteRepository.Builder("central", "default",
+                "http://central.maven.org/maven2/").build();
+        def system = newRepositorySystem()
+        localRepoDir = localRepoDir.canonicalFile
+        List<File> otherRepos = new ArrayList<>()
+        otherRepoDirs.each {
+            def repo = new File(it).getCanonicalFile()
+            if (repo.exists() && !repo.equals(localRepoDir)) {
+                otherRepos.add(repo)
+            }
+        }
+        def session = newRepositorySystemSession(system, localRepoDir)
+        ids.each {
+            def artifact = new DefaultArtifact(it)
+            artifactsToResolve.add(artifact)
+        }
+
+        while (!artifactsToResolve.isEmpty()) {
+            println("remaining artifacts to resolve ${artifactsToResolve.size()}")
+            Artifact artifact = artifactsToResolve.remove(0)
+            println("    handling artifact ${artifact.getArtifactId()}")
+            if (shouldSkip(artifact, otherRepos)) {
+                println("skipping $artifact")
+                continue
+            }
+            resolveArtifactWithDependencies(system, session, Arrays.asList(mavenCentral), artifact);
+        }
+    }
+
+    public static boolean shouldSkip(Artifact artifact, List<File> otherRepos) {
+        if (artifact.groupId.startsWith('com.android.databinding') ||
+                artifact.groupId.startsWith('com.android.support') ||
+                artifact.groupId.equals("jdk")){
+            return true
+        }
+        String targetPath = artifact.groupId.replaceAll("\\.", "/") + "/" + artifact.artifactId +
+                "/" + artifact.version
+        for (File repo : otherRepos) {
+            File f = new File(repo, targetPath)
+            if (f.exists()) {
+                println("skipping ${artifact} because it exists in $repo")
+                return true
+            }
+        }
+        return false
+    }
+
+    def boolean isInGit(File file) {
+        if (!file.getCanonicalPath().startsWith(localRepoDir.getCanonicalPath())) {
+            println("$file is in another git repo, ignore for license")
+            return false
+        }
+        def gitSt = ["git", "status", "--porcelain", file.getCanonicalPath()].
+                execute([], localRepoDir)
+        gitSt.waitFor()
+        if (gitSt.exitValue() != 0) {
+            throw new RuntimeException("unable to get git status for $file. ${gitSt.err.text}")
+        }
+        return gitSt.text.trim().isEmpty()
+    }
+
+    public void resolveArtifactWithDependencies(RepositorySystem system,
+            RepositorySystemSession session, List<RemoteRepository> remoteRepositories,
+            Artifact artifact) {
+        def key = artifactKey(artifact)
+        if (resolvedArtifacts.contains(key) || failed.contains(key)) {
+            return
+        }
+        resolvedArtifacts.add(key)
+        ArtifactRequest artifactRequest = new ArtifactRequest();
+        artifactRequest.setArtifact(artifact);
+        artifactRequest.setRepositories(remoteRepositories);
+        def resolved;
+        try {
+            resolved = system.resolveArtifact(session, artifactRequest);
+        } catch (Throwable ignored) {
+            println("cannot find $key, skipping")
+            failed.add(key)
+            return
+        }
+        def alreadyInGit = isInGit(resolved.artifact.file)
+        println("         |-> resolved ${resolved.artifact.file}. Already in git? $alreadyInGit")
+
+
+
+        if (!alreadyInGit) {
+            def license = ExportLicensesTask.findLicenseFor(resolved.artifact.artifactId)
+            if (license == null) {
+                missingLicenses.add(artifactKey(artifact))
+            } else {
+                licenses.put(resolved.artifact.artifactId, license)
+            }
+        }
+
+        ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
+        descriptorRequest.setArtifact(artifact);
+        descriptorRequest.setRepositories(remoteRepositories);
+
+        ArtifactDescriptorResult descriptorResult = system.
+                readArtifactDescriptor(session, descriptorRequest);
+        for (Dependency dependency : descriptorResult.getDependencies()) {
+            println("dependency $dependency for $artifact . scope: ${dependency.scope}")
+            if ("provided".equals(dependency.scope)) {
+                println("skipping $dependency because provided")
+                continue
+            }
+            if ("optional".equals(dependency.scope)) {
+                println("skipping $dependency because optional")
+                continue
+            }
+            if ("test".equals(dependency.scope)) {
+                if (fetchTestDependencies.contains(key)) {
+                    println("${dependency} is test scope but including because $key is in direct dependencies")
+                } else {
+                    println("skipping $dependency because test and not first level dependency")
+                    continue
+                }
+            }
+
+
+            def dependencyKey = artifactKey(dependency.artifact)
+            if (resolvedArtifacts.contains(dependencyKey)) {
+                println("skipping $dependency because is already resolved as ${dependencyKey}")
+                continue
+            }
+            println("adding to the list ${dependency.artifact}")
+            artifactsToResolve.add(dependency.artifact)
+        }
+        File unwanted = new File(resolved.artifact.file.getParentFile(), "_remote.repositories")
+        if (unwanted.exists()) {
+            unwanted.delete()
+        }
+    }
+
+    public static DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system,
+            File localRepoDir) {
+        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+        LocalRepository localRepo = new LocalRepository(localRepoDir);
+        session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
+        return session;
+    }
+
+    public static RepositorySystem newRepositorySystem() {
+        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
+        locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
+        locator.addService(TransporterFactory.class, FileTransporterFactory.class);
+        locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
+
+        return locator.getService(RepositorySystem.class);
+    }
+}
diff --git a/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/LocalizePluginExtension.groovy b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/LocalizePluginExtension.groovy
new file mode 100644
index 0000000..0104206
--- /dev/null
+++ b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/LocalizePluginExtension.groovy
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding
+
+
+class LocalizePluginExtension {
+    def File localRepoDir;
+    def List<String> otherRepoDirs;
+}
diff --git a/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/MavenDependencyCollectorPlugin.groovy b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/MavenDependencyCollectorPlugin.groovy
new file mode 100644
index 0000000..c3a318d
--- /dev/null
+++ b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/MavenDependencyCollectorPlugin.groovy
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+public class MavenDependencyCollectorPlugin implements Plugin<Project> {
+    private static final String DEFAULT_TASK_NAME = "localizeDependencies"
+    static final String EXTENSION_NAME = "localizeMaven"
+    @Override
+    void apply(Project project) {
+        Project parent = project.parent == null ? project : project.parent;
+        def localizeDependenciesTask = parent.tasks.findByName(DEFAULT_TASK_NAME)
+        if (localizeDependenciesTask == null) {
+            localizeDependenciesTask = parent.tasks.
+                    create(DEFAULT_TASK_NAME, LocalizeDependenciesTask)
+            parent.extensions.create(EXTENSION_NAME, LocalizePluginExtension)
+        }
+
+        project.allprojects {
+            afterEvaluate { p ->
+                project.tasks.create("collectDependenciesOf${it.getName().capitalize()}", MavenDependencyCollectorTask, {
+                    it.localizeTask = localizeDependenciesTask
+                    localizeDependenciesTask.dependsOn it
+                })
+
+            }
+        }
+        project.tasks.create("buildLicenseNotice", ExportLicensesTask) {
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/MavenDependencyCollectorTask.groovy b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/MavenDependencyCollectorTask.groovy
new file mode 100644
index 0000000..4966868
--- /dev/null
+++ b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/MavenDependencyCollectorTask.groovy
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding
+
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils
+import org.eclipse.aether.DefaultRepositorySystemSession
+import org.eclipse.aether.RepositorySystem
+import org.eclipse.aether.RepositorySystemSession
+import org.eclipse.aether.artifact.Artifact
+import org.eclipse.aether.artifact.DefaultArtifact
+import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory
+import org.eclipse.aether.graph.Dependency
+import org.eclipse.aether.impl.DefaultServiceLocator
+import org.eclipse.aether.repository.LocalRepository
+import org.eclipse.aether.repository.RemoteRepository
+import org.eclipse.aether.resolution.ArtifactDescriptorRequest
+import org.eclipse.aether.resolution.ArtifactDescriptorResult
+import org.eclipse.aether.resolution.ArtifactRequest
+import org.eclipse.aether.spi.connector.RepositoryConnectorFactory
+import org.eclipse.aether.spi.connector.transport.TransporterFactory
+import org.eclipse.aether.transport.file.FileTransporterFactory
+import org.eclipse.aether.transport.http.HttpTransporterFactory
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.ModuleVersionIdentifier
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.TaskAction
+
+class MavenDependencyCollectorTask extends DefaultTask {
+    @Input
+    LocalizeDependenciesTask localizeTask
+
+    @TaskAction
+    public void doIt() {
+        project.configurations.each { conf ->
+            resolveDirectDependencies(conf)
+        }
+        project.buildscript.configurations.each { conf ->
+            resolveDirectDependencies(conf)
+        }
+    }
+
+    void resolveDirectDependencies(Configuration conf) {
+        conf.getResolvedConfiguration().getResolvedArtifacts().each {
+            localizeTask.add(this, it.getModuleVersion().id, conf)
+        }
+    }
+}
diff --git a/developmentPlugins/localizeMavenPlugin/src/main/resources/META-INF/gradle-plugins/com.android.databinding.localizemaven.properties b/developmentPlugins/localizeMavenPlugin/src/main/resources/META-INF/gradle-plugins/com.android.databinding.localizemaven.properties
new file mode 100644
index 0000000..c738d68
--- /dev/null
+++ b/developmentPlugins/localizeMavenPlugin/src/main/resources/META-INF/gradle-plugins/com.android.databinding.localizemaven.properties
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# 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.
+#
+
+implementation-class=android.databinding.MavenDependencyCollectorPlugin
\ No newline at end of file
diff --git a/developmentPlugins/settings.gradle b/developmentPlugins/settings.gradle
new file mode 100644
index 0000000..2788877
--- /dev/null
+++ b/developmentPlugins/settings.gradle
@@ -0,0 +1,2 @@
+include 'bintrayPlugin'
+include 'localizeMavenPlugin'
\ No newline at end of file
diff --git a/extensions/baseAdapters/build.gradle b/extensions/baseAdapters/build.gradle
index 813f599..9450d42 100644
--- a/extensions/baseAdapters/build.gradle
+++ b/extensions/baseAdapters/build.gradle
@@ -43,15 +43,9 @@
 }
 
 dependencies {
-    // TODO make these provided when gradle build supports them
-    // see: https://code.google.com/p/android/issues/detail?id=149268
-    compile 'com.android.support:support-v4:+'
-    compile 'com.android.support:cardview-v7:+'
-    compile 'com.android.support:appcompat-v7:+'
-}
-
-configurations {
-    jarArchives
+    provided 'com.android.support:support-v4:+'
+    provided 'com.android.support:cardview-v7:+'
+    provided 'com.android.support:appcompat-v7:+'
 }
 
 //create jar tasks
@@ -62,24 +56,9 @@
         return; // Skip debug builds.
     }
     def suffix = name.capitalize()
-    // @Jar version is needed to run compiler tests
-    def jarTask = project.tasks.create "jar${suffix}", Jar
-    jarTask.dependsOn variant.javaCompile
-    jarTask.from variant.javaCompile.destinationDir
-    def packageName = "com.android.databinding.library.baseAdapters"
-    def appPkgAsClass = packageName.replace('.', '/')
-    jarTask.exclude("android/databinding/layouts/*.*")
-    jarTask.exclude("$appPkgAsClass/databinding/*")
-    jarTask.exclude("$appPkgAsClass/BR.*")
-    artifacts.add('jarArchives', jarTask);
 
     def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
         source variant.javaCompile.source
-        exclude("android/databinding/layouts/*.*")
-        exclude("$appPkgAsClass/databinding/*")
-        exclude("$appPkgAsClass/BR.*")
-        exclude("$appPkgAsClass/R.*")
-        exclude("$appPkgAsClass/BuildConfig.*")
         classpath = files(variant.javaCompile.classpath.files) + files(
                 "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
     }
@@ -95,22 +74,15 @@
         from android.sourceSets.main.java.srcDirs
     }
 
-    artifacts.add('jarArchives', javadocJarTask);
-    artifacts.add('jarArchives', sourcesJarTask);
+    artifacts.add('archives', javadocJarTask);
+    artifacts.add('archives', sourcesJarTask);
 }
 
 uploadArchives {
-}
-
-uploadJarArchives {
     repositories {
         mavenDeployer {
             repository(url: "file://${config.mavenRepoDir}")
             pom.artifactId = "adapters"
-            pom.whenConfigured {
-                println("configured pom, $it")
-                it.dependencies.clear()
-            }
             pom.project {
                 licenses {
                     license {
@@ -124,7 +96,7 @@
     }
 }
 
-uploadArchives.dependsOn uploadJarArchives
+
 task prebuild(type : Copy) {
     dependsOn uploadArchives
     from "$buildDir/outputs/aar/baseAdapters-release.aar"
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java
index d8c3125..9643be2 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java
@@ -34,9 +34,7 @@
      * so will not keep a strong reference to either.
      *
      * Example usage:
-     * <pre>
-     * {@code
-     * @BindingAdapter("onFoo")
+     *<pre><code>@BindingAdapter("onFoo")
      * public static void addFooListener(MyView view, OnFooListener listener) {
      *     OnFooListener oldValue = ListenerUtil.trackListener(view, listener, R.id.fooListener);
      *     if (oldValue != null) {
@@ -45,9 +43,7 @@
      *     if (listener != null) {
      *         view.addOnFooListener(listener);
      *     }
-     * }
-     * }
-     * </pre>
+     * }</code></pre>
      *
      * @param view The View that will have this listener
      * @param listener The listener to keep track of. May be null if the listener is being removed.
diff --git a/extensions/build.gradle b/extensions/build.gradle
index 6b9575d..51aad32 100644
--- a/extensions/build.gradle
+++ b/extensions/build.gradle
@@ -13,24 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-
+ext.rootFolder = new File(project.projectDir, "..")
 buildscript {
-    def Properties dataBindingProperties = new Properties()
-    dataBindingProperties.load(new FileInputStream("${projectDir}/../databinding.properties"))
-    def repoBase = dataBindingProperties.mavenRepoAbsolutePath == "." ? "${projectDir}/.." : dataBindingProperties.mavenRepoAbsolutePath
-    dataBindingProperties.mavenRepoDir = "${repoBase}/${dataBindingProperties.mavenRepoName}"
-    dataBindingProperties.prebuildFolder = "${projectDir}/../${dataBindingProperties.prebuildFolderName}" +
-            "/${dataBindingProperties.releaseVersion}"
-    ext.config = dataBindingProperties
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
+    ext.rootFolder = new File(project.projectDir, "..")
+    apply from: "${project.projectDir}/../propLoader.gradle"
+    ext.addRepos(repositories)
     dependencies {
-        classpath "com.android.tools.build:gradle:${config.androidPluginVersion}"
         classpath "com.android.databinding:dataBinder:${config.version}"
     }
 }
@@ -39,16 +27,8 @@
     apply plugin: 'maven'
     group = config.group
     version = config.version
-    repositories {
-        mavenCentral()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
 }
 
-
-
 task preparePrebuilds() {
 }
 
diff --git a/gradlePlugin/build.gradle b/gradlePlugin/build.gradle
index 92ae8bf..203105a 100644
--- a/gradlePlugin/build.gradle
+++ b/gradlePlugin/build.gradle
@@ -19,11 +19,6 @@
 sourceCompatibility = config.javaTargetCompatibility
 targetCompatibility = config.javaSourceCompatibility
 
-buildscript {
-    repositories {
-        mavenCentral()
-    }
-}
 
 tasks.create(name : 'copyBuildVersion') << {
     def buildVersionFile = new File(sourceSets.main.output.resourcesDir,"data_binding_build_info")
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
index 22e1056..a116dc1 100644
--- a/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
@@ -346,7 +346,7 @@
             String removeGeneratedTaskName = "dataBindingExcludeGeneratedFrom" +
                     StringUtils.capitalize(packageTask.getName());
             if (project.getTasks().findByName(removeGeneratedTaskName) == null) {
-                final AbstractCompile javaCompileTask = variantData.javaCompileTask;
+                final AbstractCompile javaCompileTask = variantData.javacTask;
                 Preconditions.checkNotNull(javaCompileTask);
 
                 project.getTasks().create(removeGeneratedTaskName,
diff --git a/integration-tests/App With Spaces/build.gradle b/integration-tests/App With Spaces/build.gradle
index ddf912c..b13840a 100644
--- a/integration-tests/App With Spaces/build.gradle
+++ b/integration-tests/App With Spaces/build.gradle
@@ -14,31 +14,11 @@
  * limitations under the License.
  */
 buildscript {
-    def Properties dataBindingProperties = new Properties()
-    dataBindingProperties.load(new FileInputStream("${projectDir}/../../databinding.properties"))
-    dataBindingProperties.mavenRepoDir = "${projectDir}/../../${dataBindingProperties.mavenRepoName}"
-    ext.config = dataBindingProperties
-    println "loaded config"
-
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
+    ext.rootFolder = new File(project.projectDir, "../..")
+    apply from: "${project.projectDir}/../../propLoader.gradle"
+    ext.addRepos(repositories)
     dependencies {
         classpath "com.android.tools.build:gradle:${config.androidPluginVersion}"
         classpath "com.android.databinding:dataBinder:${config.version}"
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
     }
 }
diff --git a/integration-tests/IndependentLibrary/build.gradle b/integration-tests/IndependentLibrary/build.gradle
index 8c6433d..db36a5b 100644
--- a/integration-tests/IndependentLibrary/build.gradle
+++ b/integration-tests/IndependentLibrary/build.gradle
@@ -14,31 +14,11 @@
  */
 
 buildscript {
-    def Properties dataBindingProperties = new Properties()
-    dataBindingProperties.load(new FileInputStream("${projectDir}/../../databinding.properties"))
-    dataBindingProperties.mavenRepoDir = "${projectDir}/../../${dataBindingProperties.mavenRepoName}"
-    ext.config = dataBindingProperties
-    println "loaded config"
-
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
+    ext.rootFolder = new File(project.projectDir, "../..")
+    apply from: "${project.projectDir}/../../propLoader.gradle"
+    ext.addRepos(repositories)
     dependencies {
         classpath "com.android.tools.build:gradle:${config.androidPluginVersion}"
         classpath "com.android.databinding:dataBinder:${config.version}"
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
     }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
-}
+}
\ No newline at end of file
diff --git a/integration-tests/MultiModuleTestApp/build.gradle b/integration-tests/MultiModuleTestApp/build.gradle
index ddf912c..5e5a3e2 100644
--- a/integration-tests/MultiModuleTestApp/build.gradle
+++ b/integration-tests/MultiModuleTestApp/build.gradle
@@ -14,31 +14,11 @@
  * limitations under the License.
  */
 buildscript {
-    def Properties dataBindingProperties = new Properties()
-    dataBindingProperties.load(new FileInputStream("${projectDir}/../../databinding.properties"))
-    dataBindingProperties.mavenRepoDir = "${projectDir}/../../${dataBindingProperties.mavenRepoName}"
-    ext.config = dataBindingProperties
-    println "loaded config"
-
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
+    ext.rootFolder = new File(project.projectDir, "../..")
+    apply from: "${project.projectDir}/../../propLoader.gradle"
+    ext.addRepos(repositories)
     dependencies {
         classpath "com.android.tools.build:gradle:${config.androidPluginVersion}"
         classpath "com.android.databinding:dataBinder:${config.version}"
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
     }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
-}
+}
\ No newline at end of file
diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/InvalidateAllTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/InvalidateAllTest.java
index 7e5ee20..bdf9f0d 100644
--- a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/InvalidateAllTest.java
+++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/InvalidateAllTest.java
@@ -17,9 +17,11 @@
     public void testRefreshViaInvalidateAll() throws InterruptedException {
         final Semaphore semaphore = new Semaphore(1);
         semaphore.acquire();
+        final NotBindableVo vo = new NotBindableVo("foo");
         initBinder(new Runnable() {
             @Override
             public void run() {
+                mBinder.setVo(vo);
                 mBinder.addOnRebindCallback(new OnRebindCallback() {
                     @Override
                     public void onBound(ViewDataBinding binding) {
@@ -29,8 +31,6 @@
                 });
             }
         });
-        NotBindableVo vo = new NotBindableVo("foo");
-        mBinder.setVo(vo);
         assertTrue(semaphore.tryAcquire(2, TimeUnit.SECONDS));
 
         assertEquals("foo", mBinder.textView.getText().toString());
diff --git a/integration-tests/TestApp/build.gradle b/integration-tests/TestApp/build.gradle
index c80adb4..c15f7f5 100644
--- a/integration-tests/TestApp/build.gradle
+++ b/integration-tests/TestApp/build.gradle
@@ -1,29 +1,9 @@
 buildscript {
-    def Properties dataBindingProperties = new Properties()
-    dataBindingProperties.load(new FileInputStream("${projectDir}/../../databinding.properties"))
-    dataBindingProperties.mavenRepoDir = "${projectDir}/../../${dataBindingProperties.mavenRepoName}"
-    ext.config = dataBindingProperties
-    println "loaded config"
-
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
-    }
+    ext.rootFolder = new File(project.projectDir, "../..")
+    apply from: "${project.projectDir}/../../propLoader.gradle"
+    ext.addRepos(repositories)
     dependencies {
         classpath "com.android.tools.build:gradle:${config.androidPluginVersion}"
         classpath "com.android.databinding:dataBinder:${config.version}"
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-        maven {
-            url config.mavenRepoDir
-        }
     }
 }
diff --git a/library/build.gradle b/library/build.gradle
index 0d9fd62..937a383 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -17,9 +17,6 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 
 buildscript {
-    repositories {
-        jcenter()
-    }
     dependencies {
         classpath "com.android.tools.build:gradle:${config.androidPluginVersion}"
         // NOTE: Do not place your application dependencies here; they belong
diff --git a/library/src/doc/java/com/android/databinding/library/R.java b/library/src/doc/java/com/android/databinding/library/R.java
new file mode 100644
index 0000000..668a20c
--- /dev/null
+++ b/library/src/doc/java/com/android/databinding/library/R.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 com.android.databinding.library;
+
+/**
+ * This is only here to allow building the javadoc without building the rest of
+ * data binding.
+ *
+ * This should be removed when data binding is included in the framework build.
+ *
+ * @hide
+ */
+public class R {
+    public static class id {
+        public static int dataBinding = 0;
+    }
+}
\ No newline at end of file
diff --git a/library/src/main/java/android/databinding/BaseObservable.java b/library/src/main/java/android/databinding/BaseObservable.java
index 6c19c4d..f3be2c6 100644
--- a/library/src/main/java/android/databinding/BaseObservable.java
+++ b/library/src/main/java/android/databinding/BaseObservable.java
@@ -18,7 +18,7 @@
 
 /**
  * A convenience class that implements {@link android.databinding.Observable} interface and provides
- * {@link #notifyPropertyChanged(int)} and @{link #notifyChange} methods.
+ * {@link #notifyPropertyChanged(int)} and {@link #notifyChange} methods.
  */
 public class BaseObservable implements Observable {
     private transient PropertyChangeRegistry mCallbacks;
@@ -27,26 +27,36 @@
     }
 
     @Override
-    public synchronized void addOnPropertyChangedCallback(OnPropertyChangedCallback listener) {
+    public synchronized void addOnPropertyChangedCallback(OnPropertyChangedCallback callback) {
         if (mCallbacks == null) {
             mCallbacks = new PropertyChangeRegistry();
         }
-        mCallbacks.add(listener);
+        mCallbacks.add(callback);
     }
 
     @Override
-    public synchronized void removeOnPropertyChangedCallback(OnPropertyChangedCallback listener) {
+    public synchronized void removeOnPropertyChangedCallback(OnPropertyChangedCallback callback) {
         if (mCallbacks != null) {
-            mCallbacks.remove(listener);
+            mCallbacks.remove(callback);
         }
     }
 
+    /**
+     * Notifies listeners that all properties of this instance have changed.
+     */
     public synchronized void notifyChange() {
         if (mCallbacks != null) {
             mCallbacks.notifyCallbacks(this, 0, null);
         }
     }
 
+    /**
+     * Notifies listeners that a specific property has changed. The getter for the property
+     * that changes should be marked with {@link Bindable} to generate a field in
+     * <code>BR</code> to be used as <code>fieldId</code>.
+     *
+     * @param fieldId The generated BR id for the Bindable field.
+     */
     public void notifyPropertyChanged(int fieldId) {
         if (mCallbacks != null) {
             mCallbacks.notifyCallbacks(this, fieldId, null);
diff --git a/library/src/main/java/android/databinding/DataBinderMapper.java b/library/src/main/java/android/databinding/DataBinderMapper.java
index 044880f..683615a 100644
--- a/library/src/main/java/android/databinding/DataBinderMapper.java
+++ b/library/src/main/java/android/databinding/DataBinderMapper.java
@@ -22,6 +22,7 @@
  * This class will be stripped from the jar and then replaced by the annotation processor
  * as part of the code generation step. This class's existence is just to ensure that
  * compile works and no reflection is needed to access the generated class.
+ * @hide
  */
 class DataBinderMapper {
     public ViewDataBinding getDataBinder(DataBindingComponent bindingComponent, View view,
diff --git a/library/src/main/java/android/databinding/DataBindingComponent.java b/library/src/main/java/android/databinding/DataBindingComponent.java
index d609118..a8fb2fe 100644
--- a/library/src/main/java/android/databinding/DataBindingComponent.java
+++ b/library/src/main/java/android/databinding/DataBindingComponent.java
@@ -15,6 +15,10 @@
  */
 package android.databinding;
 
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
 /**
  * This interface is generated during compilation to contain getters for all used instance
  * BindingAdapters. When a BindingAdapter is an instance method, an instance of the class
@@ -25,8 +29,12 @@
  * An instance of this class may also be passed into static or instance BindingAdapters as the
  * first parameter.
  * <p>
- * If you are using Dagger 2, you should extend this interface and annotate the extended interface
+ * If using Dagger 2, the developer should extend this interface and annotate the extended interface
  * as a Component.
+ *
+ * @see DataBindingUtil#setDefaultComponent(DataBindingComponent)
+ * @see DataBindingUtil#inflate(LayoutInflater, int, ViewGroup, boolean, DataBindingComponent)
+ * @see DataBindingUtil#bind(View, DataBindingComponent)
  */
 public interface DataBindingComponent {
 }
diff --git a/library/src/main/java/android/databinding/DataBindingUtil.java b/library/src/main/java/android/databinding/DataBindingUtil.java
index 9860a4a..c2e616f 100644
--- a/library/src/main/java/android/databinding/DataBindingUtil.java
+++ b/library/src/main/java/android/databinding/DataBindingUtil.java
@@ -32,17 +32,30 @@
     private static DataBindingComponent sDefaultComponent = null;
 
     /**
-     * Set the default {@link DataBindingComponent} to use for data binding. When instance
-     * method BindingAdapters are used, the class instance for the binding adapter is retrieved
-     * from the DataBindingComponent.
+     * Prevent DataBindingUtil from being instantiated.
+     */
+    private DataBindingUtil() {}
+
+    /**
+     * Set the default {@link DataBindingComponent} to use for data binding.
+     * <p>
+     * <code>bindingComponent</code> may be passed as the first parameter of binding adapters.
+     * <p>
+     * When instance method BindingAdapters are used, the class instance for the binding adapter
+     * is retrieved from the DataBindingComponent.
      */
     public static void setDefaultComponent(DataBindingComponent bindingComponent) {
         sDefaultComponent = bindingComponent;
     }
 
     /**
-     * @return the default {@link DataBindingComponent} used in data binding. Can be <code>null</code>
-     * if no default was set in {@link #setDefaultComponent(DataBindingComponent)}.
+     * Returns the default {@link DataBindingComponent} used in data binding. This can be
+     * <code>null</code> if no default was set in
+     * {@link #setDefaultComponent(DataBindingComponent)}.
+     *
+     * @return the default {@link DataBindingComponent} used in data binding. This can be
+     * <code>null</code> if no default was set in
+     * {@link #setDefaultComponent(DataBindingComponent)}.
      */
     public static DataBindingComponent getDefaultComponent() {
         return sDefaultComponent;
@@ -52,6 +65,9 @@
      * Inflates a binding layout and returns the newly-created binding for that layout.
      * This uses the DataBindingComponent set in
      * {@link #setDefaultComponent(DataBindingComponent)}.
+     * <p>
+     * Use this version only if <code>layoutId</code> is unknown in advance. Otherwise, use
+     * the generated Binding's inflate method to ensure type-safe inflation.
      *
      * @param inflater The LayoutInflater used to inflate the binding layout.
      * @param layoutId The layout resource ID of the layout to inflate.
@@ -74,6 +90,9 @@
 
     /**
      * Inflates a binding layout and returns the newly-created binding for that layout.
+     * <p>
+     * Use this version only if <code>layoutId</code> is unknown in advance. Otherwise, use
+     * the generated Binding's inflate method to ensure type-safe inflation.
      *
      * @param inflater The LayoutInflater used to inflate the binding layout.
      * @param layoutId The layout resource ID of the layout to inflate.
@@ -117,6 +136,9 @@
      * Returns the binding for the given layout root or creates a binding if one
      * does not exist. This uses the DataBindingComponent set in
      * {@link #setDefaultComponent(DataBindingComponent)}.
+     * <p>
+     * Prefer using the generated Binding's <code>bind</code> method to ensure type-safe inflation
+     * when it is known that <code>root</code> has not yet been bound.
      *
      * @param root The root View of the inflated binding layout.
      * @return A ViewDataBinding for the given root View. If one already exists, the
@@ -132,6 +154,9 @@
     /**
      * Returns the binding for the given layout root or creates a binding if one
      * does not exist.
+     * <p>
+     * Prefer using the generated Binding's <code>bind</code> method to ensure type-safe inflation
+     * when it is known that <code>root</code> has not yet been bound.
      *
      * @param root The root View of the inflated binding layout.
      * @param bindingComponent The DataBindingComponent to use in data binding.
@@ -177,7 +202,7 @@
      * <code>null</code> will be returned.
      * <p>
      * This differs from {@link #getBinding(View)} in that findBinding takes any view in the
-     * layout and searches for the binding associated with the root <code>getBinding</code>
+     * layout and searches for the binding associated with the root. <code>getBinding</code>
      * takes only the root view.
      *
      * @param view A <code>View</code> in the bound layout.
diff --git a/library/src/main/java/android/databinding/ListChangeRegistry.java b/library/src/main/java/android/databinding/ListChangeRegistry.java
index 4ea2c6f..e13f867 100644
--- a/library/src/main/java/android/databinding/ListChangeRegistry.java
+++ b/library/src/main/java/android/databinding/ListChangeRegistry.java
@@ -17,6 +17,9 @@
 
 import android.support.v4.util.Pools;
 
+/**
+ * Utility class for managing ObservableList callbacks.
+ */
 public class ListChangeRegistry
         extends
         CallbackRegistry<ObservableList.OnListChangedCallback, ObservableList,
@@ -57,25 +60,59 @@
         }
     };
 
+    /**
+     * Notify registered callbacks that there was an unknown or whole-list change.
+     *
+     * @param list The list that changed.
+     */
     public void notifyChanged(ObservableList list) {
         notifyCallbacks(list, ALL, null);
     }
 
+    /**
+     * Notify registered callbacks that some elements have changed.
+     *
+     * @param list The list that changed.
+     * @param start The index of the first changed element.
+     * @param count The number of changed elements.
+     */
     public void notifyChanged(ObservableList list, int start, int count) {
         ListChanges listChanges = acquire(start, 0, count);
         notifyCallbacks(list, CHANGED, listChanges);
     }
 
+    /**
+     * Notify registered callbacks that elements were inserted.
+     *
+     * @param list The list that changed.
+     * @param start The index where the elements were inserted.
+     * @param count The number of elements that were inserted.
+     */
     public void notifyInserted(ObservableList list, int start, int count) {
         ListChanges listChanges = acquire(start, 0, count);
         notifyCallbacks(list, INSERTED, listChanges);
     }
 
+    /**
+     * Notify registered callbacks that elements were moved.
+     *
+     * @param list The list that changed.
+     * @param from The index of the first element moved.
+     * @param to The index of where the element was moved to.
+     * @param count The number of elements moved.
+     */
     public void notifyMoved(ObservableList list, int from, int to, int count) {
         ListChanges listChanges = acquire(from, to, count);
         notifyCallbacks(list, MOVED, listChanges);
     }
 
+    /**
+     * Notify registered callbacks that elements were deleted.
+     *
+     * @param list The list that changed.
+     * @param start The index of the first element to be removed.
+     * @param count The number of elements removed.
+     */
     public void notifyRemoved(ObservableList list, int start, int count) {
         ListChanges listChanges = acquire(start, 0, count);
         notifyCallbacks(list, REMOVED, listChanges);
@@ -101,9 +138,6 @@
         }
     }
 
-    /**
-     * Creates an EventRegistry that notifies the event with notifier.
-     */
     public ListChangeRegistry() {
         super(NOTIFIER_CALLBACK);
     }
diff --git a/library/src/main/java/android/databinding/MapChangeRegistry.java b/library/src/main/java/android/databinding/MapChangeRegistry.java
index 5815606..9c453b6 100644
--- a/library/src/main/java/android/databinding/MapChangeRegistry.java
+++ b/library/src/main/java/android/databinding/MapChangeRegistry.java
@@ -15,6 +15,9 @@
  */
 package android.databinding;
 
+/**
+ * Utility class for managing ObservableMap callbacks.
+ */
 public class MapChangeRegistry
         extends CallbackRegistry<ObservableMap.OnMapChangedCallback, ObservableMap, Object> {
 
@@ -31,6 +34,12 @@
         super(NOTIFIER_CALLBACK);
     }
 
+    /**
+     * Notifies registered callbacks that an element has been added, removed, or changed.
+     *
+     * @param sender The map that has changed.
+     * @param key The key of the element that changed.
+     */
     public void notifyChange(ObservableMap sender, Object key) {
         notifyCallbacks(sender, 0, key);
     }
diff --git a/library/src/main/java/android/databinding/ObservableArrayList.java b/library/src/main/java/android/databinding/ObservableArrayList.java
index 88c27e4..864e09e 100644
--- a/library/src/main/java/android/databinding/ObservableArrayList.java
+++ b/library/src/main/java/android/databinding/ObservableArrayList.java
@@ -18,6 +18,9 @@
 import java.util.ArrayList;
 import java.util.Collection;
 
+/**
+ * An {@link ObservableList} implementation using ArrayList as an implementation.
+ */
 public class ObservableArrayList<T> extends ArrayList<T> implements ObservableList<T> {
     private transient ListChangeRegistry mListeners = new ListChangeRegistry();
 
diff --git a/library/src/main/java/android/databinding/ObservableBoolean.java b/library/src/main/java/android/databinding/ObservableBoolean.java
index f85ad08..73c65aa 100644
--- a/library/src/main/java/android/databinding/ObservableBoolean.java
+++ b/library/src/main/java/android/databinding/ObservableBoolean.java
@@ -21,7 +21,14 @@
 import java.io.Serializable;
 
 /**
- * An observable class that holds a primitive int.
+ * An observable class that holds a primitive boolean.
+ * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableBoolean isAdult = new ObservableBoolean();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
  * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
@@ -46,10 +53,16 @@
     public ObservableBoolean() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public boolean get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(boolean value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableByte.java b/library/src/main/java/android/databinding/ObservableByte.java
index 9133ec9..bba7ec1 100644
--- a/library/src/main/java/android/databinding/ObservableByte.java
+++ b/library/src/main/java/android/databinding/ObservableByte.java
@@ -23,6 +23,13 @@
 /**
  * An observable class that holds a primitive byte.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableByte flags = new ObservableByte();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
  * data binding framework always re-registers callbacks when the view is bound.
@@ -46,10 +53,16 @@
     public ObservableByte() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public byte get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(byte value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableChar.java b/library/src/main/java/android/databinding/ObservableChar.java
index acd5e84..883cb90 100644
--- a/library/src/main/java/android/databinding/ObservableChar.java
+++ b/library/src/main/java/android/databinding/ObservableChar.java
@@ -23,6 +23,13 @@
 /**
  * An observable class that holds a primitive char.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableChar firstInitial = new ObservableChar();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
  * data binding framework always re-registers callbacks when the view is bound.
@@ -46,10 +53,16 @@
     public ObservableChar() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public char get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(char value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableDouble.java b/library/src/main/java/android/databinding/ObservableDouble.java
index 3582017..78f6a48 100644
--- a/library/src/main/java/android/databinding/ObservableDouble.java
+++ b/library/src/main/java/android/databinding/ObservableDouble.java
@@ -23,6 +23,13 @@
 /**
  * An observable class that holds a primitive double.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableDouble temperature = new ObservableDouble();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
  * data binding framework always re-registers callbacks when the view is bound.
@@ -46,10 +53,16 @@
     public ObservableDouble() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public double get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(double value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableField.java b/library/src/main/java/android/databinding/ObservableField.java
index a3e49bc..6de798b 100644
--- a/library/src/main/java/android/databinding/ObservableField.java
+++ b/library/src/main/java/android/databinding/ObservableField.java
@@ -19,6 +19,14 @@
 
 /**
  * An object wrapper to make it observable.
+ * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableField&lt;String> name = new ObservableField&lt;String>();
+ *     public final ObservableInt age = new ObservableInt();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
  *
  * @param <T> The type parameter for the actual object.
  * @see android.databinding.ObservableParcelable
@@ -42,10 +50,16 @@
     public ObservableField() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public T get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(T value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableFloat.java b/library/src/main/java/android/databinding/ObservableFloat.java
index 7e7f829..0eb8969 100644
--- a/library/src/main/java/android/databinding/ObservableFloat.java
+++ b/library/src/main/java/android/databinding/ObservableFloat.java
@@ -23,6 +23,13 @@
 /**
  * An observable class that holds a primitive float.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableFloat temperature = new ObservableFloat();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
  * data binding framework always re-registers callbacks when the view is bound.
@@ -46,10 +53,16 @@
     public ObservableFloat() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public float get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(float value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableInt.java b/library/src/main/java/android/databinding/ObservableInt.java
index 8affde2..cb25c56 100644
--- a/library/src/main/java/android/databinding/ObservableInt.java
+++ b/library/src/main/java/android/databinding/ObservableInt.java
@@ -23,6 +23,14 @@
 /**
  * An observable class that holds a primitive int.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableField<String> name = new ObservableField<String>();
+ *     public final ObservableInt age = new ObservableInt();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
  * data binding framework always re-registers callbacks when the view is bound.
@@ -46,10 +54,16 @@
     public ObservableInt() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public int get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(int value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableLong.java b/library/src/main/java/android/databinding/ObservableLong.java
index fbc98af..954e326 100644
--- a/library/src/main/java/android/databinding/ObservableLong.java
+++ b/library/src/main/java/android/databinding/ObservableLong.java
@@ -23,6 +23,13 @@
 /**
  * An observable class that holds a primitive long.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableLong friendCount = new ObservableLong();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
  * data binding framework always re-registers callbacks when the view is bound.
@@ -46,10 +53,16 @@
     public ObservableLong() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public long get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(long value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/ObservableParcelable.java b/library/src/main/java/android/databinding/ObservableParcelable.java
index 92ff87b..96eec27 100644
--- a/library/src/main/java/android/databinding/ObservableParcelable.java
+++ b/library/src/main/java/android/databinding/ObservableParcelable.java
@@ -24,6 +24,14 @@
 /**
  * An observable class that holds a parcelable object.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableParcelable&lt;String> name = new ObservableParcelable&lt;String>();
+ *     public final ObservableInt age = new ObservableInt();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable but you should keep in mind that listeners are ignored when the object
  * is parcelled. Unless you add custom observers, this should not be an issue because data binding
  * framework always re-registers observers when the view is bound.
diff --git a/library/src/main/java/android/databinding/ObservableShort.java b/library/src/main/java/android/databinding/ObservableShort.java
index b4de9ea..57e428d 100644
--- a/library/src/main/java/android/databinding/ObservableShort.java
+++ b/library/src/main/java/android/databinding/ObservableShort.java
@@ -23,6 +23,13 @@
 /**
  * An observable class that holds a primitive short.
  * <p>
+ * Observable field classes may be used instead of creating an Observable object:
+ * <pre><code>public class MyDataObject {
+ *     public final ObservableShort age = new ObservableShort();
+ * }</code></pre>
+ * Fields of this type should be declared final because bindings only detect changes in the
+ * field's value, not of the field itself.
+ * <p>
  * This class is parcelable and serializable but callbacks are ignored when the object is
  * parcelled / serialized. Unless you add custom callbacks, this will not be an issue because
  * data binding framework always re-registers callbacks when the view is bound.
@@ -46,10 +53,16 @@
     public ObservableShort() {
     }
 
+    /**
+     * @return the stored value.
+     */
     public short get() {
         return mValue;
     }
 
+    /**
+     * Set the stored value.
+     */
     public void set(short value) {
         if (value != mValue) {
             mValue = value;
diff --git a/library/src/main/java/android/databinding/PropertyChangeRegistry.java b/library/src/main/java/android/databinding/PropertyChangeRegistry.java
index 59de731..5e1858c 100644
--- a/library/src/main/java/android/databinding/PropertyChangeRegistry.java
+++ b/library/src/main/java/android/databinding/PropertyChangeRegistry.java
@@ -15,6 +15,9 @@
  */
 package android.databinding;
 
+/**
+ * Utility class for managing Observable callbacks.
+ */
 public class PropertyChangeRegistry extends
         CallbackRegistry<Observable.OnPropertyChangedCallback, Observable, Void> {
 
@@ -30,6 +33,13 @@
         super(NOTIFIER_CALLBACK);
     }
 
+    /**
+     * Notifies registered callbacks that a specific property has changed.
+     *
+     * @param observable The Observable that has changed.
+     * @param propertyId The BR id of the property that has changed or BR._all if the entire
+     *                   Observable has changed.
+     */
     public void notifyChange(Observable observable, int propertyId) {
         notifyCallbacks(observable, propertyId, null);
     }
diff --git a/library/src/main/java/android/databinding/ViewDataBinding.java b/library/src/main/java/android/databinding/ViewDataBinding.java
index ee117a2..b23d7b8 100644
--- a/library/src/main/java/android/databinding/ViewDataBinding.java
+++ b/library/src/main/java/android/databinding/ViewDataBinding.java
@@ -27,12 +27,19 @@
 import android.text.TextUtils;
 import android.util.SparseIntArray;
 import android.view.Choreographer;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewGroup;
 
 import java.lang.ref.WeakReference;
 
+/**
+ * Base class for generated data binding classes. If possible, the generated binding should
+ * be instantiated using one of its generated static bind or inflate methods. If the specific
+ * binding is unknown, {@link DataBindingUtil#bind(View)} or
+ * {@link DataBindingUtil#inflate(LayoutInflater, int, ViewGroup, boolean)} should be used.
+ */
 public abstract class ViewDataBinding {
 
     /**
@@ -48,6 +55,8 @@
     /**
      * Prefix for android:tag on Views with binding. The root View and include tags will not have
      * android:tag attributes and will use ids instead.
+     *
+     * @hide
      */
     public static final String BINDING_TAG_PREFIX = "binding_";
 
@@ -267,6 +276,7 @@
      * @param fieldId The BR ID of the field being changed or _all if
      *                no specific field is being notified.
      * @return true if this change should cause a change to the UI.
+     * @hide
      */
     protected abstract boolean onFieldChange(int localFieldId, Object object, int fieldId);
 
@@ -394,7 +404,9 @@
     }
 
     /**
-     * Returns the outermost View in the layout file associated with the Binding.
+     * Returns the outermost View in the layout file associated with the Binding. If this
+     * binding is for a merge layout file, this will return the first root in the merge tag.
+     *
      * @return the outermost View in the layout file associated with the Binding.
      */
     public View getRoot() {
@@ -540,6 +552,7 @@
      * @return An array of size numBindings containing all Views in the hierarchy that have IDs
      * (with elements in viewsWithIds), are tagged containing expressions, or the bindings for
      * included layouts.
+     * @hide
      */
     protected static Object[] mapBindings(DataBindingComponent bindingComponent, View root,
             int numBindings, IncludedLayouts includes, SparseIntArray viewsWithIds) {
diff --git a/library/src/main/java/android/databinding/ViewStubProxy.java b/library/src/main/java/android/databinding/ViewStubProxy.java
index 2f2f512..6979928 100644
--- a/library/src/main/java/android/databinding/ViewStubProxy.java
+++ b/library/src/main/java/android/databinding/ViewStubProxy.java
@@ -21,8 +21,9 @@
 
 /**
  * This class represents a ViewStub before and after inflation. Before inflation,
- * the ViewStub is accessible. After inflation, the ViewDataBinding is accessible
- * if the inflated View has bindings. If not, the root View will be accessible.
+ * the ViewStub is accessible. After inflation, the root View of the inflated layout
+ * will be available. If the inflated layout has data binding, the ViewDataBinding for the inflated
+ * View is accessible.
  */
 public class ViewStubProxy {
     private ViewStub mViewStub;
@@ -58,31 +59,42 @@
     }
 
     /**
-     * @return <code>true</code> if the ViewStub has replaced itself with the inflated layout
+     * Returns <code>true</code> if the ViewStub has replaced itself with the inflated layout
      * or <code>false</code> if not.
+     *
+     * @return <code>true</code> if the ViewStub has replaced itself with the inflated layout
+     * or <code>false</code> if not
      */
     public boolean isInflated() {
         return mRoot != null;
     }
 
     /**
-     * @return The root View of the layout replacing the ViewStub once it has been inflated.
+     * Returns the root View of the layout replacing the ViewStub once it has been inflated.
      * <code>null</code> is returned prior to inflation.
+     *
+     * @return the root View of the layout replacing the ViewStub once it has been inflated.
+     * <code>null</code> is returned prior to inflation
      */
     public View getRoot() {
         return mRoot;
     }
 
     /**
-     * @return The data binding associated with the inflated layout once it has been inflated.
+     * Returns the data binding associated with the inflated layout once it has been inflated.
      * <code>null</code> prior to inflation or if there is no binding associated with the layout.
+     *
+     * @return the data binding associated with the inflated layout once it has been inflated.
+     * <code>null</code> prior to inflation or if there is no binding associated with the layout
      */
     public ViewDataBinding getBinding() {
         return mViewDataBinding;
     }
 
     /**
-     * @return The ViewStub in the layout or <code>null</code> if the ViewStub has been inflated.
+     * Returns the ViewStub in the layout or <code>null</code> if the ViewStub has been inflated.
+     *
+     * @return the ViewStub in the layout or <code>null</code> if the ViewStub has been inflated.
      */
     public ViewStub getViewStub() {
         return mViewStub;
diff --git a/localize.sh b/localize.sh
new file mode 100755
index 0000000..d861d77
--- /dev/null
+++ b/localize.sh
@@ -0,0 +1,2 @@
+ #!/bin/bash
+./gradlew localizeDependencies -PaddRemoteRepos=true
diff --git a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar
index 5c9686e..27fa902 100644
--- a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar
+++ b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar
Binary files differ
diff --git a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.md5 b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.md5
index 3293a1e..bb1e3c0 100644
--- a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.md5
+++ b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.md5
@@ -1 +1 @@
-83d38096b851a268a66d2d6ee90a31ff
\ No newline at end of file
+21449624c543d72f226683327e46bc52
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.sha1 b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.sha1
index fda9ccc..1fb2594 100644
--- a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.sha1
+++ b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.jar.sha1
@@ -1 +1 @@
-94f6eead750fe14be81f7d18b7aa4dbd64f1c31e
\ No newline at end of file
+4b9a0762ff3a255e5a57386c54a8379133d45998
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom
index 611e415..7b2ffc5 100644
--- a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom
+++ b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom
@@ -9,7 +9,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.11</version>
+      <version>4.12</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.md5 b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.md5
index 6e44b0b..06b668b 100644
--- a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.md5
+++ b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.md5
@@ -1 +1 @@
-be31274229f9a5963df0a56affb9e35c
\ No newline at end of file
+3dc6ce6e2b0f405e0e005bfd61824683
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.sha1 b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.sha1
index c9742ca..c071f7c 100644
--- a/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.sha1
+++ b/plugins-repo/com/android/databinding/bintray/1.0/bintray-1.0.pom.sha1
@@ -1 +1 @@
-65d055619f31b262aae79b71aef852d66275caee
\ No newline at end of file
+05fa26e81f15809f9e231099f05fc62d0c4a536b
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/bintray/maven-metadata.xml b/plugins-repo/com/android/databinding/bintray/maven-metadata.xml
index 454a889..1615227 100644
--- a/plugins-repo/com/android/databinding/bintray/maven-metadata.xml
+++ b/plugins-repo/com/android/databinding/bintray/maven-metadata.xml
@@ -7,6 +7,6 @@
     <versions>
       <version>1.0</version>
     </versions>
-    <lastUpdated>20150710193446</lastUpdated>
+    <lastUpdated>20150714230002</lastUpdated>
   </versioning>
 </metadata>
diff --git a/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.md5 b/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.md5
index 4d96143..91cb33f 100644
--- a/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.md5
+++ b/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.md5
@@ -1 +1 @@
-dbc6439743246c12efca48c1b6976eae
\ No newline at end of file
+c68b6bdd46b2c465501abedb72b62b15
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.sha1 b/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.sha1
index 9f1bf9c..8281a74 100644
--- a/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.sha1
+++ b/plugins-repo/com/android/databinding/bintray/maven-metadata.xml.sha1
@@ -1 +1 @@
-71029b8d18868e830b6480e9e45e0394c586d170
\ No newline at end of file
+243c68cc8984455847e8765e14e34fa355378405
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar
new file mode 100644
index 0000000..d8d10fc
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar
Binary files differ
diff --git a/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar.md5 b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar.md5
new file mode 100644
index 0000000..d82ebb7
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar.md5
@@ -0,0 +1 @@
+6b918ba89221ac740a32a1fdbf2076f7
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar.sha1 b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar.sha1
new file mode 100644
index 0000000..c285e77
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.jar.sha1
@@ -0,0 +1 @@
+cac4bbf3c633037d17d1d9543071d5c13135bd67
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom
new file mode 100644
index 0000000..e9cc223
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.android.databinding</groupId>
+  <artifactId>localizemaven</artifactId>
+  <version>1.0</version>
+  <dependencies>
+    <dependency>
+      <groupId>org.eclipse.aether</groupId>
+      <artifactId>aether-connector-basic</artifactId>
+      <version>1.0.2.v20150114</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.aether</groupId>
+      <artifactId>aether-transport-http</artifactId>
+      <version>1.0.2.v20150114</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.aether</groupId>
+      <artifactId>aether-transport-file</artifactId>
+      <version>1.0.2.v20150114</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-aether-provider</artifactId>
+      <version>3.3.3</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>2.4</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.aether</groupId>
+      <artifactId>aether</artifactId>
+      <version>1.0.2.v20150114</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom.md5 b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom.md5
new file mode 100644
index 0000000..21c3a27
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom.md5
@@ -0,0 +1 @@
+f7cd22c6b15280987bb23c4871f32d31
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom.sha1 b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom.sha1
new file mode 100644
index 0000000..f0713d2
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/1.0/localizemaven-1.0.pom.sha1
@@ -0,0 +1 @@
+2bae0e1507a55b8d3ad7f484c56a25896b490cc0
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml b/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml
new file mode 100644
index 0000000..42bba55
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>com.android.databinding</groupId>
+  <artifactId>localizemaven</artifactId>
+  <version>1.0</version>
+  <versioning>
+    <versions>
+      <version>1.0</version>
+    </versions>
+    <lastUpdated>20150714230005</lastUpdated>
+  </versioning>
+</metadata>
diff --git a/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml.md5 b/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml.md5
new file mode 100644
index 0000000..19bed64
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml.md5
@@ -0,0 +1 @@
+ef58d2c1f235e51db31d0efaf6736192
\ No newline at end of file
diff --git a/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml.sha1 b/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml.sha1
new file mode 100644
index 0000000..e946b8a
--- /dev/null
+++ b/plugins-repo/com/android/databinding/localizemaven/maven-metadata.xml.sha1
@@ -0,0 +1 @@
+070f503e0456b0092c916ff84e23b272ca266a97
\ No newline at end of file
diff --git a/propLoader.gradle b/propLoader.gradle
new file mode 100644
index 0000000..f8730ae
--- /dev/null
+++ b/propLoader.gradle
@@ -0,0 +1,71 @@
+/**
+ * Helper build script that reads data binding variables and sets up the projects.
+ */
+def root = ext.rootFolder
+Properties databindingProperties = new Properties()
+databindingProperties.load(new FileInputStream("${root}/databinding.properties"))
+def repoBase = databindingProperties.mavenRepoAbsolutePath == "." ? root : databindingProperties.mavenRepoAbsolutePath
+databindingProperties.mavenRepoDir = "${repoBase}/${databindingProperties.mavenRepoName}"
+databindingProperties.extraPluginsRepoDir = "${root}/${databindingProperties.extraPluginsRepoName}"
+
+databindingProperties.eapOutDir = "${root}/${databindingProperties.eapOutFolderName}"
+databindingProperties.prebuildFolder = "${root}/${databindingProperties.prebuildFolderName}" +
+        "/${databindingProperties.releaseVersion}"
+
+ext.config = databindingProperties
+ext.config.externalPrebuiltsBase = "${root}/../../prebuilts"
+databindingProperties.megaRepoDir = "${databindingProperties.externalPrebuiltsBase}/tools/common/m2/repository"
+
+println "local maven repo is ${ext.config.mavenRepoDir}."
+println "local pre-build folder is ${ext.config.prebuildFolder}."
+println "mega-repo folder is ${ext.config.megaRepoDir}."
+
+new File(ext.config.mavenRepoDir).mkdir()
+new File(ext.config.prebuildFolder).mkdir()
+
+def addRemoteRepos = !project.hasProperty('addRemoteRepos') || project.getProperty('addRemoteRepos').equals("true")
+ext.config.addRemoteRepos = addRemoteRepos
+def config = ext.config
+def localRepositories = ["${config.extraPluginsRepoDir}",
+                         "${config.megaRepoDir}",
+                         "${config.mavenRepoDir}",
+                         "${config.externalPrebuiltsBase}/maven_repo/android",
+                         "${config.externalPrebuiltsBase}/gradle-plugin",
+                         "${config.externalPrebuiltsBase}/tools/common/m2/repository"]
+ext.config.localRepositories = localRepositories
+def addRepos(RepositoryHandler handler) {
+    config.localRepositories.each { repo ->
+        handler.maven {
+            url repo
+        }
+    }
+    handler.jcenter()
+    handler.mavenCentral()
+}
+ext.addRepos = this.&addRepos
+subprojects {
+    buildscript {
+        config.localRepositories.each { repo ->
+            repositories.maven {
+                url repo
+            }
+        }
+        repositories {
+            if (config.addRemoteRepos) {
+                jcenter()
+                mavenCentral()
+            }
+        }
+    }
+    repositories {
+        config.localRepositories.each { repo ->
+            repositories.maven {
+                url repo
+            }
+        }
+        if (config.addRemoteRepos) {
+            jcenter()
+            mavenCentral()
+        }
+    }
+}