diff --git a/tools/commons/pom.xml b/tools/commons/pom.xml
new file mode 100755
index 0000000..709d145
--- /dev/null
+++ b/tools/commons/pom.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0"?>
+<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.ekingstar.commons</groupId>
+	<artifactId>commons</artifactId>
+	<version>1.0.0</version>
+	<properties>
+		<mockito.version>1.9.5</mockito.version>
+		<testng.version>6.5.2</testng.version>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<downloadJavadocs>true</downloadJavadocs>
+		<logback.version>1.0.7</logback.version>
+		<slf4j.version>1.6.6</slf4j.version>
+	</properties>
+	<distributionManagement>
+		<repository>
+			<id>ekingstar-releases</id>
+			<name>internal release</name>
+			<url>http://app.supwisdom.com:81/artifactory/libs-release-local</url>
+		</repository>
+		<snapshotRepository>
+			<id>ekingstar-snapshots</id>
+			<name>internal Snapshots</name>
+			<url>http://app.supwisdom.com:81/artifactory/libs-snapshot-local</url>
+		</snapshotRepository>
+		<downloadUrl>http://app.supwisdom.com:81/artifactory</downloadUrl>
+	</distributionManagement>
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.slf4j</groupId>
+				<artifactId>slf4j-api</artifactId>
+				<version>1.6.6</version>
+			</dependency>
+			<dependency>
+				<groupId>ch.qos.logback</groupId>
+				<artifactId>logback-core</artifactId>
+				<version>1.0.7</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>ch.qos.logback</groupId>
+				<artifactId>logback-classic</artifactId>
+				<version>1.0.7</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.mockito</groupId>
+				<artifactId>mockito-all</artifactId>
+				<version>1.9.5</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.testng</groupId>
+				<artifactId>testng</artifactId>
+				<version>6.5.2</version>
+				<scope>test</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+	<dependencies>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.6.6</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.testng</groupId>
+			<artifactId>testng</artifactId>
+			<version>6.5.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-all</artifactId>
+			<version>1.9.5</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-core</artifactId>
+			<version>1.0.7</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-classic</artifactId>
+			<version>1.0.7</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.0</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+					<encoding>UTF-8</encoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>jar-no-fork</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-javadocs</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<!-- explicitly define maven-deploy-plugin after other to force exec 
+					order -->
+				<artifactId>maven-deploy-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>deploy</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>deploy</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+
+</project>
\ No newline at end of file
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/Disposable.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/Disposable.java
new file mode 100644
index 0000000..b12af80
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/Disposable.java
@@ -0,0 +1,37 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean;
+
+/**
+ * <p>
+ * Disposable interface.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface Disposable {
+
+  /**
+   * <p>
+   * destroy.
+   * </p>
+   */
+  void destroy();
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/Initializing.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/Initializing.java
new file mode 100644
index 0000000..65e4a21
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/Initializing.java
@@ -0,0 +1,38 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean;
+
+/**
+ * <p>
+ * Initializing interface.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface Initializing {
+  /**
+   * <p>
+   * init.
+   * </p>
+   * 
+   * @throws java.lang.Exception if any.
+   */
+  void init() throws Exception;
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/PropertyNameResolver.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/PropertyNameResolver.java
new file mode 100644
index 0000000..c059513
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/PropertyNameResolver.java
@@ -0,0 +1,215 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean;
+
+/**
+ * Default Property Name Resolver .
+ * <p>
+ * This class assists in resolving property names in the following four formats, with the layout of
+ * an identifying String in parentheses:
+ * <ul>
+ * <li><strong>Simple (<code>name</code>)</strong> - The specified <code>name</code> identifies an
+ * individual property of a particular JavaBean. The name of the actual getter or setter method to
+ * be used is determined using standard JavaBeans instrospection, a property named "xyz" will have a
+ * getter method named <code>getXyz()</code> or (for boolean properties only) <code>isXyz()</code>,
+ * and a setter method named <code>setXyz()</code>.</li>
+ * <li><strong>Indexed (<code>name[index]</code>)</strong> - The underlying property value is
+ * assumed to be an array. The appropriate (zero-relative) entry in the array is selected. <code>List</code>
+ * objects are now also supported for read/write.</li>
+ * <li><strong>Mapped (<code>name(key)</code>)</strong> - The JavaBean is assumed to have an
+ * property getter and setter methods with an additional attribute of type
+ * <code>java.lang.String</code>.</li>
+ * <li><strong>Nested (<code>name1.name2[index].name3(key)</code>)</strong> - Combining mapped,
+ * nested, and indexed references is also supported.</li>
+ * </ul>
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class PropertyNameResolver {
+
+  private static final char Nested = '.';
+  private static final char MappedStart = '(';
+  private static final char MappedEnd = ')';
+  private static final char IndexedStart = '[';
+  private static final char IndexedEnd = ']';
+
+  /**
+   * Return the index value from the property expression or -1.
+   * 
+   * @param expression The property expression
+   * @return The index value or -1 if the property is not indexed
+   * @throws IllegalArgumentException If the indexed property is illegally
+   *           formed or has an invalid (non-numeric) value.
+   */
+  public int getIndex(String expression) {
+    if (expression == null || expression.length() == 0) { return -1; }
+    for (int i = 0; i < expression.length(); i++) {
+      char c = expression.charAt(i);
+      if (c == Nested || c == MappedStart) {
+        return -1;
+      } else if (c == IndexedStart) {
+        int end = expression.indexOf(IndexedEnd, i);
+        if (end < 0) { throw new IllegalArgumentException("Missing End Delimiter"); }
+        String value = expression.substring(i + 1, end);
+        if (value.length() == 0) { throw new IllegalArgumentException("No Index Value"); }
+        int index = 0;
+        try {
+          index = Integer.parseInt(value, 10);
+        } catch (Exception e) {
+          throw new IllegalArgumentException("Invalid index value '" + value + "'");
+        }
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Return the map key from the property expression or <code>null</code>.
+   * 
+   * @param expression The property expression
+   * @return The index value
+   * @throws IllegalArgumentException If the mapped property is illegally formed.
+   */
+  public String getKey(String expression) {
+    if (expression == null || expression.length() == 0) { return null; }
+    for (int i = 0; i < expression.length(); i++) {
+      char c = expression.charAt(i);
+      if (c == Nested || c == IndexedStart) {
+        return null;
+      } else if (c == MappedStart) {
+        int end = expression.indexOf(MappedEnd, i);
+        if (end < 0) { throw new IllegalArgumentException("Missing End Delimiter"); }
+        return expression.substring(i + 1, end);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return the property name from the property expression.
+   * 
+   * @param expression The property expression
+   * @return The property name
+   */
+  public String getProperty(String expression) {
+    if (expression == null || expression.length() == 0) { return expression; }
+    for (int i = 0; i < expression.length(); i++) {
+      char c = expression.charAt(i);
+      if (c == Nested) {
+        return expression.substring(0, i);
+      } else if (c == MappedStart || c == IndexedStart) { return expression.substring(0, i); }
+    }
+    return expression;
+  }
+
+  /**
+   * Indicates whether or not the expression contains nested property expressions or not.
+   * 
+   * @param expression The property expression
+   * @return The next property expression
+   */
+  public boolean hasNested(String expression) {
+    if (expression == null || expression.length() == 0) return false;
+    else return remove(expression) != null;
+
+  }
+
+  /**
+   * Indicate whether the expression is for an indexed property or not.
+   * 
+   * @param expression The property expression
+   * @return <code>true</code> if the expresion is indexed,
+   *         otherwise <code>false</code>
+   */
+  public boolean isIndexed(String expression) {
+    if (expression == null || expression.length() == 0) { return false; }
+    for (int i = 0; i < expression.length(); i++) {
+      char c = expression.charAt(i);
+      if (c == Nested || c == MappedStart) {
+        return false;
+      } else if (c == IndexedStart) { return true; }
+    }
+    return false;
+  }
+
+  /**
+   * Indicate whether the expression is for a mapped property or not.
+   * 
+   * @param expression The property expression
+   * @return <code>true</code> if the expresion is mapped,
+   *         otherwise <code>false</code>
+   */
+  public boolean isMapped(String expression) {
+    if (expression == null || expression.length() == 0) { return false; }
+    for (int i = 0; i < expression.length(); i++) {
+      char c = expression.charAt(i);
+      if (c == Nested || c == IndexedStart) {
+        return false;
+      } else if (c == MappedStart) { return true; }
+    }
+    return false;
+  }
+
+  /**
+   * Extract the next property expression from the current expression.
+   * 
+   * @param expression The property expression
+   * @return The next property expression
+   */
+  public String next(String expression) {
+    if (expression == null || expression.length() == 0) { return null; }
+    boolean indexed = false;
+    boolean mapped = false;
+    for (int i = 0; i < expression.length(); i++) {
+      char c = expression.charAt(i);
+      if (indexed) {
+        if (c == IndexedEnd) { return expression.substring(0, i + 1); }
+      } else if (mapped) {
+        if (c == MappedEnd) { return expression.substring(0, i + 1); }
+      } else {
+        if (c == Nested) {
+          return expression.substring(0, i);
+        } else if (c == MappedStart) {
+          mapped = true;
+        } else if (c == IndexedStart) {
+          indexed = true;
+        }
+      }
+    }
+    return expression;
+  }
+
+  /**
+   * Remove the last property expresson from the current expression.
+   * 
+   * @param expression The property expression
+   * @return The new expression value, with first property
+   *         expression removed - null if there are no more expressions
+   */
+  public String remove(String expression) {
+    if (expression == null || expression.length() == 0) { return null; }
+    String property = next(expression);
+    if (expression.length() == property.length()) { return null; }
+    int start = property.length();
+    if (expression.charAt(start) == Nested) start++;
+    return expression.substring(start);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/PropertyUtils.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/PropertyUtils.java
new file mode 100644
index 0000000..53f7115
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/PropertyUtils.java
@@ -0,0 +1,251 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean;
+
+import java.lang.reflect.Array;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ekingstar.commons.conversion.Conversion;
+import com.ekingstar.commons.conversion.impl.DefaultConversion;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.lang.Throwables;
+import com.ekingstar.commons.lang.reflect.ClassInfo;
+import com.ekingstar.commons.lang.reflect.MethodInfo;
+
+/**
+ * @author chaostone
+ */
+public class PropertyUtils {
+
+  private static final Logger logger = LoggerFactory.getLogger(PropertyUtils.class);
+
+  private static final PropertyNameResolver resolver = new PropertyNameResolver();
+
+  /**
+   * @throws NoSuchMethodException
+   * @param bean
+   * @param name
+   * @param value
+   */
+  public static void setProperty(Object bean, String name, Object value) {
+    copyProperty(bean, name, value, null);
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> T getProperty(Object bean, String name) {
+    // Resolve nested references
+    while (resolver.hasNested(name)) {
+      String next = resolver.next(name);
+      Object nestedBean = null;
+      if (bean instanceof Map) {
+        nestedBean = getPropertyOfMapBean((Map<?, ?>) bean, next);
+      } else if (resolver.isMapped(next)) {
+        nestedBean = getMappedProperty(bean, next);
+      } else if (resolver.isIndexed(next)) {
+        nestedBean = getIndexedProperty(bean, next);
+      } else {
+        nestedBean = getSimpleProperty(bean, next);
+      }
+      if (nestedBean == null) return null;
+      bean = nestedBean;
+      name = resolver.remove(name);
+    }
+
+    if (bean instanceof Map) {
+      bean = getPropertyOfMapBean((Map<?, ?>) bean, name);
+    } else if (resolver.isMapped(name)) {
+      bean = getMappedProperty(bean, name);
+    } else if (resolver.isIndexed(name)) {
+      bean = getIndexedProperty(bean, name);
+    } else {
+      bean = getSimpleProperty(bean, name);
+    }
+    return (T) bean;
+  }
+
+  @SuppressWarnings({ "unchecked", "rawtypes" })
+  public static Object copyProperty(Object bean, String name, Object value, Conversion conversion) {
+    // Resolve nested references
+    while (resolver.hasNested(name)) {
+      String next = resolver.next(name);
+      Object nestedBean = null;
+      if (bean instanceof Map) {
+        nestedBean = getPropertyOfMapBean((Map) bean, next);
+      } else if (resolver.isMapped(next)) {
+        nestedBean = getMappedProperty(bean, next);
+      } else if (resolver.isIndexed(next)) {
+        nestedBean = getIndexedProperty(bean, next);
+      } else {
+        nestedBean = getSimpleProperty(bean, next);
+      }
+      if (nestedBean == null) { throw new RuntimeException("Null property value for '" + name
+          + "' on bean class '" + bean.getClass() + "'"); }
+      bean = nestedBean;
+      name = resolver.remove(name);
+    }
+
+    if (bean instanceof Map) {
+      setPropertyOfMapBean((Map<Object, Object>) bean, name, value);
+    } else if (resolver.isMapped(name)) {
+      setMappedProperty(bean, name, value);
+    } else if (resolver.isIndexed(name)) {
+      return copyIndexedProperty(bean, name, value, conversion);
+    } else {
+      return copySimpleProperty(bean, name, value, conversion);
+    }
+    return value;
+  }
+
+  public static boolean isWriteable(Object bean, String name) {
+    ClassInfo classInfo = ClassInfo.get(bean.getClass());
+    return null != classInfo.getWriter(name);
+  }
+
+  public static Class<?> getPropertyType(Class<?> clazz, String name) {
+    return ClassInfo.get(clazz).getPropertyType(name);
+  }
+
+  public static Set<String> getWritableProperties(Class<?> clazz) {
+    return ClassInfo.get(clazz).getWritableProperties();
+  }
+
+  private static Object copySimpleProperty(Object bean, String name, Object value, Conversion conversion) {
+    ClassInfo classInfo = ClassInfo.get(bean.getClass());
+    MethodInfo info = classInfo.getWriter(name);
+    if (null == info) {
+      logger.warn("Cannot find set" + Strings.capitalize(name) + " in " + bean.getClass());
+      return null;
+    }
+    Object converted = value;
+    if (null != conversion) converted = conversion.convert(value, classInfo.getPropertyType(name));
+    try {
+      return info.method.invoke(bean, converted);
+    } catch (Exception e) {
+      Throwables.propagate(e);
+    }
+    return converted;
+  }
+
+  @SuppressWarnings("unchecked")
+  private static void setMappedProperty(Object bean, String name, Object value) {
+    // Identify the key of the requested individual property
+    String key = null;
+    try {
+      key = resolver.getKey(name);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("Invalid mapped property '" + name + "' on bean class '"
+          + bean.getClass() + "'");
+    }
+    if (key == null) { throw new IllegalArgumentException("Invalid mapped property '" + name
+        + "' on bean class '" + bean.getClass() + "'"); }
+
+    // Isolate the name
+    name = resolver.getProperty(name);
+    Object rs = bean;
+    if (name != null && name.length() >= 0) rs = getSimpleProperty(bean, name);
+    if (rs instanceof java.util.Map<?, ?>) ((java.util.Map<Object, Object>) rs).put(key, value);
+  }
+
+  private static void setPropertyOfMapBean(Map<Object, Object> bean, String propertyName, Object value) {
+    if (resolver.isMapped(propertyName)) {
+      String name = resolver.getProperty(propertyName);
+      if (name == null || name.length() == 0) {
+        propertyName = resolver.getKey(propertyName);
+      }
+    }
+    if (resolver.isIndexed(propertyName) || resolver.isMapped(propertyName)) { throw new IllegalArgumentException(
+        "Indexed or mapped properties are not supported on" + " objects of type Map: " + propertyName); }
+
+    bean.put(propertyName, value);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static Object copyIndexedProperty(Object bean, String name, Object value, Conversion conversion) {
+    int index = -1;
+    try {
+      index = resolver.getIndex(name);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("Invalid indexed property '" + name + "' on bean class '"
+          + bean.getClass() + "'");
+    }
+    if (index < 0) { throw new IllegalArgumentException("Invalid indexed property '" + name
+        + "' on bean class '" + bean.getClass() + "'"); }
+
+    // Isolate the name
+    name = resolver.getProperty(name);
+    Object rs = bean;
+    if (name != null && name.length() >= 0) rs = getSimpleProperty(bean, name);
+
+    Object converted = value;
+    if (rs.getClass().isArray()) {
+      if (null != conversion) converted = conversion.convert(value, rs.getClass().getComponentType());
+      Array.set(rs, index, value);
+    } else if (rs instanceof List) {
+      ((List<Object>) rs).set(index, value);
+    }
+    return converted;
+  }
+
+  public static Object copyProperty(Object bean, String name, Object value) {
+    return copyProperty(bean,name,value,DefaultConversion.Instance);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static <T> T getSimpleProperty(Object bean, String name) {
+    MethodInfo info = ClassInfo.get(bean.getClass()).getReader(name);
+    if (null == info) {
+      logger.warn("Cannot find get" + Strings.capitalize(name) + " in " + bean.getClass());
+      return null;
+    }
+    try {
+      return (T) info.method.invoke(bean);
+    } catch (Exception e) {
+      throw Throwables.propagate(e);
+    }
+  }
+
+  private static Object getPropertyOfMapBean(Map<?, ?> bean, String propertyName) {
+    String name = resolver.getProperty(propertyName);
+    if (name == null || name.length() == 0) propertyName = resolver.getKey(propertyName);
+    return bean.get(propertyName);
+  }
+
+  private static Object getMappedProperty(Object bean, String name) {
+    String key = resolver.getKey(name);
+    if (key == null) { throw new IllegalArgumentException("Invalid mapped property '" + name + "'"); }
+    Object value = getSimpleProperty(bean, resolver.getProperty(name));
+    if (null == value) return null;
+    return ((Map<?, ?>) value).get(key);
+  }
+
+  private static Object getIndexedProperty(Object bean, String name) {
+    int index = resolver.getIndex(name);
+    if (index < 0) { throw new IllegalArgumentException("Invalid indexed property '" + name + "'"); }
+    Object value = getSimpleProperty(bean, resolver.getProperty(name));
+    if (null == value) return null;
+
+    if (value.getClass().isArray()) return (Array.get(value, index));
+    else return ((List<?>) value).get(index);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/ChainComparator.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/ChainComparator.java
new file mode 100755
index 0000000..f3a9968
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/ChainComparator.java
@@ -0,0 +1,112 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.comparators;
+
+import java.util.Comparator;
+import java.util.List;
+
+import com.ekingstar.commons.collection.CollectUtils;
+
+/**
+ * 组合比较器
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class ChainComparator<T> implements Comparator<T> {
+
+  private List<Comparator<T>> comparators;
+
+  /**
+   * <p>
+   * compare.
+   * </p>
+   * 
+   * @param first a T object.
+   * @param second a T object.
+   * @return 0 is equals,-1 first &lt; second ,1 first &gt; second
+   */
+  public int compare(final T first, final T second) {
+    int cmpRs = 0;
+    for (final Comparator<T> com : comparators) {
+      cmpRs = com.compare(first, second);
+      if (0 == cmpRs) {
+        continue;
+      } else {
+        break;
+      }
+    }
+    return cmpRs;
+  }
+
+  /**
+   * <p>
+   * Constructor for ChainComparator.
+   * </p>
+   */
+  public ChainComparator() {
+    this.comparators = CollectUtils.newArrayList();
+  }
+
+  /**
+   * <p>
+   * Constructor for ChainComparator.
+   * </p>
+   * 
+   * @param comparators a {@link java.util.List} object.
+   */
+  public ChainComparator(final List<Comparator<T>> comparators) {
+    super();
+    this.comparators = comparators;
+  }
+
+  /**
+   * <p>
+   * addComparator.
+   * </p>
+   * 
+   * @param com a {@link java.util.Comparator} object.
+   */
+  public void addComparator(final Comparator<T> com) {
+    this.comparators.add(com);
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>comparators</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<Comparator<T>> getComparators() {
+    return comparators;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>comparators</code>.
+   * </p>
+   * 
+   * @param comparators a {@link java.util.List} object.
+   */
+  public void setComparators(final List<Comparator<T>> comparators) {
+    this.comparators = comparators;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/CollatorStringComparator.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/CollatorStringComparator.java
new file mode 100755
index 0000000..6b3000d
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/CollatorStringComparator.java
@@ -0,0 +1,128 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.comparators;
+
+import java.text.Collator;
+
+/**
+ * <p>
+ * CollatorStringComparator class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class CollatorStringComparator implements StringComparator {
+  private boolean asc;
+
+  private Collator collator;
+
+  /**
+   * <p>
+   * Constructor for CollatorStringComparator.
+   * </p>
+   */
+  public CollatorStringComparator() {
+    super();
+    collator = Collator.getInstance();
+  }
+
+  /**
+   * <p>
+   * Constructor for CollatorStringComparator.
+   * </p>
+   * 
+   * @param asc a boolean.
+   */
+  public CollatorStringComparator(final boolean asc) {
+    this();
+    this.asc = asc;
+  }
+
+  /**
+   * <p>
+   * Constructor for CollatorStringComparator.
+   * </p>
+   * 
+   * @param asc a boolean.
+   * @param collator a {@link java.text.Collator} object.
+   */
+  public CollatorStringComparator(final boolean asc, final Collator collator) {
+    this.collator = collator;
+    this.asc = asc;
+  }
+
+  /**
+   * <p>
+   * compare.
+   * </p>
+   * 
+   * @param what0 a {@link java.lang.String} object.
+   * @param what1 a {@link java.lang.String} object.
+   * @return a int.
+   */
+  public int compare(final String what0, final String what1) {
+    return (asc ? 1 : -1) * (collator.compare((null == what0) ? "" : what0, (null == what1) ? "" : what1));
+  }
+
+  /**
+   * <p>
+   * isAsc.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isAsc() {
+    return asc;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>asc</code>.
+   * </p>
+   * 
+   * @param asc a boolean.
+   */
+  public void setAsc(final boolean asc) {
+    this.asc = asc;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>collator</code>.
+   * </p>
+   * 
+   * @return a {@link java.text.Collator} object.
+   */
+  public Collator getCollator() {
+    return collator;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>collator</code>.
+   * </p>
+   * 
+   * @param collator a {@link java.text.Collator} object.
+   */
+  public void setCollator(final Collator collator) {
+    this.collator = collator;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/CollectionSizeComparator.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/CollectionSizeComparator.java
new file mode 100755
index 0000000..99915a8
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/CollectionSizeComparator.java
@@ -0,0 +1,45 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.comparators;
+
+import java.util.Collection;
+import java.util.Comparator;
+
+/**
+ * 比较两个集合，元素多的大
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class CollectionSizeComparator<T extends Collection<?>> implements Comparator<T> {
+
+  /**
+   * <p>
+   * compare.
+   * </p>
+   * 
+   * @param first a T object.
+   * @param second a T object.
+   * @return equals : 0,first less then second : -1 or small , first greate then second : 1 or big
+   */
+  public int compare(final T first, final T second) {
+    if (first.equals(second)) return 0;
+    else return first.size() - second.size();
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/MultiPropertyComparator.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/MultiPropertyComparator.java
new file mode 100755
index 0000000..5e0f5e3
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/MultiPropertyComparator.java
@@ -0,0 +1,46 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.comparators;
+
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 多个属性的比较
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class MultiPropertyComparator extends ChainComparator<Object> {
+
+  /**
+   * <p>
+   * Constructor for MultiPropertyComparator.
+   * </p>
+   * 
+   * @param propertyStr a {@link java.lang.String} object.
+   */
+  public MultiPropertyComparator(final String propertyStr) {
+    super();
+    final String[] properties = Strings.split(propertyStr, ',');
+    for (int i = 0; i < properties.length; i++) {
+      addComparator(new PropertyComparator(properties[i].trim()));
+    }
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/PropertyComparator.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/PropertyComparator.java
new file mode 100755
index 0000000..1d28289
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/PropertyComparator.java
@@ -0,0 +1,225 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.comparators;
+
+import java.util.Comparator;
+
+import com.ekingstar.commons.bean.PropertyUtils;
+import com.ekingstar.commons.lang.Numbers;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 属性比较器。<br>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class PropertyComparator implements Comparator<Object> {
+
+  private String cmpWhat;
+
+  private int index = -1;
+
+  private boolean asc;
+
+  // 升序情况下，null排在前面，降序情况下，null排在后面。
+  private boolean nullFirst = true;
+
+  @SuppressWarnings("rawtypes")
+  private Comparator comparator;
+
+  private StringComparator stringComparator;
+
+  /**
+   * new OrderedBeanComparator("id") or<br>
+   * new OrderedBeanComparator("name desc"); new
+   * OrderedBeanComparator("[0].name desc");
+   * 
+   * @param cmpStr a {@link java.lang.String} object.
+   */
+  public PropertyComparator(final String cmpStr) {
+    if (Strings.isEmpty(cmpStr)) { return; }
+
+    if (Strings.contains(cmpStr, ',')) { throw new RuntimeException(
+        "PropertyComparator don't suport comma based order by." + " Use MultiPropertyComparator "); }
+    cmpWhat = cmpStr.trim();
+    // 处理带有[]符号的字符串
+    if ('[' == cmpWhat.charAt(0)) {
+      index = Numbers.toInt(Strings.substringBetween(cmpWhat, "[", "]"));
+      cmpWhat = Strings.substringAfter(cmpWhat, "]");
+      if (cmpWhat.length() > 0 && '.' == cmpWhat.charAt(0)) {
+        cmpWhat = cmpWhat.substring(1);
+      }
+    }
+    // 处理排序
+    asc = true;
+    if (Strings.contains(cmpWhat, ' ')) {
+      if (Strings.contains(cmpWhat, " desc")) {
+        asc = false;
+      }
+      cmpWhat = cmpWhat.substring(0, cmpWhat.indexOf(' '));
+    }
+    stringComparator = new CollatorStringComparator(asc);
+  }
+
+  /**
+   * <p>
+   * Constructor for PropertyComparator.
+   * </p>
+   * 
+   * @param cmpWhat a {@link java.lang.String} object.
+   * @param asc a boolean.
+   */
+  public PropertyComparator(final String cmpWhat, final boolean asc) {
+    this(cmpWhat + " " + (asc ? "" : "desc"));
+  }
+
+  /** {@inheritDoc} */
+  @SuppressWarnings("unchecked")
+  public int compare(Object arg0, Object arg1) {
+    Object what0 = null;
+    Object what1 = null;
+    // 取出属性
+    if (index > -1) {
+      arg0 = ((Object[]) arg0)[index];
+      arg1 = ((Object[]) arg1)[index];
+      if (Strings.isEmpty(cmpWhat)) {
+        what0 = arg0;
+        what1 = arg1;
+      }
+    }
+    if (Strings.isNotEmpty(cmpWhat)) {
+      what0 = PropertyUtils.getProperty(arg0, cmpWhat);
+      what1 = PropertyUtils.getProperty(arg1, cmpWhat);
+    }
+
+    if (what0 == null && null == what1) { return 0; }
+
+    // 进行比较
+    if (null == comparator) {
+      if (what0 == null && null != what1) { return asc && nullFirst ? -1 : 1; }
+
+      if (what0 != null && null == what1) { return asc && nullFirst ? 1 : -1; }
+      // 进行字符串比较
+      if (what0 instanceof String || what1 instanceof String) {
+        return stringComparator.compare(what0.toString(), what1.toString());
+      } else {
+        if (asc) {
+          return ((Comparable<Object>) what0).compareTo(what1);
+        } else {
+          return ((Comparable<Object>) what1).compareTo(what0);
+        }
+      }
+    } else {
+      // return doCompare(comparator,what0,what1);
+      return comparator.compare(what0, what1);
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>comparator</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.Comparator} object.
+   */
+  @SuppressWarnings("rawtypes")
+  public Comparator getComparator() {
+    return comparator;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>comparator</code>.
+   * </p>
+   * 
+   * @param comparator a {@link java.util.Comparator} object.
+   */
+  @SuppressWarnings("rawtypes")
+  public void setComparator(final Comparator comparator) {
+    this.comparator = comparator;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>stringComparator</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.bean.comparators.StringComparator} object.
+   */
+  public StringComparator getStringComparator() {
+    return stringComparator;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>stringComparator</code>.
+   * </p>
+   * 
+   * @param stringComparator a {@link com.ekingstar.commons.bean.comparators.StringComparator} object.
+   */
+  public void setStringComparator(final StringComparator stringComparator) {
+    this.stringComparator = stringComparator;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>cmpWhat</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getCmpWhat() {
+    return cmpWhat;
+  }
+
+  /**
+   * <p>
+   * isAsc.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isAsc() {
+    return asc;
+  }
+
+  /**
+   * <p>
+   * isNullFirst.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isNullFirst() {
+    return nullFirst;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>nullFirst</code>.
+   * </p>
+   * 
+   * @param nullFirst a boolean.
+   */
+  public void setNullFirst(boolean nullFirst) {
+    this.nullFirst = nullFirst;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/StringComparator.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/StringComparator.java
new file mode 100755
index 0000000..8fef168
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/comparators/StringComparator.java
@@ -0,0 +1,31 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.comparators;
+
+import java.util.Comparator;
+
+/**
+ * 根据local对两个非空字符串进行比较。
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface StringComparator extends Comparator<String> {
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/package-info.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/package-info.java
new file mode 100644
index 0000000..a08c226
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/package-info.java
@@ -0,0 +1,10 @@
+/**
+ * Commons bean interfaces .Some comparator and converters.
+ * It offers 
+ * <ul>
+ *     <li>Bean lifecyle interface(Initializing,Disposable),it could be integrated with IOC container.
+ *     <li>Comparators,PropertyComparator,ChainComparator etc.
+ *     <li>Converters,Date,Enum to String and vice versa.
+ * </ul>
+ */
+package com.ekingstar.commons.bean;
\ No newline at end of file
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/predicates/PropertyEqualPredicate.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/predicates/PropertyEqualPredicate.java
new file mode 100755
index 0000000..b6dd241
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/predicates/PropertyEqualPredicate.java
@@ -0,0 +1,62 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.predicates;
+
+import com.ekingstar.commons.bean.PropertyUtils;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.Objects;
+import com.ekingstar.commons.lang.functor.Predicate;
+
+/**
+ * Property Equals Predicate
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class PropertyEqualPredicate<T> implements Predicate<T> {
+  private String propertyName;
+  private Object propertyValue;
+
+  /**
+   * <p>
+   * Constructor for PropertyEqualPredicate.
+   * </p>
+   * 
+   * @param propertyName a {@link java.lang.String} object.
+   * @param propertyValue a {@link java.lang.Object} object.
+   */
+  public PropertyEqualPredicate(String propertyName, Object propertyValue) {
+    Assert.notEmpty(propertyName);
+    this.propertyName = propertyName;
+    this.propertyValue = propertyValue;
+  }
+
+  /**
+   * <p>
+   * evaluate.
+   * </p>
+   * 
+   * @param arg0 a {@link java.lang.Object} object.
+   * @return a boolean.
+   */
+  public Boolean apply(T arg0) {
+    return Objects.equals(PropertyUtils.getProperty(arg0, propertyName), propertyValue);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/bean/transformers/PropertyTransformer.java b/tools/commons/src/main/java/com/ekingstar/commons/bean/transformers/PropertyTransformer.java
new file mode 100755
index 0000000..669b951
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/bean/transformers/PropertyTransformer.java
@@ -0,0 +1,82 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.transformers;
+
+import com.ekingstar.commons.bean.PropertyUtils;
+import com.ekingstar.commons.lang.functor.Transformer;
+
+/**
+ * bean属性提取器<br>
+ * CollectionUtils.transform(collections,new PropertyTransformer('myAttr'))
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class PropertyTransformer implements Transformer<Object, Object> {
+
+  private String property;
+
+  /**
+   * <p>
+   * Constructor for PropertyTransformer.
+   * </p>
+   * 
+   * @param property a {@link java.lang.String} object.
+   */
+  public PropertyTransformer(final String property) {
+    super();
+    this.property = property;
+  }
+
+  /**
+   * <p>
+   * Constructor for PropertyTransformer.
+   * </p>
+   */
+  public PropertyTransformer() {
+    super();
+  }
+
+  public Object apply(final Object arg0) {
+    return PropertyUtils.getProperty(arg0, property);
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>property</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getProperty() {
+    return property;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>property</code>.
+   * </p>
+   * 
+   * @param property a {@link java.lang.String} object.
+   */
+  public void setProperty(final String property) {
+    this.property = property;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/collection/CollectUtils.java b/tools/commons/src/main/java/com/ekingstar/commons/collection/CollectUtils.java
new file mode 100755
index 0000000..14ff4c7
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/collection/CollectUtils.java
@@ -0,0 +1,437 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+
+import com.ekingstar.commons.bean.PropertyUtils;
+import com.ekingstar.commons.lang.Throwables;
+import com.ekingstar.commons.lang.functor.Predicate;
+import com.ekingstar.commons.lang.functor.Transformer;
+
+/**
+ * <p>
+ * CollectUtils class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public final class CollectUtils {
+
+  /**
+   * <p>
+   * newArrayList.
+   * </p>
+   * 
+   * @param <E> a E object.
+   * @return a {@link java.util.List} object.
+   */
+  public static <E> List<E> newArrayList() {
+    return new ArrayList<E>();
+  }
+
+  /**
+   * <p>
+   * newArrayList.
+   * </p>
+   * 
+   * @param initialCapacity a int.
+   * @param <E> a E object.
+   * @return a {@link java.util.List} object.
+   */
+  public static <E> List<E> newArrayList(int initialCapacity) {
+    return new ArrayList<E>(initialCapacity);
+  }
+
+  /**
+   * <p>
+   * newArrayList.
+   * </p>
+   * 
+   * @param c a {@link java.util.Collection} object.
+   * @param <E> a E object.
+   * @return a {@link java.util.List} object.
+   */
+  public static <E> List<E> newArrayList(Collection<? extends E> c) {
+    return new ArrayList<E>(c);
+  }
+
+  /**
+   * <p>
+   * newArrayList.
+   * </p>
+   * 
+   * @param values a E object.
+   * @param <E> a E object.
+   * @return a {@link java.util.List} object.
+   */
+  public static <E> List<E> newArrayList(E... values) {
+    List<E> list = new ArrayList<E>(values.length);
+    for (E e : values) {
+      list.add(e);
+    }
+    return list;
+  }
+
+  /**
+   * 将一个集合按照固定大小查分成若干个集合。
+   * 
+   * @param list a {@link java.util.List} object.
+   * @param count a int.
+   * @param <T> a T object.
+   * @return a {@link java.util.List} object.
+   */
+  public static <T> List<List<T>> split(final List<T> list, final int count) {
+    List<List<T>> subIdLists = CollectUtils.newArrayList();
+    if (list.size() < count) {
+      subIdLists.add(list);
+    } else {
+      int i = 0;
+      while (i < list.size()) {
+        int end = i + count;
+        if (end > list.size()) {
+          end = list.size();
+        }
+        subIdLists.add(list.subList(i, end));
+        i += count;
+      }
+    }
+    return subIdLists;
+  }
+
+  /**
+   * <p>
+   * newHashMap.
+   * </p>
+   * 
+   * @param <K> a K object.
+   * @param <V> a V object.
+   * @return a {@link java.util.Map} object.
+   */
+  public static <K, V> Map<K, V> newHashMap() {
+    return new HashMap<K, V>();
+  }
+
+  public static <K, V> FastHashMap<K, V> newFastMap() {
+    return new FastHashMap<K, V>();
+  }
+
+  public static <K, V> FastHashMap<K, V> newFastMap(int capacity) {
+    return new FastHashMap<K, V>(capacity);
+  }
+
+  /**
+   * <p>
+   * newConcurrentHashMap.
+   * </p>
+   * 
+   * @param <K> a K object.
+   * @param <V> a V object.
+   * @return a {@link java.util.Map} object.
+   */
+  public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap() {
+    return new ConcurrentHashMap<K, V>();
+  }
+
+  /**
+   * <p>
+   * newConcurrentLinkedQueue.
+   * </p>
+   * 
+   * @param <E> a E object.
+   * @return a {@link java.util.Queue} object.
+   */
+  public static <E> Queue<E> newConcurrentLinkedQueue() {
+    return new ConcurrentLinkedQueue<E>();
+  }
+
+  /**
+   * <p>
+   * newHashMap.
+   * </p>
+   * 
+   * @param m a {@link java.util.Map} object.
+   * @param <K> a K object.
+   * @param <V> a V object.
+   * @return a {@link java.util.Map} object.
+   */
+  public static <K, V> Map<K, V> newHashMap(Map<? extends K, ? extends V> m) {
+    return new HashMap<K, V>(m);
+  }
+
+  /**
+   * <p>
+   * newLinkedHashMap.
+   * </p>
+   * 
+   * @param m a {@link java.util.Map} object.
+   * @param <K> a K object.
+   * @param <V> a V object.
+   * @return a {@link java.util.Map} object.
+   */
+  public static <K, V> Map<K, V> newLinkedHashMap(Map<? extends K, ? extends V> m) {
+    return new LinkedHashMap<K, V>(m);
+  }
+
+  /**
+   * <p>
+   * newLinkedHashMap.
+   * </p>
+   * 
+   * @param size a int.
+   * @param <K> a K object.
+   * @param <V> a V object.
+   * @return a {@link java.util.Map} object.
+   */
+  public static <K, V> Map<K, V> newLinkedHashMap(int size) {
+    return new LinkedHashMap<K, V>(size);
+  }
+
+  /**
+   * <p>
+   * newHashSet.
+   * </p>
+   * 
+   * @param <E> a E object.
+   * @return a {@link java.util.Set} object.
+   */
+  public static <E> Set<E> newHashSet() {
+    return new HashSet<E>();
+  }
+
+  /**
+   * <p>
+   * newHashSet.
+   * </p>
+   * 
+   * @param values a E object.
+   * @param <E> a E object.
+   * @return a {@link java.util.Set} object.
+   */
+  public static <E> Set<E> newHashSet(E... values) {
+    Set<E> set = new HashSet<E>(values.length);
+    for (E e : values) {
+      set.add(e);
+    }
+    return set;
+  }
+
+  /**
+   * <p>
+   * newHashSet.
+   * </p>
+   * 
+   * @param c a {@link java.util.Collection} object.
+   * @param <E> a E object.
+   * @return a {@link java.util.Set} object.
+   */
+  public static <E> Set<E> newHashSet(Collection<? extends E> c) {
+    return new HashSet<E>(c);
+  }
+
+  /**
+   * <p>
+   * convertToMap.
+   * </p>
+   * 
+   * @param coll a {@link java.util.Collection} object.
+   * @param keyProperty a {@link java.lang.String} object.
+   * @return a {@link java.util.Map} object.
+   */
+  public static Map<?, ?> convertToMap(Collection<?> coll, String keyProperty) {
+    Map<Object, Object> map = newHashMap();
+    for (Object obj : coll) {
+      Object key = null;
+      try {
+        key = PropertyUtils.getProperty(obj, keyProperty);
+      } catch (Exception e) {
+        Throwables.propagate(e);
+      }
+      map.put(key, obj);
+    }
+    return map;
+  }
+
+  /**
+   * <p>
+   * convertToMap.
+   * </p>
+   * 
+   * @param coll a {@link java.util.Collection} object.
+   * @param keyProperty a {@link java.lang.String} object.
+   * @param valueProperty a {@link java.lang.String} object.
+   * @return a {@link java.util.Map} object.
+   */
+  public static Map<?, ?> convertToMap(Collection<?> coll, String keyProperty, String valueProperty) {
+    Map<Object, Object> map = newHashMap();
+    for (Object obj : coll) {
+      Object key = PropertyUtils.getProperty(obj, keyProperty);
+      Object value = PropertyUtils.getProperty(obj, valueProperty);
+      if (null != key) map.put(key, value);
+    }
+    return map;
+  }
+
+  /**
+   * <p>
+   * toMap.
+   * </p>
+   * 
+   * @param wordMappings an array of {@link java.lang.String} objects.
+   * @return a {@link java.util.Map} object.
+   */
+  public static Map<String, String> toMap(String[]... wordMappings) {
+    Map<String, String> mappings = new HashMap<String, String>();
+    for (int i = 0; i < wordMappings.length; i++) {
+      String singular = wordMappings[i][0];
+      String plural = wordMappings[i][1];
+      mappings.put(singular, plural);
+    }
+    return mappings;
+  }
+
+  /**
+   * Null-safe check if the specified collection is empty.
+   * <p>
+   * Null returns true.
+   * 
+   * @param coll the collection to check, may be null
+   * @return true if empty or null
+   * @since 3.1
+   */
+  public static boolean isEmpty(Collection<?> coll) {
+    return (coll == null || coll.isEmpty());
+  }
+
+  /**
+   * Null-safe check if the specified collection is not empty.
+   * <p>
+   * Null returns false.
+   * 
+   * @param coll the collection to check, may be null
+   * @return true if non-null and non-empty
+   * @since 3.1
+   */
+  public static boolean isNotEmpty(Collection<?> coll) {
+    return null != coll && !coll.isEmpty();
+  }
+
+  public static <T> List<T> union(List<T> first, List<T> second) {
+    Map<T, Integer> mapa = getCardinalityMap(first), mapb = getCardinalityMap(second);
+    Set<T> elts = new HashSet<T>(first);
+    elts.addAll(second);
+    List<T> list = newArrayList();
+    for (T obj : elts)
+      for (int i = 0, m = Math.max(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; i++)
+        list.add(obj);
+    return list;
+
+  }
+
+  public static <T> Map<T, Integer> getCardinalityMap(final List<T> coll) {
+    Map<T, Integer> count = newHashMap();
+    for (Iterator<T> it = coll.iterator(); it.hasNext();) {
+      T obj = it.next();
+      Integer c = (count.get(obj));
+      if (c == null) count.put(obj, Integer.valueOf(1));
+      else count.put(obj, new Integer(c.intValue() + 1));
+    }
+    return count;
+  }
+
+  private static final <T> int getFreq(final T obj, final Map<T, Integer> freqMap) {
+    Integer count = freqMap.get(obj);
+    return (count != null) ? count.intValue() : 0;
+  }
+
+  public static <T> List<T> intersection(List<T> first, List<T> second) {
+    List<T> list = CollectUtils.newArrayList();
+    Map<T, Integer> mapa = getCardinalityMap(first), mapb = getCardinalityMap(second);
+    Set<T> elts = new HashSet<T>(first);
+    elts.addAll(second);
+    for (T obj : elts)
+      for (int i = 0, m = Math.min(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; i++)
+        list.add(obj);
+    return list;
+  }
+
+  public static <T> Set<T> intersection(Set<T> first, Set<T> second) {
+    Set<T> elts = CollectUtils.newHashSet();
+    for (T obj : first)
+      if (second.contains(second)) elts.add(obj);
+    return elts;
+  }
+
+  public static <T> List<T> subtract(List<T> first, List<T> second) {
+    List<T> list = newArrayList(first);
+    for (T t : second)
+      list.remove(t);
+    return list;
+  }
+
+  public static <T> Set<T> subtract(final Set<T> a, final Set<T> b) {
+    Set<T> set = CollectUtils.newHashSet(a);
+    set.removeAll(b);
+    return set;
+  }
+
+  public static <T> void filter(Collection<T> datas, Predicate<T> predicate) {
+    for (Iterator<T> it = datas.iterator(); it.hasNext();)
+      if (!predicate.apply(it.next())) it.remove();
+  }
+
+  public static <T> List<T> select(List<T> datas, Predicate<T> predicate) {
+    List<T> rs = CollectUtils.newArrayList();
+    for (T t : datas)
+      if (predicate.apply(t)) rs.add(t);
+    return rs;
+  }
+
+  public static <T> Set<T> select(Set<T> datas, Predicate<T> predicate) {
+    Set<T> rs = CollectUtils.newHashSet();
+    for (T t : datas)
+      if (predicate.apply(t)) rs.add(t);
+    return rs;
+  }
+
+  public static <R> List<R> collect(Collection<?> datas, Transformer<?, ?> transformer) {
+    @SuppressWarnings("unchecked")
+    Transformer<Object, R> objTransformer = (Transformer<Object, R>) transformer;
+    List<R> rs = new ArrayList<R>();
+    for (Object t : datas) {
+      R value = objTransformer.apply(t);
+      rs.add(value);
+    }
+    return rs;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/collection/FastHashMap.java b/tools/commons/src/main/java/com/ekingstar/commons/collection/FastHashMap.java
new file mode 100644
index 0000000..2f8c870
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/collection/FastHashMap.java
@@ -0,0 +1,915 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.collection;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public final class FastHashMap<K, V> implements Map<K, V>, Cloneable, Serializable {
+  private static final long serialVersionUID = -1340573582218930052L;
+
+  /**
+   * Holds the map's hash table.
+   */
+  private transient EntryImpl<K, V>[] _entries;
+
+  /**
+   * Holds the map's current capacity.
+   */
+  private transient int _capacity;
+
+  /**
+   * Holds the hash code mask.
+   */
+  private transient int _mask;
+
+  /**
+   * Holds the first pool entry (linked list).
+   */
+  private transient EntryImpl<K, V> _poolFirst;
+
+  /**
+   * Holds the first map entry (linked list).
+   */
+  private transient EntryImpl<K, V> _mapFirst;
+
+  /**
+   * Holds the last map entry (linked list).
+   */
+  private transient EntryImpl<K, V> _mapLast;
+
+  /**
+   * Holds the current size.
+   */
+  private transient int _size;
+
+  /**
+   * Creates a {@link FastMap} with a capacity of <code>256</code> entries.
+   */
+  public FastHashMap() {
+    initialize(256);
+  }
+
+  /**
+   * Creates a {@link FastMap}, copy of the specified <code>Map</code>.
+   * If the specified map is not an instance of {@link FastMap}, the
+   * newly created map has a capacity set to the specified map's size.
+   * The copy has the same order as the original, regardless of the original
+   * map's implementation:
+   * 
+   * <pre>
+   *     TreeMap dictionary = ...;
+   *     FastMap dictionaryLookup = new FastMap(dictionary);
+   * </pre>
+   * 
+   * @param map the map whose mappings are to be placed in this map.
+   */
+  public FastHashMap(Map<K, V> map) {
+    int capacity = (map instanceof FastHashMap) ? ((FastHashMap<K, V>) map).capacity() : map.size();
+    initialize(capacity);
+    putAll(map);
+  }
+
+  /**
+   * Creates a {@link FastMap} with the specified capacity. Unless the
+   * capacity is exceeded, operations on this map do not allocate entries.
+   * For optimum performance, the capacity should be of the same order
+   * of magnitude or larger than the expected map's size.
+   * 
+   * @param capacity the number of buckets in the hash table; it also
+   *          defines the number of pre-allocated entries.
+   */
+  public FastHashMap(int capacity) {
+    initialize(capacity);
+  }
+
+  /**
+   * Returns the number of key-value mappings in this {@link FastMap}.
+   * 
+   * @return this map's size.
+   */
+  public int size() {
+    return _size;
+  }
+
+  /**
+   * Returns the capacity of this {@link FastMap}. The capacity defines
+   * the number of buckets in the hash table, as well as the maximum number
+   * of entries the map may contain without allocating memory.
+   * 
+   * @return this map's capacity.
+   */
+  public int capacity() {
+    return _capacity;
+  }
+
+  /**
+   * Indicates if this {@link FastMap} contains no key-value mappings.
+   * 
+   * @return <code>true</code> if this map contains no key-value mappings; <code>false</code>
+   *         otherwise.
+   */
+  public boolean isEmpty() {
+    return _size == 0;
+  }
+
+  /**
+   * Indicates if this {@link FastMap} contains a mapping for the specified
+   * key.
+   * 
+   * @param key the key whose presence in this map is to be tested.
+   * @return <code>true</code> if this map contains a mapping for the
+   *         specified key; <code>false</code> otherwise.
+   * @throws NullPointerException if the key is <code>null</code>.
+   */
+  public boolean containsKey(Object key) {
+    EntryImpl<K, V> entry = _entries[keyHash(key) & _mask];
+    while (entry != null) {
+      if (key.equals(entry._key)) { return true; }
+      entry = entry._next;
+    }
+    return false;
+  }
+
+  /**
+   * Indicates if this {@link FastMap} maps one or more keys to the
+   * specified value.
+   * 
+   * @param value the value whose presence in this map is to be tested.
+   * @return <code>true</code> if this map maps one or more keys to the
+   *         specified value.
+   * @throws NullPointerException if the key is <code>null</code>.
+   */
+  public boolean containsValue(Object value) {
+    EntryImpl<K, V> entry = _mapFirst;
+    while (entry != null) {
+      if (value.equals(entry._value)) { return true; }
+      entry = entry._after;
+    }
+    return false;
+  }
+
+  /**
+   * Returns the value to which this {@link FastMap} maps the specified key.
+   * 
+   * @param key the key whose associated value is to be returned.
+   * @return the value to which this map maps the specified key,
+   *         or <code>null</code> if there is no mapping for the key.
+   * @throws NullPointerException if key is <code>null</code>.
+   */
+  public V get(Object key) {
+    EntryImpl<K, V> entry = _entries[keyHash(key) & _mask];
+    while (entry != null) {
+      if (key == entry._key || key.equals(entry._key)) return entry._value;
+      entry = entry._next;
+    }
+    return null;
+  }
+
+  /**
+   * Returns the entry with the specified key.
+   * 
+   * @param key the key whose associated entry is to be returned.
+   * @return the entry for the specified key or <code>null</code> if none.
+   */
+  public Map.Entry<K, V> getEntry(Object key) {
+    EntryImpl<K, V> entry = _entries[keyHash(key) & _mask];
+    while (entry != null) {
+      if (key.equals(entry._key)) { return entry; }
+      entry = entry._next;
+    }
+    return null;
+  }
+
+  /**
+   * Associates the specified value with the specified key in this {@link FastMap}. If the
+   * {@link FastMap} previously contained a mapping
+   * for this key, the old value is replaced.
+   * 
+   * @param key the key with which the specified value is to be associated.
+   * @param value the value to be associated with the specified key.
+   * @return the previous value associated with specified key,
+   *         or <code>null</code> if there was no mapping for key.
+   *         A <code>null</code> return can also indicate that the map
+   *         previously associated <code>null</code> with the specified key.
+   * @throws NullPointerException if the key is <code>null</code>.
+   */
+  public V put(K key, V value) {
+    EntryImpl<K, V> entry = _entries[keyHash(key) & _mask];
+    while (entry != null) {
+      if (key.equals(entry._key)) {
+        V prevValue = entry._value;
+        entry._value = value;
+        return prevValue;
+      }
+      entry = entry._next;
+    }
+    // No previous mapping.
+    addEntry(key, value);
+    return null;
+  }
+
+  /**
+   * Copies all of the mappings from the specified map to this {@link FastMap}.
+   * 
+   * @param map the mappings to be stored in this map.
+   * @throws NullPointerException the specified map is <code>null</code>, or
+   *           the specified map contains <code>null</code> keys.
+   */
+  public void putAll(Map<? extends K, ? extends V> map) {
+    for (Map.Entry<? extends K, ? extends V> e : map.entrySet()) {
+      addEntry(e.getKey(), e.getValue());
+    }
+  }
+
+  /**
+   * Removes the mapping for this key from this {@link FastMap} if present.
+   * 
+   * @param key the key whose mapping is to be removed from the map.
+   * @return previous value associated with specified key,
+   *         or <code>null</code> if there was no mapping for key.
+   *         A <code>null</code> return can also indicate that the map
+   *         previously associated <code>null</code> with the specified key.
+   * @throws NullPointerException if the key is <code>null</code>.
+   */
+  public V remove(Object key) {
+    EntryImpl<K, V> entry = _entries[keyHash(key) & _mask];
+    while (entry != null) {
+      if (key.equals(entry._key)) {
+        V prevValue = entry._value;
+        removeEntry(entry);
+        return prevValue;
+      }
+      entry = entry._next;
+    }
+    return null;
+  }
+
+  /**
+   * Removes all mappings from this {@link FastMap}.
+   */
+  public void clear() {
+    // Clears all keys, values and buckets linked lists.
+    for (EntryImpl<K, V> entry = _mapFirst; entry != null; entry = entry._after) {
+      entry._key = null;
+      entry._value = null;
+      entry._before = null;
+      entry._next = null;
+      if (entry._previous == null) { // First in bucket.
+        _entries[entry._index] = null;
+      } else {
+        entry._previous = null;
+      }
+    }
+
+    // Recycles all entries.
+    if (_mapLast != null) {
+      _mapLast._after = _poolFirst; // Connects to pool.
+      _poolFirst = _mapFirst;
+      _mapFirst = null;
+      _mapLast = null;
+      _size = 0;
+      sizeChanged();
+    }
+  }
+
+  /**
+   * Changes the current capacity of this {@link FastMap}. If the capacity
+   * is increased, new entries are allocated and added to the pool.
+   * If the capacity is decreased, entries from the pool are deallocated
+   * (and are eventually garbage collected). The capacity also determined
+   * the number of buckets for the hash table.
+   * 
+   * @param newCapacity the new capacity of this map.
+   */
+  @SuppressWarnings("unchecked")
+  public void setCapacity(int newCapacity) {
+    if (newCapacity > _capacity) { // Capacity increases.
+      for (int i = _capacity; i < newCapacity; i++) {
+        EntryImpl<K, V> entry = new EntryImpl<K, V>();
+        entry._after = _poolFirst;
+        _poolFirst = entry;
+      }
+    } else if (newCapacity < _capacity) { // Capacity decreases.
+      for (int i = newCapacity; (i < _capacity) && (_poolFirst != null); i++) {
+        // Disconnects the entry for gc to do its work.
+        EntryImpl<K, V> entry = _poolFirst;
+        _poolFirst = entry._after;
+        entry._after = null; // All pointers are now null!
+      }
+    }
+    // Find a power of 2 >= capacity
+    int tableLength = 16;
+    while (tableLength < newCapacity) {
+      tableLength <<= 1;
+    }
+    // Checks if the hash table has to be re-sized.
+    if (_entries.length != tableLength) {
+      _entries = new EntryImpl[tableLength];
+      _mask = tableLength - 1;
+
+      // Repopulates the hash table.
+      EntryImpl<K, V> entry = _mapFirst;
+      while (entry != null) {
+        int index = keyHash(entry._key) & _mask;
+        entry._index = index;
+
+        // Connects to bucket.
+        entry._previous = null; // Resets previous.
+        EntryImpl<K, V> next = _entries[index];
+        entry._next = next;
+        if (next != null) {
+          next._previous = entry;
+        }
+        _entries[index] = entry;
+
+        entry = entry._after;
+      }
+    }
+    _capacity = newCapacity;
+  }
+
+  /**
+   * Returns a shallow copy of this {@link FastMap}. The keys and
+   * the values themselves are not cloned.
+   * 
+   * @return a shallow copy of this map.
+   */
+  @SuppressWarnings("unchecked")
+  public Object clone() {
+    try {
+      FastHashMap<K, V> clone = (FastHashMap<K, V>) super.clone();
+      clone.initialize(_capacity);
+      clone.putAll(this);
+      return clone;
+    } catch (CloneNotSupportedException e) {
+      // Should not happen, since we are Cloneable.
+      throw new InternalError();
+    }
+  }
+
+  /**
+   * Compares the specified object with this {@link FastMap} for equality.
+   * Returns <code>true</code> if the given object is also a map and the two
+   * maps represent the same mappings (regardless of collection iteration
+   * order).
+   * 
+   * @param obj the object to be compared for equality with this map.
+   * @return <code>true</code> if the specified object is equal to this map; <code>false</code>
+   *         otherwise.
+   */
+  public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    } else if (obj instanceof Map) {
+      @SuppressWarnings("unchecked")
+      Map<K, V> that = (Map<K, V>) obj;
+      if (this.size() == that.size()) {
+        EntryImpl<K, V> entry = _mapFirst;
+        while (entry != null) {
+          if (!that.entrySet().contains(entry)) { return false; }
+          entry = entry._after;
+        }
+        return true;
+      } else {
+        return false;
+      }
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Returns the hash code value for this {@link FastMap}.
+   * 
+   * @return the hash code value for this map.
+   */
+  public int hashCode() {
+    int code = 0;
+    EntryImpl<K, V> entry = _mapFirst;
+    while (entry != null) {
+      code += entry.hashCode();
+      entry = entry._after;
+    }
+    return code;
+  }
+
+  /**
+   * Returns a <code>String</code> representation of this {@link FastMap}.
+   * 
+   * @return <code>this.entrySet().toString();</code>
+   */
+  public String toString() {
+    return entrySet().toString();
+  }
+
+  /**
+   * Returns a collection view of the values contained in this {@link FastMap}. The collection is
+   * backed by the map, so changes to
+   * the map are reflected in the collection, and vice-versa.
+   * The collection supports element removal, which removes the corresponding
+   * mapping from this map, via the <code>Iterator.remove</code>, <code>Collection.remove</code>,
+   * <code>removeAll</code>, <code>retainAll</code>,
+   * and <code>clear</code> operations. It does not support the <code>add</code> or
+   * <code>addAll</code> operations.
+   * 
+   * @return a collection view of the values contained in this map.
+   */
+  public Collection<V> values() {
+    return _values;
+  }
+
+  private transient Values _values;
+
+  private class Values extends AbstractCollection<V> {
+    public Iterator<V> iterator() {
+      return new Iterator<V>() {
+        EntryImpl<K, V> after = _mapFirst;
+        EntryImpl<K, V> before;
+
+        public void remove() {
+          removeEntry(before);
+        }
+
+        public boolean hasNext() {
+          return after != null;
+        }
+
+        public V next() {
+          before = after;
+          after = after._after;
+          return before._value;
+        }
+      };
+    }
+
+    public int size() {
+      return _size;
+    }
+
+    public boolean contains(Object o) {
+      return containsValue(o);
+    }
+
+    public void clear() {
+      FastHashMap.this.clear();
+    }
+  }
+
+  /**
+   * Returns a collection view of the mappings contained in this {@link FastMap}. Each element in
+   * the returned collection is a <code>Map.Entry</code>. The collection is backed by the map,
+   * so changes to the map are reflected in the collection, and vice-versa.
+   * The collection supports element removal, which removes the corresponding
+   * mapping from this map, via the <code>Iterator.remove</code>, <code>Collection.remove</code>,
+   * <code>removeAll</code>, <code>retainAll</code>,
+   * and <code>clear</code> operations. It does not support the <code>add</code> or
+   * <code>addAll</code> operations.
+   * 
+   * @return a collection view of the mappings contained in this map.
+   */
+  public Set<Map.Entry<K, V>> entrySet() {
+    return _entrySet;
+  }
+
+  private transient EntrySet _entrySet;
+
+  private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+    public Iterator<Map.Entry<K, V>> iterator() {
+      return new Iterator<Map.Entry<K, V>>() {
+        EntryImpl<K, V> after = _mapFirst;
+        EntryImpl<K, V> before;
+
+        public void remove() {
+          removeEntry(before);
+        }
+
+        public boolean hasNext() {
+          return after != null;
+        }
+
+        public Map.Entry<K, V> next() {
+          before = after;
+          after = after._after;
+          return before;
+        }
+      };
+    }
+
+    public int size() {
+      return _size;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean contains(Object obj) { // Optimization.
+      if (obj instanceof Map.Entry) {
+        Map.Entry<K, V> entry = (Map.Entry<K, V>) obj;
+        Map.Entry<K, V> mapEntry = getEntry(entry.getKey());
+        return entry.equals(mapEntry);
+      } else {
+        return false;
+      }
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean remove(Object obj) { // Optimization.
+      if (obj instanceof Map.Entry) {
+        Map.Entry<K, V> entry = (Map.Entry<K, V>) obj;
+        EntryImpl<K, V> mapEntry = (EntryImpl<K, V>) getEntry(entry.getKey());
+        if ((mapEntry != null) && (entry.getValue()).equals(mapEntry._value)) {
+          removeEntry(mapEntry);
+          return true;
+        }
+      }
+      return false;
+    }
+  }
+
+  /**
+   * Returns a set view of the keys contained in this {@link FastMap}.
+   * The set is backed by the map, so changes to the map are reflected
+   * in the set, and vice-versa. The set supports element removal,
+   * which removes the corresponding mapping from this map, via the <code>Iterator.remove</code>,
+   * <code>Collection.remove</code>, <code>removeAll</code>, <code>retainAll</code>,
+   * and <code>clear</code> operations. It does not support the <code>add</code> or
+   * <code>addAll</code> operations.
+   * 
+   * @return a set view of the keys contained in this map.
+   */
+  public Set<K> keySet() {
+    return _keySet;
+  }
+
+  private transient KeySet _keySet;
+
+  private class KeySet extends AbstractSet<K> {
+    public Iterator<K> iterator() {
+      return new Iterator<K>() {
+        EntryImpl<K, V> after = _mapFirst;
+        EntryImpl<K, V> before;
+
+        public void remove() {
+          removeEntry(before);
+        }
+
+        public boolean hasNext() {
+          return after != null;
+        }
+
+        public K next() {
+          before = after;
+          after = after._after;
+          return before._key;
+        }
+      };
+    }
+
+    public int size() {
+      return _size;
+    }
+
+    public boolean contains(Object obj) { // Optimization.
+      return FastHashMap.this.containsKey(obj);
+    }
+
+    public boolean remove(Object obj) { // Optimization.
+      return FastHashMap.this.remove(obj) != null;
+    }
+
+    public void clear() { // Optimization.
+      FastHashMap.this.clear();
+    }
+  }
+
+  /**
+   * This methods is being called when the size of this {@link FastMap} has changed. The default
+   * behavior is to double the map's capacity
+   * when the map's size reaches the current map's capacity.
+   * Sub-class may override this method to implement custom resizing
+   * policies or to disable automatic resizing. For example:
+   * 
+   * <pre>
+   * Map fixedCapacityMap = new FastMap(256) {
+   *   protected sizeChanged() {
+   *     // Do nothing, automatic resizing disabled.
+   *   }
+   * };
+   * </pre>
+   * 
+   * @see #setCapacity
+   */
+  protected void sizeChanged() {
+    if (size() > capacity()) {
+      setCapacity(capacity() * 2);
+    }
+  }
+
+  /**
+   * Returns the the key's hash code.
+   * 
+   * @param key the key to calculate the hashcode for.
+   * @return the hash code for the specified key.
+   */
+
+  private static final int keyHash(Object key) {
+    return key.hashCode();
+  }
+
+  /**
+   * Adds a new entry for the specified key and value.
+   * 
+   * @param key the entry's key.
+   * @param value the entry's value.
+   */
+  private void addEntry(K key, V value) {
+    EntryImpl<K, V> entry = _poolFirst;
+    if (entry != null) {
+      _poolFirst = entry._after;
+      entry._after = null;
+    } else { // Pool empty.
+      entry = new EntryImpl<K, V>();
+    }
+
+    // Setup entry paramters.
+    entry._key = key;
+    entry._value = value;
+    int index = keyHash(key) & _mask;
+    entry._index = index;
+
+    // Connects to bucket.
+    EntryImpl<K, V> next = _entries[index];
+    entry._next = next;
+    if (next != null) {
+      next._previous = entry;
+    }
+    _entries[index] = entry;
+
+    // Connects to collection.
+    if (_mapLast != null) {
+      entry._before = _mapLast;
+      _mapLast._after = entry;
+    } else {
+      _mapFirst = entry;
+    }
+    _mapLast = entry;
+
+    // Updates size.
+    _size++;
+    sizeChanged();
+  }
+
+  /**
+   * Removes the specified entry from the map.
+   * 
+   * @param entry the entry to be removed.
+   */
+  private void removeEntry(EntryImpl<K, V> entry) {
+
+    // Removes from bucket.
+    EntryImpl<K, V> previous = entry._previous;
+    EntryImpl<K, V> next = entry._next;
+    if (previous != null) {
+      previous._next = next;
+      entry._previous = null;
+    } else { // First in bucket.
+      _entries[entry._index] = next;
+    }
+    if (next != null) {
+      next._previous = previous;
+      entry._next = null;
+    } // Else do nothing, no last pointer.
+
+    // Removes from collection.
+    EntryImpl<K, V> before = entry._before;
+    EntryImpl<K, V> after = entry._after;
+    if (before != null) {
+      before._after = after;
+      entry._before = null;
+    } else { // First in collection.
+      _mapFirst = after;
+    }
+    if (after != null) {
+      after._before = before;
+    } else { // Last in collection.
+      _mapLast = before;
+    }
+
+    // Clears value and key.
+    entry._key = null;
+    entry._value = null;
+
+    // Recycles.
+    entry._after = _poolFirst;
+    _poolFirst = entry;
+
+    // Updates size.
+    _size--;
+    sizeChanged();
+  }
+
+  /**
+   * Initializes this instance for the specified capacity.
+   * Once initialized, operations on this map should not create new objects
+   * (unless the map's size exceeds the specified capacity).
+   * 
+   * @param capacity the initial capacity.
+   */
+  @SuppressWarnings("unchecked")
+  private void initialize(int capacity) {
+    // Find a power of 2 >= capacity
+    int tableLength = 16;
+    while (tableLength < capacity) {
+      tableLength <<= 1;
+    }
+    // Allocates hash table.
+    _entries = new EntryImpl[tableLength];
+    _mask = tableLength - 1;
+    _capacity = capacity;
+    _size = 0;
+    // Allocates views.
+    _values = new Values();
+    _entrySet = new EntrySet();
+    _keySet = new KeySet();
+    // Resets pointers.
+    _poolFirst = null;
+    _mapFirst = null;
+    _mapLast = null;
+    // Allocates entries.
+    for (int i = 0; i < capacity; i++) {
+      EntryImpl<K, V> entry = new EntryImpl<K, V>();
+      entry._after = _poolFirst;
+      _poolFirst = entry;
+    }
+  }
+
+  /**
+   * Requires special handling during de-serialization process.
+   * 
+   * @param stream the object input stream.
+   * @throws IOException if an I/O error occurs.
+   * @throws ClassNotFoundException if the class for the object de-serialized
+   *           is not found.
+   */
+  @SuppressWarnings("unchecked")
+  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+    int capacity = stream.readInt();
+    initialize(capacity);
+    int size = stream.readInt();
+    for (int i = 0; i < size; i++) {
+      addEntry((K) stream.readObject(), (V) stream.readObject());
+    }
+  }
+
+  /**
+   * Requires special handling during serialization process.
+   * 
+   * @param stream the object output stream.
+   * @throws IOException if an I/O error occurs.
+   */
+  private void writeObject(ObjectOutputStream stream) throws IOException {
+    stream.writeInt(_capacity);
+    stream.writeInt(_size);
+    int count = 0;
+    EntryImpl<K, V> entry = _mapFirst;
+    while (entry != null) {
+      stream.writeObject(entry._key);
+      stream.writeObject(entry._value);
+      count++;
+      entry = entry._after;
+    }
+    if (count != _size) { throw new IOException("FastMap Corrupted"); }
+  }
+
+  /**
+   * This class represents a {@link FastMap} entry.
+   */
+  private static final class EntryImpl<K, V> implements Map.Entry<K, V> {
+
+    /**
+     * Holds the entry key (null when in pool).
+     */
+    private K _key;
+
+    /**
+     * Holds the entry value (null when in pool).
+     */
+    private V _value;
+
+    /**
+     * Holds the bucket index (undefined when in pool).
+     */
+    private int _index;
+
+    /**
+     * Holds the previous entry in the same bucket (null when in pool).
+     */
+    private EntryImpl<K, V> _previous;
+
+    /**
+     * Holds the next entry in the same bucket (null when in pool).
+     */
+    private EntryImpl<K, V> _next;
+
+    /**
+     * Holds the entry added before this entry (null when in pool).
+     */
+    private EntryImpl<K, V> _before;
+
+    /**
+     * Holds the entry added after this entry
+     * or the next available entry when in pool.
+     */
+    private EntryImpl<K, V> _after;
+
+    /**
+     * Returns the key for this entry.
+     * 
+     * @return the entry's key.
+     */
+    public K getKey() {
+      return _key;
+    }
+
+    /**
+     * Returns the value for this entry.
+     * 
+     * @return the entry's value.
+     */
+    public V getValue() {
+      return _value;
+    }
+
+    /**
+     * Sets the value for this entry.
+     * 
+     * @param value the new value.
+     * @return the previous value.
+     */
+    public V setValue(V value) {
+      V old = _value;
+      _value = value;
+      return old;
+    }
+
+    /**
+     * Indicates if this entry is considered equals to the specified
+     * entry.
+     * 
+     * @param that the object to test for equality.
+     * @return <code>true<code> if both entry are considered equal;
+     *         <code>false<code> otherwise.
+     */
+    public boolean equals(Object that) {
+      if (that instanceof Map.Entry) {
+        @SuppressWarnings("unchecked")
+        Map.Entry<K, V> entry = (Map.Entry<K, V>) that;
+        return (_key.equals(entry.getKey()))
+            && ((_value != null) ? _value.equals(entry.getValue()) : (entry.getValue() == null));
+      } else {
+        return false;
+      }
+    }
+
+    /**
+     * Returns the hash code for this entry.
+     * 
+     * @return this entry's hash code.
+     */
+    public int hashCode() {
+      return _key.hashCode() ^ ((_value != null) ? _value.hashCode() : 0);
+    }
+
+    /**
+     * Returns the text representation of this entry.
+     * 
+     * @return this entry's textual representation.
+     */
+    public String toString() {
+      return _key + "=" + _value;
+    }
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/collection/MapConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/collection/MapConverter.java
new file mode 100755
index 0000000..7d46f04
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/collection/MapConverter.java
@@ -0,0 +1,333 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.collection;
+
+import java.lang.reflect.Array;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+
+import com.ekingstar.commons.conversion.Conversion;
+import com.ekingstar.commons.conversion.impl.DefaultConversion;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * <p>
+ * MapConverter class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class MapConverter {
+
+  private final Conversion conversion;
+
+  /**
+   * <p>
+   * Constructor for MapConverter.
+   * </p>
+   */
+  public MapConverter() {
+    this(DefaultConversion.Instance);
+  }
+
+  /**
+   * <p>
+   * Constructor for MapConverter.
+   * </p>
+   */
+  public MapConverter(DefaultConversion conversion) {
+    super();
+    this.conversion = conversion;
+  }
+
+  /**
+   * <p>
+   * getAll.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param attr a {@link java.lang.String} object.
+   * @return an array of {@link java.lang.Object} objects.
+   */
+  public Object[] getAll(Map<String, Object> data, String attr) {
+    return (Object[]) data.get(attr);
+  }
+
+  /**
+   * <p>
+   * getAll.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param attr a {@link java.lang.String} object.
+   * @param clazz a {@link java.lang.Class} object.
+   * @param <T> a T object.
+   * @return an array of T objects.
+   */
+  public <T> T[] getAll(Map<String, Object> data, String attr, Class<T> clazz) {
+    return convert((Object[]) data.get(attr), clazz);
+  }
+
+  /**
+   * get parameter named attr
+   * 
+   * @param attr a {@link java.lang.String} object.
+   * @return single value or multivalue joined with comma
+   * @param data a {@link java.util.Map} object.
+   */
+  public String getString(Map<String, Object> data, String attr) {
+    Object value = data.get(attr);
+    if (null == value) { return null; }
+    if (!value.getClass().isArray()) { return value.toString(); }
+    String[] values = (String[]) value;
+    if (values.length == 1) {
+      return values[0];
+    } else {
+      return Strings.join(values, ",");
+    }
+  }
+
+  /**
+   * get parameter named attr
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @return a {@link java.lang.Object} object.
+   */
+  public Object get(Map<String, Object> data, String name) {
+    Object value = data.get(name);
+    if (null == value) return null;
+    if (value.getClass().isArray()) {
+      Object[] values = (Object[]) value;
+      if (values.length == 1) { return values[0]; }
+    }
+    return value;
+  }
+
+  /**
+   * <p>
+   * convert.
+   * </p>
+   * 
+   * @param value a {@link java.lang.Object} object.
+   * @param clazz a {@link java.lang.Class} object.
+   * @param <T> a T object.
+   * @return a T object.
+   */
+  public <T> T convert(Object value, Class<T> clazz) {
+    if (null == value) return null;
+    if (value instanceof String && Strings.isEmpty((String) value)) { return null; }
+    if (value.getClass().isArray()) {
+      Object[] values = (Object[]) value;
+      if (values.length >= 1) {
+        value = values[0];
+      }
+    }
+    return conversion.convert(value, clazz);
+  }
+
+  /**
+   * <p>
+   * convert.
+   * </p>
+   * 
+   * @param datas an array of {@link java.lang.Object} objects.
+   * @param clazz a {@link java.lang.Class} object.
+   * @param <T> a T object.
+   * @return an array of T objects.
+   */
+  public <T> T[] convert(Object[] datas, Class<T> clazz) {
+    if (null == datas) { return null; }
+    @SuppressWarnings("unchecked")
+    T[] newDatas = (T[]) Array.newInstance(clazz, datas.length);
+    for (int i = 0; i < datas.length; i++) {
+      newDatas[i] = convert(datas[i], clazz);
+    }
+    return newDatas;
+  }
+
+  /**
+   * <p>
+   * get.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @param clazz a {@link java.lang.Class} object.
+   * @param <T> a T object.
+   * @return a T object.
+   */
+  public <T> T get(Map<String, Object> data, String name, Class<T> clazz) {
+    return convert(get(data, name), clazz);
+  }
+
+  /**
+   * <p>
+   * getBoolean.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @return a {@link java.lang.Boolean} object.
+   */
+  public Boolean getBoolean(Map<String, Object> data, String name) {
+    return get(data, name, Boolean.class);
+  }
+
+  /**
+   * <p>
+   * getBool.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @return a boolean.
+   */
+  public boolean getBool(Map<String, Object> data, String name) {
+    Boolean value = getBoolean(data, name);
+    return (null == value) ? false : value.booleanValue();
+  }
+
+  /**
+   * <p>
+   * getDate.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @return a {@link java.sql.Date} object.
+   */
+  public java.sql.Date getDate(Map<String, Object> data, String name) {
+    return get(data, name, java.sql.Date.class);
+  }
+
+  /**
+   * <p>
+   * getDateTime.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @return a {@link java.util.Date} object.
+   */
+  public Date getDateTime(Map<String, Object> data, String name) {
+    return get(data, name, Date.class);
+  }
+
+  /**
+   * <p>
+   * getFloat.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @return a {@link java.lang.Float} object.
+   */
+  public Float getFloat(Map<String, Object> data, String name) {
+    return get(data, name, Float.class);
+  }
+
+  /**
+   * <p>
+   * getInteger.
+   * </p>
+   */
+  public Integer getInteger(Map<String, Object> data, String name) {
+    return get(data, name, Integer.class);
+  }
+
+  /**
+   * Get Short.
+   */
+  public Short getShort(Map<String, Object> data, String name) {
+    return get(data, name, Short.class);
+  }
+
+  /**
+   * <p>
+   * getLong.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param name a {@link java.lang.String} object.
+   * @return a {@link java.lang.Long} object.
+   */
+  public Long getLong(Map<String, Object> data, String name) {
+    return get(data, name, Long.class);
+  }
+
+  /**
+   * 返回request中以prefix.开头的参数
+   * 
+   * @param prefix a {@link java.lang.String} object.
+   * @param exclusiveAttrNames
+   *          要排除的属性串
+   * @param data a {@link java.util.Map} object.
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> sub(Map<String, Object> data, String prefix, String exclusiveAttrNames) {
+    return sub(data, prefix, exclusiveAttrNames, true);
+  }
+
+  /**
+   * <p>
+   * sub.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param prefix a {@link java.lang.String} object.
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> sub(Map<String, Object> data, String prefix) {
+    return sub(data, prefix, null, true);
+  }
+
+  /**
+   * <p>
+   * sub.
+   * </p>
+   * 
+   * @param data a {@link java.util.Map} object.
+   * @param prefix a {@link java.lang.String} object.
+   * @param exclusiveAttrNames a {@link java.lang.String} object.
+   * @param stripPrefix a boolean.
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> sub(Map<String, Object> data, String prefix, String exclusiveAttrNames,
+      boolean stripPrefix) {
+    Set<String> excludes = CollectUtils.newHashSet();
+    if (Strings.isNotEmpty(exclusiveAttrNames)) {
+      String[] exclusiveAttrs = Strings.split(exclusiveAttrNames, ",");
+      for (int i = 0; i < exclusiveAttrs.length; i++) {
+        excludes.add(exclusiveAttrs[i]);
+      }
+    }
+    Map<String, Object> newParams = CollectUtils.newHashMap();
+    for (final Map.Entry<String, Object> entry : data.entrySet()) {
+      final String attr = entry.getKey();
+      if ((attr.indexOf(prefix + ".") == 0) && (!excludes.contains(attr))) {
+        newParams.put((stripPrefix ? attr.substring(prefix.length() + 1) : attr), get(data, attr));
+      }
+    }
+    return newParams;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/collection/Order.java b/tools/commons/src/main/java/com/ekingstar/commons/collection/Order.java
new file mode 100755
index 0000000..67b9aed
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/collection/Order.java
@@ -0,0 +1,236 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.collection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 排序
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class Order {
+
+  /** Constant <code>ORDER_STR="orderBy"</code> */
+  public static final String ORDER_STR = "orderBy";
+
+  private String property;
+
+  private boolean ascending;
+
+  private boolean ignoreCase;
+
+  /**
+   * <p>
+   * Constructor for Order.
+   * </p>
+   */
+  public Order() {
+    super();
+  }
+
+  /**
+   * <p>
+   * Constructor for Order.
+   * </p>
+   * 
+   * @param property a {@link java.lang.String} object.
+   * @param ascending a boolean.
+   */
+  public Order(String property, boolean ascending) {
+    this.property = property;
+    this.ascending = ascending;
+  }
+
+  /**
+   * <p>
+   * Constructor for Order.
+   * </p>
+   * 
+   * @param property a {@link java.lang.String} object.
+   */
+  public Order(String property) {
+    if (Strings.contains(property, ",")) { throw new RuntimeException("user parser for multiorder"); }
+    if (Strings.contains(property, " desc")) {
+      this.ascending = false;
+      this.property = Strings.substringBefore(property, " desc");
+    } else {
+      if (Strings.contains(property, " asc")) {
+        this.property = Strings.substringBefore(property, " asc");
+      } else {
+        this.property = property;
+      }
+      this.ascending = true;
+    }
+    this.property = this.property.trim();
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>property</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getProperty() {
+    return property;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>property</code>.
+   * </p>
+   * 
+   * @param property a {@link java.lang.String} object.
+   */
+  public void setProperty(final String property) {
+    this.property = property;
+  }
+
+  /**
+   * <p>
+   * isAscending.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isAscending() {
+    return ascending;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>ascending</code>.
+   * </p>
+   * 
+   * @param ascending a boolean.
+   */
+  public void setAscending(boolean ascending) {
+    this.ascending = ascending;
+  }
+
+  /**
+   * <p>
+   * ignoreCase.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.Order} object.
+   */
+  public Order ignoreCase() {
+    ignoreCase = true;
+    return this;
+  }
+
+  /**
+   * <p>
+   * asc.
+   * </p>
+   * 
+   * @param property a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.commons.collection.Order} object.
+   */
+  public static Order asc(String property) {
+    return new Order(property, true);
+  }
+
+  /**
+   * <p>
+   * desc.
+   * </p>
+   * 
+   * @param property a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.commons.collection.Order} object.
+   */
+  public static Order desc(String property) {
+    return new Order(property, false);
+  }
+
+  /**
+   * <p>
+   * toSortString.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String toSortString(final List<Order> orders) {
+    if (null == orders || orders.isEmpty()) { return ""; }
+    final StringBuilder buf = new StringBuilder("order by ");
+    for (final Order order : orders) {
+      if (order.isAscending()) {
+        buf.append(order.getProperty()).append(',');
+      } else {
+        buf.append(order.getProperty()).append(" desc,");
+      }
+    }
+    return buf.substring(0, buf.length() - 1).toString();
+  }
+
+  /**
+   * <p>
+   * parse.
+   * </p>
+   * 
+   * @param orderString a {@link java.lang.String} object.
+   * @return a {@link java.util.List} object.
+   */
+  public static List<Order> parse(final String orderString) {
+    if (Strings.isBlank(orderString)) {
+      return new ArrayList<Order>();
+    } else {
+      final List<Order> orders = new ArrayList<Order>();
+      final String[] orderStrs = Strings.split(orderString, ',');
+      for (int i = 0; i < orderStrs.length; i++) {
+        String order = orderStrs[i].trim();
+        if (Strings.isBlank(order)) {
+          continue;
+        }
+        order = order.toLowerCase().trim();
+        if (order.endsWith(" desc")) {
+          orders.add(new Order(orderStrs[i].substring(0, order.indexOf(" desc")), false));
+        } else if (order.endsWith(" asc")) {
+          orders.add(new Order(orderStrs[i].substring(0, order.indexOf(" asc")), true));
+        } else {
+          orders.add(new Order(orderStrs[i], true));
+        }
+      }
+      return orders;
+    }
+  }
+
+  /**
+   * <p>
+   * toString.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String toString() {
+    if (ignoreCase) {
+      return "lower(" + getProperty() + ") " + (ascending ? "asc" : "desc");
+    } else {
+      return getProperty() + " " + (ascending ? "asc" : "desc");
+    }
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/Conversion.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/Conversion.java
new file mode 100644
index 0000000..89193e5
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/Conversion.java
@@ -0,0 +1,37 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion;
+
+/**
+ * convert a source to target type.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public interface Conversion {
+
+  /**
+   * Convert to target type.
+   * <ul>
+   * <li>convert null to null;
+   * <li>convert array to array ,when cannot find converter return targetType[0]
+   * </ul>
+   */
+  <T> T convert(Object source, Class<T> targetType);
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/Converter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/Converter.java
new file mode 100644
index 0000000..07c9916
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/Converter.java
@@ -0,0 +1,32 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion;
+
+import com.ekingstar.commons.lang.functor.UnaryFunction;
+
+/**
+ * Convert source to target
+ * 
+ * @author chaostone
+ * @param <S> source
+ * @param <T> target
+ */
+public interface Converter<S, T> extends UnaryFunction<S, T> {
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/ConverterRegistry.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/ConverterRegistry.java
new file mode 100644
index 0000000..8bf6123
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/ConverterRegistry.java
@@ -0,0 +1,31 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion;
+
+/**
+ * Converter Registry.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public interface ConverterRegistry {
+
+  void addConverter(Converter<?, ?> converter);
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/Number2NumberConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/Number2NumberConverter.java
new file mode 100644
index 0000000..99f4704
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/Number2NumberConverter.java
@@ -0,0 +1,93 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.conversion.impl.ConverterFactory;
+
+/**
+ * Number Converter Factory
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class Number2NumberConverter extends ConverterFactory<Number, Number> {
+
+  public Number2NumberConverter() {
+    register(Integer.class, new ShortConverter());
+    register(Integer.class, new IntConverter());
+    register(Long.class, new LongConverter());
+    register(Float.class, new FloatConverter());
+    register(Double.class, new DoubleConverter());
+    register(BigInteger.class, new BigIntegerConverter());
+    register(BigDecimal.class, new BigDecimalConverter());
+  }
+
+  private static class ShortConverter implements Converter<Number, Short> {
+    @Override
+    public Short apply(Number number) {
+      return Short.valueOf(number.shortValue());
+    }
+  }
+
+  private static class IntConverter implements Converter<Number, Integer> {
+    @Override
+    public Integer apply(Number number) {
+      return Integer.valueOf(number.intValue());
+    }
+  }
+
+  private static class LongConverter implements Converter<Number, Long> {
+    @Override
+    public Long apply(Number number) {
+      return Long.valueOf(number.intValue());
+    }
+  }
+
+  private static class FloatConverter implements Converter<Number, Float> {
+    @Override
+    public Float apply(Number number) {
+      return Float.valueOf(number.floatValue());
+    }
+  }
+
+  private static class DoubleConverter implements Converter<Number, Double> {
+    @Override
+    public Double apply(Number number) {
+      return Double.valueOf(number.doubleValue());
+    }
+  }
+
+  private static class BigIntegerConverter implements Converter<Number, BigInteger> {
+    @Override
+    public BigInteger apply(Number number) {
+      return BigInteger.valueOf(number.longValue());
+    }
+  }
+
+  private static class BigDecimalConverter implements Converter<Number, BigDecimal> {
+    @Override
+    public BigDecimal apply(Number number) {
+      return new BigDecimal(number.toString());
+    }
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/Object2StringConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/Object2StringConverter.java
new file mode 100644
index 0000000..be6b19d
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/Object2StringConverter.java
@@ -0,0 +1,40 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * Convert Object to String
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class Object2StringConverter implements Converter<Object, String> {
+
+  @Override
+  public String apply(Object input) {
+    if (input == null) return null;
+    if (input.getClass().isArray()) {
+      return Strings.join((Object[]) input,',');
+    } else return input.toString();
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2BooleanConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2BooleanConverter.java
new file mode 100644
index 0000000..fa9ac46
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2BooleanConverter.java
@@ -0,0 +1,65 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * Convert String to Boolean.
+ * <p>
+ * Convert true,on,yes,Y,1 to Boolean.TRUE.<br>
+ * Convert false,off,no,N,0 to Boolean.FALSE. <br>
+ * Otherwise null.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class String2BooleanConverter implements Converter<String, Boolean> {
+  private static final Set<String> trueValues = new HashSet<String>(4);
+
+  private static final Set<String> falseValues = new HashSet<String>(4);
+
+  static {
+    trueValues.add("true");
+    trueValues.add("on");
+    trueValues.add("yes");
+    trueValues.add("Y");
+    trueValues.add("1");
+
+    falseValues.add("false");
+    falseValues.add("off");
+    falseValues.add("no");
+    falseValues.add("N");
+    falseValues.add("0");
+  }
+
+  @Override
+  public Boolean apply(String input) {
+    if(Strings.isEmpty(input))return null;
+    String value = input.toLowerCase();
+    if (trueValues.contains(value)) return Boolean.TRUE;
+    else if (falseValues.contains(value)) return Boolean.FALSE;
+    return null;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2DateConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2DateConverter.java
new file mode 100755
index 0000000..f54acee
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2DateConverter.java
@@ -0,0 +1,127 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.lang.Numbers;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * <p>
+ * DateConverter class.
+ * </p>
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ * @version $Id: $
+ */
+public class String2DateConverter extends StringConverterFactory<String, Date> {
+
+  public String2DateConverter() {
+    register(Date.class, new DateConverter());
+    register(java.sql.Date.class, new SqlDateConverter());
+  }
+
+  private static class DateConverter implements Converter<String, Date> {
+    @Override
+    public Date apply(String value) {
+      if (Strings.isEmpty((String) value)) { return null; }
+      String dateStr = (String) value;
+      String[] times = Strings.split(dateStr, " ");
+      String[] dateElems = null;
+      if (Strings.contains(times[0], "-")) {
+        dateElems = Strings.split(times[0], "-");
+      } else {
+        dateElems = new String[3];
+        int yearIndex = "yyyy".length();
+        dateElems[0] = Strings.substring(times[0], 0, yearIndex);
+        dateElems[1] = Strings.substring(times[0], yearIndex, yearIndex + 2);
+        dateElems[2] = Strings.substring(times[0], yearIndex + 2, yearIndex + 4);
+      }
+      Calendar gc = GregorianCalendar.getInstance();
+      gc.set(Calendar.YEAR, Numbers.toInt(dateElems[0]));
+      gc.set(Calendar.MONTH, Numbers.toInt(dateElems[1]) - 1);
+      gc.set(Calendar.DAY_OF_MONTH, Numbers.toInt(dateElems[2]));
+      if (times.length > 1 && Strings.isNotBlank(times[1])) {
+        String[] timeElems = Strings.split(times[1], ":");
+        if (timeElems.length > 0) gc.set(Calendar.HOUR_OF_DAY, Numbers.toInt(timeElems[0]));
+        if (timeElems.length > 1) gc.set(Calendar.MINUTE, Numbers.toInt(timeElems[1]));
+        if (timeElems.length > 2) gc.set(Calendar.SECOND, Numbers.toInt(timeElems[2]));
+      }
+      return gc.getTime();
+
+    }
+
+  }
+
+  private static class SqlDateConverter implements Converter<String, java.sql.Date> {
+    @Override
+    public java.sql.Date apply(String input) {
+      // 修复了jdk 1.6_u26 的错误
+      return java.sql.Date.valueOf(normalize(input));
+    }
+
+  }
+
+  /**
+   * <p>
+   * normalize.
+   * </p>
+   * 
+   * @param dateStr a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String normalize(String dateStr) {
+    if (!dateStr.contains("-")) {
+      StringBuilder dateBuf = new StringBuilder(dateStr);
+      dateBuf.insert("yyyyMM".length(), '-');
+      dateBuf.insert("yyyy".length(), '-');
+      return dateBuf.toString();
+    } else {
+      if (dateStr.length() >= 10) return dateStr;
+      else if (dateStr.length() < 8) throw new IllegalArgumentException();
+      else {
+        // try 2009-9-1
+        char[] value = dateStr.toCharArray();
+        int dayIndex = -1;
+        if (value[6] == '-') dayIndex = 7;
+        if (value[7] == '-') dayIndex = 8;
+        if (dayIndex < 0) throw new IllegalArgumentException();
+        StringBuilder sb = new StringBuilder(10);
+
+        // append year-
+        sb.append(value, 0, 5);
+
+        // append month-
+        if (dayIndex - 5 < 3) sb.append('0').append(value, 5, 2);
+        else sb.append(value, 5, 3);
+
+        // append day
+        if (value.length - dayIndex < 2) sb.append('0').append(value, dayIndex, 1);
+        else sb.append(value, dayIndex, 2);
+
+        return sb.toString();
+      }
+    }
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2EnumConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2EnumConverter.java
new file mode 100644
index 0000000..0179fc2
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2EnumConverter.java
@@ -0,0 +1,59 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import com.ekingstar.commons.conversion.Converter;
+
+/**
+ * Convert String to Enumeration.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class String2EnumConverter extends StringConverterFactory<String, Enum<?>> {
+
+  public String2EnumConverter() {
+    super();
+  }
+
+  @SuppressWarnings({ "rawtypes", "unchecked" })
+  @Override
+  public <T extends Enum<?>> Converter<String, T> getConverter(Class<T> targetType) {
+    Converter<String, T> converter = super.getConverter(targetType);
+    if (null == converter) {
+      converter = new EnumConverter(targetType);
+      register(targetType, converter);
+    }
+    return converter;
+  }
+
+  private static class EnumConverter<T extends Enum<T>> implements Converter<String, T> {
+
+    private final Class<T> enumType;
+
+    public EnumConverter(Class<T> enumType) {
+      this.enumType = enumType;
+    }
+
+    @Override
+    public T apply(String input) {
+      return (T) Enum.valueOf(enumType, input);
+    }
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2LocaleConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2LocaleConverter.java
new file mode 100644
index 0000000..3512a58
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2LocaleConverter.java
@@ -0,0 +1,55 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import java.util.Locale;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * Convert String to Locale.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class String2LocaleConverter implements Converter<String, Locale> {
+
+  @Override
+  public Locale apply(String localeStr) {
+    if (Strings.isBlank(localeStr)) return null;
+
+    int index = localeStr.indexOf('_');
+    if (index < 0) return new Locale(localeStr);
+
+    String language = localeStr.substring(0, index);
+    if (index == localeStr.length()) return new Locale(language);
+
+    localeStr = localeStr.substring(index + 1);
+    index = localeStr.indexOf('_');
+    if (index < 0) return new Locale(language, localeStr);
+
+    String country = localeStr.substring(0, index);
+    if (index == localeStr.length()) return new Locale(language, country);
+
+    localeStr = localeStr.substring(index + 1);
+    return new Locale(language, country, localeStr);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2NumberConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2NumberConverter.java
new file mode 100644
index 0000000..9b47dfc
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/String2NumberConverter.java
@@ -0,0 +1,121 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import com.ekingstar.commons.conversion.Converter;
+
+/**
+ * Convert string to number.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class String2NumberConverter extends StringConverterFactory<String, Number> {
+
+  public String2NumberConverter() {
+    register(Short.class, new ShortConverter());
+    register(Integer.class, new IntConverter());
+    register(Long.class, new LongConverter());
+    register(Float.class, new FloatConverter());
+    register(Double.class, new DoubleConverter());
+    register(BigInteger.class, new BigIntegerConverter());
+    register(BigDecimal.class, new BigDecimalConverter());
+  }
+
+  private static class ShortConverter implements Converter<String, Short> {
+    @Override
+    public Short apply(String string) {
+      try {
+        return Short.valueOf(string);
+      } catch (NumberFormatException e) {
+        return null;
+      }
+    }
+  }
+
+  private static class IntConverter implements Converter<String, Integer> {
+    @Override
+    public Integer apply(String string) {
+      try {
+        return Integer.valueOf(string);
+      } catch (NumberFormatException e) {
+        return null;
+      }
+    }
+  }
+
+  private static class LongConverter implements Converter<String, Long> {
+    @Override
+    public Long apply(String string) {
+      try {
+        return Long.valueOf(string);
+      } catch (NumberFormatException e) {
+        return null;
+      }
+    }
+  }
+
+  private static class FloatConverter implements Converter<String, Float> {
+    @Override
+    public Float apply(String string) {
+      try {
+        return Float.valueOf(string);
+      } catch (NumberFormatException e) {
+        return null;
+      }
+    }
+  }
+
+  private static class DoubleConverter implements Converter<String, Double> {
+    @Override
+    public Double apply(String string) {
+      try {
+        return Double.valueOf(string);
+      } catch (NumberFormatException e) {
+        return null;
+      }
+    }
+  }
+
+  private static class BigIntegerConverter implements Converter<String, BigInteger> {
+    @Override
+    public BigInteger apply(String string) {
+      try {
+        return new BigInteger(string);
+      } catch (NumberFormatException e) {
+        return null;
+      }
+    }
+  }
+
+  private static class BigDecimalConverter implements Converter<String, BigDecimal> {
+    @Override
+    public BigDecimal apply(String string) {
+      try {
+        return new BigDecimal(string);
+      } catch (NumberFormatException e) {
+        return null;
+      }
+    }
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/StringConverterFactory.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/StringConverterFactory.java
new file mode 100644
index 0000000..5a865d2
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/converter/StringConverterFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import com.ekingstar.commons.conversion.impl.ConverterFactory;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * String to Object
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class StringConverterFactory<S, R> extends ConverterFactory<S, R> {
+
+  @Override
+  public Object convert(Object input, Class<?> sourceType, Class<?> targetType) {
+    if (Strings.isEmpty((String) input)) return null;
+    return super.convert(input, sourceType, targetType);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/AbstractGenericConversion.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/AbstractGenericConversion.java
new file mode 100644
index 0000000..710bb0a
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/AbstractGenericConversion.java
@@ -0,0 +1,192 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.impl;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.conversion.Conversion;
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.conversion.ConverterRegistry;
+import com.ekingstar.commons.lang.Objects;
+import com.ekingstar.commons.lang.Primitives;
+import com.ekingstar.commons.lang.tuple.Pair;
+
+/**
+ * Generic Conversion Super class
+ * It provider converter registry and converter search machanism.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public abstract class AbstractGenericConversion implements Conversion, ConverterRegistry {
+
+  Map<Class<?>, Map<Class<?>, GenericConverter>> converters = CollectUtils.newHashMap();
+
+  Map<Pair<Class<?>, Class<?>>, GenericConverter> cache = CollectUtils.newConcurrentHashMap();
+
+  protected void addConverter(GenericConverter converter) {
+    Pair<?, ?> key = converter.getTypeinfo();
+    getOrCreateConverters((Class<?>) key.getLeft()).put((Class<?>) key.getRight(), converter);
+    cache.clear();
+  }
+
+  @Override
+  public void addConverter(Converter<?, ?> converter) {
+    Pair<Class<?>, Class<?>> key = null;
+    Pair<Class<Object>, Class<Object>> defaultKey = Pair.of(Object.class, Object.class);
+    for (Method m : converter.getClass().getMethods()) {
+      if (m.getName().equals("apply") && Modifier.isPublic(m.getModifiers())) {
+        key = Pair.<Class<?>, Class<?>> of(m.getParameterTypes()[0], m.getReturnType());
+        if (!key.equals(defaultKey)) break;
+      }
+    }
+    if (null == key) throw new IllegalArgumentException("Cannot find convert type pair "
+        + converter.getClass());
+
+    getOrCreateConverters((Class<?>) key.getLeft()).put((Class<?>) key.getRight(),
+        new ConverterAdapter(converter, key));
+    cache.clear();
+  }
+
+  private Map<Class<?>, GenericConverter> getOrCreateConverters(Class<?> sourceType) {
+    Map<Class<?>, GenericConverter> exists = converters.get(sourceType);
+    if (null == exists) {
+      exists = CollectUtils.newHashMap();
+      converters.put(sourceType, exists);
+    }
+    return exists;
+  }
+
+  private Map<Class<?>, GenericConverter> getConverters(Class<?> sourceType) {
+    Map<Class<?>, GenericConverter> exists = converters.get(sourceType);
+    if (null == exists) return Collections.emptyMap();
+    else return exists;
+  }
+
+  private GenericConverter getConverter(Class<?> targetType, Map<Class<?>, GenericConverter> converters) {
+    Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
+    LinkedList<Class<?>> queue = new LinkedList<Class<?>>();
+    queue.addFirst(targetType);
+    while (!queue.isEmpty()) {
+      Class<?> cur = queue.removeLast();
+      GenericConverter converter = converters.get(cur);
+      if (converter != null) return converter;
+
+      Class<?> superClass = cur.getSuperclass();
+      if (superClass != null && superClass != Object.class) queue.addFirst(superClass);
+
+      for (Class<?> interfaceType : cur.getInterfaces())
+        addInterfaces(interfaceType, interfaces);
+    }
+
+    for (Class<?> interfaceType : interfaces) {
+      GenericConverter converter = converters.get(interfaceType);
+      if (converter != null) return converter;
+    }
+
+    return null;
+  }
+
+  private void addInterfaces(Class<?> interfaceType, Set<Class<?>> interfaces) {
+    interfaces.add(interfaceType);
+    for (Class<?> inheritedInterface : interfaceType.getInterfaces())
+      addInterfaces(inheritedInterface, interfaces);
+  }
+
+  @SuppressWarnings("unchecked")
+  protected GenericConverter findConverter(Class<?> sourceType, Class<?> targetType) {
+    // Get cache
+    Pair<?, ?> key = Pair.of(sourceType, targetType);
+    GenericConverter converter = cache.get(key);
+    if (null == converter) converter = searchConverter(sourceType, targetType);
+    else return converter;
+
+    if (null == converter) converter = NoneConverter.Instance;
+    else cache.put((Pair<Class<?>, Class<?>>) key, converter);
+    return converter;
+  }
+
+  protected GenericConverter searchConverter(Class<?> sourceType, Class<?> targetType) {
+    HashSet<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
+    LinkedList<Class<?>> classQueue = new LinkedList<Class<?>>();
+    classQueue.addFirst(sourceType);
+    // Search Class hierarchy
+    while (!classQueue.isEmpty()) {
+      Class<?> currentClass = classQueue.removeLast();
+      GenericConverter converter = getConverter(targetType, getConverters(currentClass));
+      if (converter != null) return converter;
+
+      Class<?> superClass = currentClass.getSuperclass();
+      if (superClass != null && superClass != Object.class) classQueue.addFirst(superClass);
+
+      for (Class<?> interfaceType : currentClass.getInterfaces())
+        addInterfaces(interfaceType, interfaces);
+    }
+    // Search interface
+    for (Class<?> interfaceType : interfaces) {
+      GenericConverter converter = getConverter(targetType, getConverters(interfaceType));
+      if (converter != null) return converter;
+    }
+    return getConverter(targetType, getConverters(Object.class));
+  }
+
+  /**
+   * Convert to target type.
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> T convert(Object source, Class<T> targetType) {
+    if (null == source) return (T) Objects.defaultValue(targetType);
+
+    Class<?> sourceType = Primitives.wrap(source.getClass());
+    Class<?> targetClazz = Primitives.wrap(targetType);
+
+    if (targetClazz.isAssignableFrom(sourceType)) return (T) source;
+
+    if (sourceType.isArray() && targetClazz.isArray()) {
+      Class<?> sourceObjType = Primitives.wrap(sourceType.getComponentType());
+      Class<?> targetObjType = Primitives.wrap(targetClazz.getComponentType());
+      GenericConverter converter = findConverter(sourceObjType, targetObjType);
+      if (null == converter) return (T) Array.newInstance(targetClazz.getComponentType(), 0);
+      else {
+        int length = Array.getLength(source);
+        T result = (T) Array.newInstance(targetClazz.getComponentType(), length);
+        for (int i = 0; i < length; i++)
+          Array.set(result, i, converter.convert(Array.get(source, i), sourceObjType, targetObjType));
+        return result;
+      }
+    } else {
+      Object rs = null;
+      GenericConverter converter = findConverter(sourceType, targetClazz);
+      if (null != converter) rs = converter.convert(source, sourceType, targetClazz);
+      if (null == rs && targetType.isPrimitive()) rs = Objects.defaultValue(targetType);
+      return (T) rs;
+    }
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConvertUtils.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConvertUtils.java
new file mode 100644
index 0000000..72a9c7d
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConvertUtils.java
@@ -0,0 +1,26 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.impl;
+
+public final class ConvertUtils {
+
+  public static final <T> T convert(Object value, Class<T> targetType) {
+    return DefaultConversion.Instance.convert(value, targetType);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConverterAdapter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConverterAdapter.java
new file mode 100644
index 0000000..10dadb7
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConverterAdapter.java
@@ -0,0 +1,53 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.impl;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.lang.tuple.Pair;
+
+/**
+ * Adapte a Converter to GenericConverter
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class ConverterAdapter implements GenericConverter {
+
+  final Converter<Object, Object> converter;
+
+  final Pair<Class<?>, Class<?>> typeinfo;
+
+  @SuppressWarnings("unchecked")
+  public ConverterAdapter(Converter<?, ?> converter, Pair<Class<?>, Class<?>> typeinfo) {
+    super();
+    this.converter = (Converter<Object, Object>) converter;
+    this.typeinfo = typeinfo;
+  }
+
+  @Override
+  public Object convert(Object input, Class<?> sourceType, Class<?> targetType) {
+    return converter.apply(input);
+  }
+
+  @Override
+  public Pair<Class<?>, Class<?>> getTypeinfo() {
+    return typeinfo;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConverterFactory.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConverterFactory.java
new file mode 100644
index 0000000..9bcfbc4
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/ConverterFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.impl;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.lang.tuple.Pair;
+
+/**
+ * A converter factory that can convert objects from S to subtypes of R.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ * @param <S>
+ * @param <R> The target base
+ */
+public abstract class ConverterFactory<S, R> implements GenericConverter {
+  protected Map<Class<?>, Converter<S, ? extends R>> converters = CollectUtils.newHashMap();
+
+  /**
+   * Return convert from S to T
+   */
+  @SuppressWarnings("unchecked")
+  public <T extends R> Converter<S, T> getConverter(Class<T> targetType) {
+    return (Converter<S, T>) converters.get(targetType);
+  }
+
+  private Class<?> classof(Type type) {
+    if (type instanceof Class<?>) {
+      return (Class<?>) type;
+    } else if (type instanceof ParameterizedType) { return (Class<?>) ((ParameterizedType) type).getRawType(); }
+    return null;
+  }
+
+  @Override
+  public Pair<Class<?>, Class<?>> getTypeinfo() {
+    Type superType = getClass().getGenericSuperclass();
+    if ((superType instanceof ParameterizedType)) {
+      ParameterizedType ptype = (ParameterizedType) superType;
+      return Pair.<Class<?>, Class<?>> of(classof(ptype.getActualTypeArguments()[0]),
+          classof(ptype.getActualTypeArguments()[1]));
+    } else {
+      throw new RuntimeException("Cannot identify type of " + getClass());
+    }
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  public Object convert(Object input, Class<?> sourceType, Class<?> targetType) {
+    Converter<S, R> converter = getConverter((Class<R>) targetType);
+    return (null == converter) ? null : converter.apply((S) input);
+  }
+
+  protected void register(Class<?> targetType, Converter<S, ? extends R> converter) {
+    converters.put(targetType, converter);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/DefaultConversion.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/DefaultConversion.java
new file mode 100644
index 0000000..0d131f6
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/DefaultConversion.java
@@ -0,0 +1,57 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.impl;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.conversion.converter.Number2NumberConverter;
+import com.ekingstar.commons.conversion.converter.Object2StringConverter;
+import com.ekingstar.commons.conversion.converter.String2BooleanConverter;
+import com.ekingstar.commons.conversion.converter.String2DateConverter;
+import com.ekingstar.commons.conversion.converter.String2EnumConverter;
+import com.ekingstar.commons.conversion.converter.String2LocaleConverter;
+import com.ekingstar.commons.conversion.converter.String2NumberConverter;
+
+/**
+ * Default Conversion implementation.
+ * <p>
+ * It register String to Boolean/Number/Date/Locale, Number to Number and Object to String buildin
+ * converters.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class DefaultConversion extends AbstractGenericConversion {
+
+  static final public DefaultConversion Instance = new DefaultConversion();
+
+  public DefaultConversion() {
+    addConverter(new String2BooleanConverter());
+    addConverter(new String2NumberConverter());
+    addConverter(new String2DateConverter());
+    addConverter(new String2EnumConverter());
+    addConverter(new String2LocaleConverter());
+    addConverter(new Number2NumberConverter());
+    addConverter(new Object2StringConverter());
+  }
+
+  public DefaultConversion(Converter<?, ?>... converters) {
+    for (Converter<?, ?> converter : converters)
+      addConverter(converter);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/GenericConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/GenericConverter.java
new file mode 100644
index 0000000..a7f3bba
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/GenericConverter.java
@@ -0,0 +1,36 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.impl;
+
+import com.ekingstar.commons.lang.tuple.Pair;
+
+/**
+ * Generic Converter using in DefaultConversion
+ * <p>
+ * It's a SPI interface.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public interface GenericConverter {
+
+  Pair<Class<?>, Class<?>> getTypeinfo();
+
+  Object convert(Object input, Class<?> sourceType, Class<?> targetType);
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/NoneConverter.java b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/NoneConverter.java
new file mode 100644
index 0000000..1af26a6
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/conversion/impl/NoneConverter.java
@@ -0,0 +1,43 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.impl;
+
+import com.ekingstar.commons.lang.tuple.Pair;
+
+/**
+ * Convert anything to null.
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public class NoneConverter implements GenericConverter {
+
+  public final static NoneConverter Instance = new NoneConverter();
+
+  @Override
+  public Object convert(Object input, Class<?> sourceType, Class<?> targetType) {
+    return null;
+  }
+
+  @Override
+  public Pair<Class<?>, Class<?>> getTypeinfo() {
+    return Pair.<Class<?>, Class<?>> of(Object.class, Object.class);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/io/Files.java b/tools/commons/src/main/java/com/ekingstar/commons/io/Files.java
new file mode 100644
index 0000000..cac833c
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/io/Files.java
@@ -0,0 +1,236 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+import java.util.List;
+
+import com.ekingstar.commons.lang.Assert;
+
+/**
+ * File Operation Utility
+ * 
+ * @author chaostone
+ * @since 3.1
+ */
+public class Files {
+
+  public static final long CopyBufferSize = 1024 * 1024 * 30;// 30MB
+
+  /**
+   * Reads the contents of a file into a String using the default encoding for the VM.
+   * The file is always closed.
+   */
+  public static String readFileToString(File file) throws IOException {
+    return readFileToString(file, null);
+  }
+
+  /**
+   * Reads the contents of a file into a String.
+   * The file is always closed.
+   */
+  public static String readFileToString(File file, Charset charset) throws IOException {
+    InputStream in = null;
+    try {
+      in = new FileInputStream(file);
+      StringBuilderWriter sw = new StringBuilderWriter();
+
+      if (null == charset) IOs.copy(new InputStreamReader(in), sw);
+      else IOs.copy(new InputStreamReader(in, charset.name()), sw);
+
+      return sw.toString();
+    } finally {
+      IOs.close(in);
+    }
+  }
+
+  /**
+   * Reads the contents of a file line by line to a List of Strings.
+   * The file is always closed.
+   */
+  public static List<String> readLines(File file, Charset charset) throws IOException {
+    InputStream in = null;
+    try {
+      in = new FileInputStream(file);
+      if (null == charset) {
+        return IOs.readLines(new InputStreamReader(in));
+      } else {
+        InputStreamReader reader = new InputStreamReader(in, charset.name());
+        return IOs.readLines(reader);
+      }
+    } finally {
+      IOs.close(in);
+    }
+  }
+
+  public static List<String> readLines(File file) throws IOException {
+    return readLines(file, null);
+  }
+
+  /**
+   * Copies a file to a new location preserving the file date.
+   * <p>
+   * This method copies the contents of the specified source file to the specified destination file.
+   * The directory holding the destination file is created if it does not exist. If the destination
+   * file exists, then this method will overwrite it.
+   * <p>
+   * <strong>Note:</strong> This method tries to preserve the file's last modified date/times using
+   * {@link File#setLastModified(long)}, however it is not guaranteed that the operation will
+   * succeed. If the modification operation fails, no indication is provided.
+   * 
+   * @param srcFile an existing file to copy, must not be <code>null</code>
+   * @param destFile the new file, must not be <code>null</code>
+   * @throws NullPointerException if source or destination is <code>null</code>
+   * @throws IOException if source or destination is invalid
+   * @throws IOException if an IO error occurs during copying
+   * @see #copyFileToDirectory(File, File)
+   */
+  public static void copyFile(File srcFile, File destFile) throws IOException {
+    Assert.isTrue(null != srcFile, "Source must not be null");
+    Assert.isTrue(null != destFile, "Destination must not be null");
+    if (srcFile.exists() == false) { throw new FileNotFoundException("Source '" + srcFile
+        + "' does not exist"); }
+    if (srcFile.isDirectory()) { throw new IOException("Source '" + srcFile + "' exists but is a directory"); }
+    if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) { throw new IOException("Source '"
+        + srcFile + "' and destination '" + destFile + "' are the same"); }
+    File parentFile = destFile.getParentFile();
+    if (parentFile != null) {
+      if (!parentFile.mkdirs() && !parentFile.isDirectory()) { throw new IOException("Destination '"
+          + parentFile + "' directory cannot be created"); }
+    }
+    if (destFile.exists()) {
+      if (destFile.isDirectory()) { throw new IOException("Destination '" + destFile
+          + "' exists but is a directory"); }
+      if (!destFile.canWrite()) throw new IOException("Destination '" + destFile
+          + "' exists but is read-only");
+    }
+    doCopyFile(srcFile, destFile, true);
+  }
+
+  private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
+    FileInputStream fis = null;
+    FileOutputStream fos = null;
+    FileChannel input = null;
+    FileChannel output = null;
+    try {
+      fis = new FileInputStream(srcFile);
+      fos = new FileOutputStream(destFile);
+      input = fis.getChannel();
+      output = fos.getChannel();
+      long size = input.size();
+      long pos = 0;
+      long count = 0;
+      while (pos < size) {
+        count = size - pos > CopyBufferSize ? CopyBufferSize : size - pos;
+        pos += output.transferFrom(input, pos, count);
+      }
+    } finally {
+      IOs.close(output);
+      IOs.close(fos);
+      IOs.close(input);
+      IOs.close(fis);
+    }
+
+    if (srcFile.length() != destFile.length()) { throw new IOException("Failed to copy full contents from '"
+        + srcFile + "' to '" + destFile + "'"); }
+    if (preserveFileDate) {
+      destFile.setLastModified(srcFile.lastModified());
+    }
+  }
+
+  public static void deleteDirectory(File directory) throws IOException {
+    if (!directory.exists()) return;
+    if (!isSymlink(directory)) cleanDirectory(directory);
+    if (!directory.delete()) throw new IOException("Unable to delete directory " + directory + ".");
+  }
+
+  public static void cleanDirectory(File directory) throws IOException {
+    if (!directory.exists()) throw new IllegalArgumentException(directory + " does not exist");
+    if (!directory.isDirectory()) throw new IllegalArgumentException(directory + " is not a directory");
+
+    File[] files = directory.listFiles();
+    if (files == null) { // null if security restricted
+      throw new IOException("Failed to list contents of " + directory);
+    }
+    IOException exception = null;
+    for (File file : files) {
+      try {
+        forceDelete(file);
+      } catch (IOException ioe) {
+        exception = ioe;
+      }
+    }
+    if (null != exception) throw exception;
+  }
+
+  public static void forceDelete(File file) throws IOException {
+    if (file.isDirectory()) {
+      deleteDirectory(file);
+    } else {
+      if (file.exists()) {
+        if (!file.delete()) throw new IOException("Unable to delete file: " + file);
+      }
+    }
+  }
+
+  public static boolean isSymlink(File file) throws IOException {
+    if (file == null) throw new NullPointerException("File must not be null");
+    // windows
+    if (File.separatorChar == '\\') { return false; }
+    File fileInCanonicalDir = null;
+    if (file.getParent() == null) {
+      fileInCanonicalDir = file;
+    } else {
+      File canonicalDir = file.getParentFile().getCanonicalFile();
+      fileInCanonicalDir = new File(canonicalDir, file.getName());
+    }
+
+    if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile())) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  public static void writeStringToFile(File file, String data, Charset charset) throws IOException {
+    writeStringToFile(file, data, charset, false);
+  }
+
+  public static void writeStringToFile(File file, String data, Charset charset, boolean append)
+      throws IOException {
+    OutputStream out = null;
+    try {
+      out = new FileOutputStream(file, append);
+      IOs.write(data, out, charset);
+      out.close();
+    } finally {
+      IOs.close(out);
+    }
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/io/IOs.java b/tools/commons/src/main/java/com/ekingstar/commons/io/IOs.java
new file mode 100644
index 0000000..351eb0f
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/io/IOs.java
@@ -0,0 +1,133 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.io;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple IO Utility
+ * 
+ * @author chaostone
+ * @since 3.1
+ */
+public class IOs {
+  private static final int DefaultBufferSize = 1024 * 4;
+  private static final int Eof = -1;
+
+  /**
+   * Copy bytes from a <code>InputStream</code> to an <code>OutputStream</code>.
+   * 
+   * @param input the <code>InputStream</code> to read from
+   * @param output the <code>OutputStream</code> to write to
+   * @return the number of bytes copied
+   * @throws NullPointerException if the input or output is null
+   * @throws IOException if an I/O error occurs
+   * @since 3.1
+   */
+  public static long copy(InputStream input, OutputStream output) throws IOException {
+    byte[] buffer = new byte[DefaultBufferSize];
+    long count = 0;
+    int n = 0;
+    while (Eof != (n = input.read(buffer))) {
+      output.write(buffer, 0, n);
+      count += n;
+    }
+    return count;
+  }
+
+  /**
+   * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
+   * 
+   * @param input the <code>Reader</code> to read from
+   * @param output the <code>Writer</code> to write to
+   * @return the number of characters copied
+   * @throws NullPointerException if the input or output is null
+   * @throws IOException if an I/O error occurs
+   * @since 3.1
+   */
+  public static long copy(Reader input, Writer output) throws IOException {
+    char[] buffer = new char[DefaultBufferSize];
+    long count = 0;
+    int n = 0;
+    while (Eof != (n = input.read(buffer))) {
+      output.write(buffer, 0, n);
+      count += n;
+    }
+    return count;
+  }
+
+  /**
+   * Get the contents of a <code>Reader</code> as a list of Strings,
+   * one entry per line.
+   * <p>
+   * 
+   * @param input the <code>Reader</code> to read from, not null
+   * @return the list of Strings, never null
+   * @throws IOException if an I/O error occurs
+   * @since 1.1
+   */
+  public static List<String> readLines(Reader input) throws IOException {
+    BufferedReader reader = toBufferedReader(input);
+    List<String> list = new ArrayList<String>();
+    String line = reader.readLine();
+    while (line != null) {
+      list.add(line);
+      line = reader.readLine();
+    }
+    return list;
+  }
+
+  public static List<String> readLines(InputStream input) throws IOException {
+    return readLines(new InputStreamReader(input));
+  }
+
+  public static void write(String data, OutputStream output, Charset encoding) throws IOException {
+    if (data != null) {
+      if (encoding == null) {
+        output.write(data.getBytes());
+      } else {
+        output.write(data.getBytes(encoding));
+      }
+    }
+  }
+
+  public static void close(Closeable closeable) {
+    try {
+      if (closeable != null) {
+        closeable.close();
+      }
+    } catch (IOException ioe) {
+      // ignore
+    }
+  }
+
+  private static BufferedReader toBufferedReader(Reader reader) {
+    return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/io/StringBuilderWriter.java b/tools/commons/src/main/java/com/ekingstar/commons/io/StringBuilderWriter.java
new file mode 100644
index 0000000..c3298c5
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/io/StringBuilderWriter.java
@@ -0,0 +1,139 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.io;
+
+import java.io.Serializable;
+import java.io.Writer;
+
+/**
+ * {@link Writer} implementation that outputs to a {@link StringBuilder}.
+ * <p>
+ * <strong>NOTE:</strong> This implementation, as an alternative to
+ * <code>java.io.StringWriter</code>, provides an <i>un-synchronized</i> (i.e. for use in a single
+ * thread) implementation for better performance. For safe usage with multiple {@link Thread}s then
+ * <code>java.io.StringWriter</code> should be used.
+ * 
+ * @author chaostone
+ * @since 3.1
+ */
+public class StringBuilderWriter extends Writer implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  private final StringBuilder builder;
+
+  /**
+   * Construct a new {@link StringBuilder} instance with default capacity.
+   */
+  public StringBuilderWriter() {
+    this.builder = new StringBuilder();
+  }
+
+  /**
+   * Construct a new {@link StringBuilder} instance with the specified capacity.
+   * 
+   * @param capacity The initial capacity of the underlying {@link StringBuilder}
+   */
+  public StringBuilderWriter(int capacity) {
+    this.builder = new StringBuilder(capacity);
+  }
+
+  /**
+   * Construct a new instance with the specified {@link StringBuilder}.
+   * 
+   * @param builder The String builder
+   */
+  public StringBuilderWriter(StringBuilder builder) {
+    this.builder = builder != null ? builder : new StringBuilder();
+  }
+
+  /**
+   * Append a single character to this Writer.
+   */
+  @Override
+  public Writer append(char value) {
+    builder.append(value);
+    return this;
+  }
+
+  /**
+   * Append a character sequence to this Writer.
+   */
+  @Override
+  public Writer append(CharSequence value) {
+    builder.append(value);
+    return this;
+  }
+
+  /**
+   * Append a portion of a character sequence to the {@link StringBuilder}.
+   */
+  @Override
+  public Writer append(CharSequence value, int start, int end) {
+    builder.append(value, start, end);
+    return this;
+  }
+
+  /**
+   * Closing this writer has no effect.
+   */
+  @Override
+  public void close() {
+  }
+
+  /**
+   * Flushing this writer has no effect.
+   */
+  @Override
+  public void flush() {
+  }
+
+  /**
+   * Write a String to the {@link StringBuilder}.
+   * 
+   * @param value The value to write
+   */
+  @Override
+  public void write(String value) {
+    if (value != null) builder.append(value);
+  }
+
+  /**
+   * Write a portion of a character array to the {@link StringBuilder}.
+   */
+  @Override
+  public void write(char[] value, int offset, int length) {
+    if (value != null) builder.append(value, offset, length);
+  }
+
+  /**
+   * Return the underlying builder.
+   */
+  public StringBuilder getBuilder() {
+    return builder;
+  }
+
+  /**
+   * Returns {@link StringBuilder#toString()}.
+   */
+  @Override
+  public String toString() {
+    return builder.toString();
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Arrays.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Arrays.java
new file mode 100644
index 0000000..8f0dc6e
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Arrays.java
@@ -0,0 +1,142 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.lang.reflect.Array;
+import java.util.List;
+
+/**
+ * <p>
+ * Operations on arrays, primitive arrays (like {@code int[]}) and primitive wrapper arrays (like
+ * {@code Integer[]}).
+ * </p>
+ * <p>
+ * This class tries to handle {@code null} input gracefully. An exception will not be thrown for a
+ * {@code null} array input.
+ * </p>
+ * 
+ * @author chaostone
+ * @since 3.0.0
+ */
+public final class Arrays {
+
+  /**
+   * <p>
+   * Checks if an array of Objects is empty or {@code null}.
+   * </p>
+   * 
+   * @param array the array to test
+   * @return {@code true} if the array is empty or {@code null}
+   */
+  public static boolean isEmpty(Object[] array) {
+    return array == null || array.length == 0;
+  }
+
+  /**
+   * <p>
+   * Produces a new array containing the elements between the start and end indices.
+   * </p>
+   * <p>
+   * The start index is inclusive, the end index exclusive. Null array input produces null output.
+   * </p>
+   * <p>
+   * The component type of the subarray is always the same as that of the input array. Thus, if the
+   * input is an array of type {@code Date}, the following usage is envisaged:
+   * </p>
+   * 
+   * <pre>
+   * Date[] someDates = (Date[]) Arrays.subarray(allDates, 2, 5);
+   * </pre>
+   * 
+   * @param <T> the component type of the array
+   * @param array the array
+   * @param startIndexInclusive the starting index. Undervalue (&lt;0)
+   *          is promoted to 0, overvalue (&gt;array.length) results
+   *          in an empty array.
+   * @param endIndexExclusive elements up to endIndex-1 are present in the
+   *          returned subarray. Undervalue (&lt; startIndex) produces
+   *          empty array, overvalue (&gt;array.length) is demoted to
+   *          array length.
+   * @return a new array containing the elements between
+   *         the start and end indices.
+   */
+  public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
+    if (array == null) { return null; }
+    if (startIndexInclusive < 0) {
+      startIndexInclusive = 0;
+    }
+    if (endIndexExclusive > array.length) {
+      endIndexExclusive = array.length;
+    }
+    int newSize = endIndexExclusive - startIndexInclusive;
+    Class<?> type = array.getClass().getComponentType();
+    if (newSize <= 0) {
+      @SuppressWarnings("unchecked")
+      // OK, because array is of type T
+      final T[] emptyArray = (T[]) Array.newInstance(type, 0);
+      return emptyArray;
+    }
+    @SuppressWarnings("unchecked")
+    // OK, because array is of type T
+    T[] subarray = (T[]) Array.newInstance(type, newSize);
+    System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
+    return subarray;
+  }
+
+  /**
+   * join multi array
+   * 
+   * @param arrays
+   * @return
+   */
+  public static byte[] join(List<byte[]> arrays) {
+    int maxlength = 0;
+    for (byte[] array : arrays) {
+      maxlength += array.length;
+    }
+    byte[] rs = new byte[maxlength];
+    int pos = 0;
+    for (byte[] array : arrays) {
+      System.arraycopy(array, 0, rs, pos, array.length);
+      pos += array.length;
+    }
+    return rs;
+  }
+
+  /**
+   * join two array
+   * 
+   * @param array1
+   * @param array2
+   * @return
+   */
+  public static byte[] join(byte[] array1, byte[] array2) {
+    if (array1 == null) return clone(array2);
+    else if (array2 == null) return clone(array1);
+    byte[] joinedArray = new byte[array1.length + array2.length];
+    System.arraycopy(array1, 0, joinedArray, 0, array1.length);
+    System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
+    return joinedArray;
+  }
+
+  private static byte[] clone(byte[] array) {
+    if (array == null) return null;
+    return (byte[]) array.clone();
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Assert.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Assert.java
new file mode 100644
index 0000000..5ee2a29
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Assert.java
@@ -0,0 +1,207 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.util.Iterator;
+
+/**
+ * Assertion tool class
+ * 
+ * @author chaostone
+ * @since 3.0.0
+ */
+public class Assert {
+  private static final String NotEmptyCharSeqMsg = "The validated character sequence is empty";
+  private static final String IsNullMsg = "The validated object is null";
+  private static final String IsTrueMsg = "The validated expression is false";
+
+  /**
+   * <p>
+   * Validate that the argument condition is {@code true}; otherwise throwing an exception. This
+   * method is useful when validating according to an arbitrary boolean expression, such as
+   * validating a primitive number or using your own custom validation expression.
+   * </p>
+   * 
+   * <pre>
+   * Assert.isTrue(i &gt; 0);
+   * Assert.isTrue(myObject.isOk());
+   * </pre>
+   * <p>
+   * The message of the exception is &quot;The validated expression is false&quot;.
+   * </p>
+   * 
+   * @param expression the boolean expression to check
+   * @throws IllegalArgumentException if expression is {@code false}
+   * @see #isTrue(boolean, String, Object...)
+   */
+  public static void isTrue(boolean expression) {
+    if (expression == false) { throw new IllegalArgumentException(IsTrueMsg); }
+  }
+
+  /**
+   * <p>
+   * Validate that the argument condition is {@code true}; otherwise throwing an exception with the
+   * specified message. This method is useful when validating according to an arbitrary boolean
+   * expression, such as validating a primitive number or using your own custom validation
+   * expression.
+   * </p>
+   * 
+   * <pre>
+   * Assert.isTrue(i &gt;= min &amp;&amp; i &lt;= max, &quot;The value must be between %d and %d&quot;, min, max);
+   * Assert.isTrue(myObject.isOk(), &quot;The object is not okay&quot;);
+   * </pre>
+   * 
+   * @param expression the boolean expression to check
+   * @param message the {@link String#format(String, Object...)} exception message if invalid, not
+   *          null
+   * @param values the optional values for the formatted exception message, null array not
+   *          recommended
+   * @throws IllegalArgumentException if expression is {@code false}
+   * @see #isTrue(boolean)
+   */
+  public static void isTrue(boolean expression, String message, Object... values) {
+    if (!expression) { throw new IllegalArgumentException(String.format(message, values)); }
+  }
+
+  /**
+   * <p>
+   * Validate that the specified argument is not {@code null}; otherwise throwing an exception.
+   * 
+   * <pre>
+   * Assert.notNull(myObject, &quot;The object must not be null&quot;);
+   * </pre>
+   * <p>
+   * The message of the exception is &quot;The validated object is null&quot;.
+   * </p>
+   * 
+   * @param <T> the object type
+   * @param object the object to check
+   * @return the validated object (never {@code null} for method chaining)
+   * @throws NullPointerException if the object is {@code null}
+   * @see #notNull(Object, String, Object...)
+   */
+  public static <T> T notNull(T object) {
+    return notNull(object, IsNullMsg);
+  }
+
+  /**
+   * <p>
+   * Validate that the specified argument is not {@code null}; otherwise throwing an exception with
+   * the specified message.
+   * 
+   * <pre>
+   * Assert.notNull(myObject, &quot;The object must not be null&quot;);
+   * </pre>
+   * 
+   * @param <T> the object type
+   * @param object the object to check
+   * @param message the {@link String#format(String, Object...)} exception message if invalid, not
+   *          null
+   * @param values the optional values for the formatted exception message
+   * @return the validated object (never {@code null} for method chaining)
+   * @throws NullPointerException if the object is {@code null}
+   * @see #notNull(Object)
+   */
+  public static <T> T notNull(T object, String message, Object... values) {
+    if (object == null) { throw new NullPointerException(String.format(message, values)); }
+    return object;
+  }
+
+  /**
+   * <p>
+   * Validate that the specified argument array is neither {@code null} nor a length of zero (no
+   * elements); otherwise throwing an exception.
+   * 
+   * <pre>
+   * Assert.notEmpty(myArray);
+   * </pre>
+   * <p>
+   * The message in the exception is &quot;The validated array is empty&quot;.
+   * 
+   * @param <T> the array type
+   * @return the validated array (never {@code null} method for chaining)
+   * @throws NullPointerException if the array is {@code null}
+   * @throws IllegalArgumentException if the array is empty
+   */
+  public static <T extends CharSequence> T notEmpty(T chars) {
+    if (chars == null) { throw new NullPointerException(NotEmptyCharSeqMsg); }
+    if (chars.length() == 0) { throw new IllegalArgumentException(NotEmptyCharSeqMsg); }
+    return chars;
+  }
+
+  /**
+   * <p>
+   * Validate that the specified argument character sequence is neither {@code null} nor a length of
+   * zero (no characters); otherwise throwing an exception with the specified message.
+   * 
+   * <pre>
+   * Assert.notEmpty(myString);
+   * </pre>
+   * <p>
+   * The message in the exception is &quot;The validated character sequence is empty&quot;.
+   * </p>
+   * 
+   * @param <T> the character sequence type
+   * @param chars the character sequence to check, validated not null by this method
+   * @return the validated character sequence (never {@code null} method for chaining)
+   * @throws NullPointerException if the character sequence is {@code null}
+   * @throws IllegalArgumentException if the character sequence is empty
+   */
+  public static <T extends CharSequence> T notEmpty(T chars, String message, Object... values) {
+    if (chars == null) { throw new NullPointerException(String.format(message, values)); }
+    if (chars.length() == 0) { throw new IllegalArgumentException(String.format(message, values)); }
+    return chars;
+  }
+
+  /**
+   * <p>
+   * Validate that the specified argument iterable is neither {@code null} nor contains any elements
+   * that are {@code null}; otherwise throwing an exception with the specified message.
+   * 
+   * <pre>
+   * Assert.noNullElements(myCollection, &quot;The collection contains null at position %d&quot;);
+   * </pre>
+   * <p>
+   * If the iterable is {@code null}, then the message in the exception is &quot;The validated
+   * object is null&quot;.
+   * </p>
+   * <p>
+   * If the iterable has a {@code null} element, then the iteration index of the invalid element is
+   * appended to the {@code values} argument.
+   * </p>
+   * 
+   * @param <T> the iterable type
+   * @param iterable the iterable to check, validated not null by this method
+   * @param message the {@link String#format(String, Object...)} exception message if invalid, not
+   *          null
+   * @param values the optional values for the formatted exception message, null array not
+   *          recommended
+   * @return the validated iterable (never {@code null} method for chaining)
+   * @throws NullPointerException if the array is {@code null}
+   * @throws IllegalArgumentException if an element is {@code null}
+   */
+  public static <T extends Iterable<?>> T noNullElements(T iterable, String message, Object... values) {
+    notNull(iterable);
+    int i = 0;
+    for (Iterator<?> it = iterable.iterator(); it.hasNext(); i++) {
+      if (it.next() == null) { throw new IllegalArgumentException(String.format(message, Integer.valueOf(i))); }
+    }
+    return iterable;
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/BitStrings.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/BitStrings.java
new file mode 100755
index 0000000..c01305e
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/BitStrings.java
@@ -0,0 +1,152 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+/**
+ * <p>
+ * BitStrings class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class BitStrings {
+
+  BitStrings() {
+  }
+
+  /**
+   * 比较两个等长字符串的每一位，若都大于0，则返回结果的相应位为1，否则为0;
+   * 
+   * @param first a {@link java.lang.String} object.
+   * @param second a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String and(final String first, final String second) {
+    final StringBuilder buffer = new StringBuilder();
+    for (int i = 0; i < first.length(); i++) {
+      if ('0' == first.charAt(i) || '0' == second.charAt(i)) {
+        buffer.append('0');
+      } else {
+        buffer.append('1');
+      }
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * 比较两个等长字符串的每一位，相或<br>
+   * 适用于仅含有1和0的字符串.
+   * 
+   * @param first a {@link java.lang.String} object.
+   * @param second a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String or(final String first, final String second) {
+    final StringBuilder buffer = new StringBuilder();
+    for (int i = 0; i < first.length(); i++) {
+      if ('0' == first.charAt(i) && '0' == second.charAt(i)) {
+        buffer.append('0');
+      } else {
+        buffer.append('1');
+      }
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * 将一个字符串，按照boolString的形式进行变化. 如果boolString[i]!=0则保留str[i],否则置0
+   * 
+   * @param str a {@link java.lang.String} object.
+   * @param boolString a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String andWith(final String str, final String boolString) {
+    if (Strings.isEmpty(str)) { return null; }
+    if (Strings.isEmpty(boolString)) { return str; }
+    if (str.length() < boolString.length()) { return str; }
+    final StringBuilder buffer = new StringBuilder(str);
+    for (int i = 0; i < buffer.length(); i++) {
+      if (boolString.charAt(i) == '0') {
+        buffer.setCharAt(i, '0');
+      }
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * 将"314213421340asdf"转换成"1111111111101111"
+   * 
+   * @param first a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String convertToBoolStr(final String first) {
+    final StringBuilder occupyBuffer = new StringBuilder(first.length());
+    for (int i = 0; i < first.length(); i++) {
+      if ('0' == first.charAt(i)) {
+        occupyBuffer.append('0');
+      } else {
+        occupyBuffer.append('1');
+      }
+
+    }
+    return occupyBuffer.toString();
+  }
+
+  /**
+   * 返回零一串的整型值
+   * 
+   * @param binaryStr a {@link java.lang.String} object.
+   * @return a long.
+   */
+  public static long binValueOf(final String binaryStr) {
+    if (Strings.isEmpty(binaryStr)) { return 0; }
+    long value = 0;
+    long height = 1;
+
+    for (int i = binaryStr.length() - 1; i >= 0; i--) {
+      if ('1' == binaryStr.charAt(i)) {
+        value += height;
+      }
+      height *= 2;
+    }
+    return value;
+  }
+
+  /**
+   * <p>
+   * reverse.
+   * </p>
+   * 
+   * @param binaryStr a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String reverse(final String binaryStr) {
+    final StringBuilder occupyBuffer = new StringBuilder(binaryStr.length());
+    for (int i = 0; i < binaryStr.length(); i++) {
+      if ('0' == binaryStr.charAt(i)) {
+        occupyBuffer.append('1');
+      } else {
+        occupyBuffer.append('0');
+      }
+    }
+    return occupyBuffer.toString();
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Chars.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Chars.java
new file mode 100644
index 0000000..a6c1ee0
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Chars.java
@@ -0,0 +1,44 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+public final class Chars {
+
+  /**
+   * <p>
+   * Checks whether the character is ASCII 7 bit alphabetic.
+   * </p>
+   * 
+   * <pre>
+   *   isAsciiAlpha('a')  = true
+   *   isAsciiAlpha('A')  = true
+   *   isAsciiAlpha('3')  = false
+   *   isAsciiAlpha('-')  = false
+   *   isAsciiAlpha('\n') = false
+   *   isAsciiAlpha('&copy;') = false
+   * </pre>
+   * 
+   * @param ch the character to check
+   * @return true if between 65 and 90 or 97 and 122 inclusive
+   * @since 3.0
+   */
+  public static boolean isAsciiAlpha(char ch) {
+    return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Charsets.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Charsets.java
new file mode 100644
index 0000000..6b2a43e
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Charsets.java
@@ -0,0 +1,65 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.nio.charset.Charset;
+
+/**
+ * Contains constant definitions for the six standard {@link Charset} instances, which are
+ * guaranteed to be supported by all Java platform implementations.
+ * 
+ * @author chaostone
+ * @since 3.1
+ */
+public final class Charsets {
+
+  private Charsets() {
+  }
+
+  /**
+   * US-ASCII: seven-bit ASCII, the Basic Latin block of the Unicode character set (ISO646-US).
+   */
+  public static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+  /**
+   * ISO-8859-1: ISO Latin Alphabet Number 1 (ISO-LATIN-1).
+   */
+  public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+
+  /**
+   * UTF-8: eight-bit UCS Transformation Format.
+   */
+  public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+  /**
+   * UTF-16BE: sixteen-bit UCS Transformation Format, big-endian byte order.
+   */
+  public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+
+  /**
+   * UTF-16LE: sixteen-bit UCS Transformation Format, little-endian byte order.
+   */
+  public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+
+  /**
+   * UTF-16: sixteen-bit UCS Transformation Format, byte order identified by an optional
+   * byte-order-mark.
+   */
+  public static final Charset UTF_16 = Charset.forName("UTF-16");
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Dates.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Dates.java
new file mode 100644
index 0000000..7ec3759
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Dates.java
@@ -0,0 +1,46 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * Dates class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: DateUtils.java Jul 26, 2011 4:22:37 PM chaostone $
+ */
+public final class Dates {
+
+  /**
+   * <p>
+   * rollMinutes.
+   * </p>
+   * 
+   * @param date a {@link java.util.Date} object.
+   * @param mount a int.
+   * @return a {@link java.util.Date} object.
+   */
+  public static Date rollMinutes(Date date, int mount) {
+    // Do not user calendar.roll. it will never modify hour
+    return new Date(date.getTime() + mount * 60 * 1000);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Numbers.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Numbers.java
new file mode 100644
index 0000000..253edbf
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Numbers.java
@@ -0,0 +1,119 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.math.BigDecimal;
+
+public final class Numbers {
+
+  /**
+   * <p>
+   * Convert a <code>String</code> to an <code>int</code>, returning <code>zero</code> if the
+   * conversion fails.
+   * </p>
+   * <p>
+   * If the string is <code>null</code>, <code>zero</code> is returned.
+   * </p>
+   * 
+   * <pre>
+   * toInt(null) = 0
+   * toInt("")   = 0
+   * toInt("1")  = 1
+   * </pre>
+   * 
+   * @param str the string to convert, may be null
+   * @return the int represented by the string, or <code>zero</code> if
+   *         conversion fails
+   * @since 3.0
+   */
+  public static int toInt(String str) {
+    return toInt(str, 0);
+  }
+
+  /**
+   * <p>
+   * Convert a <code>String</code> to an <code>int</code>, returning a default value if the
+   * conversion fails.
+   * </p>
+   * <p>
+   * If the string is <code>null</code>, the default value is returned.
+   * </p>
+   * 
+   * <pre>
+   * toInt(null, 1) = 1
+   * toInt("", 1)   = 1
+   * toInt("1", 0)  = 1
+   * </pre>
+   * 
+   * @param str the string to convert, may be null
+   * @param defaultValue the default value
+   * @return the int represented by the string, or the default if conversion fails
+   * @since 3.0
+   */
+  public static int toInt(String str, int defaultValue) {
+    if (str == null) { return defaultValue; }
+    try {
+      return Integer.parseInt(str);
+    } catch (NumberFormatException nfe) {
+      return defaultValue;
+    }
+  }
+
+  public static float toFloat(String str) {
+    return toFloat(str, 0.0f);
+  }
+
+  public static float toFloat(String str, float defaultValue) {
+    if (str == null) return defaultValue;
+    try {
+      return Float.parseFloat(str);
+    } catch (NumberFormatException nfe) {
+      return defaultValue;
+    }
+  }
+
+  /**
+   * <p>
+   * Checks whether the <code>String</code> contains only digit characters.
+   * </p>
+   * <p>
+   * <code>Null</code> and empty String will return <code>false</code>.
+   * </p>
+   * 
+   * @param str the <code>String</code> to check
+   * @return <code>true</code> if str contains only Unicode numeric
+   */
+  public static boolean isDigits(String str) {
+    if (Strings.isEmpty(str)) return false;
+    for (int i = 0; i < str.length(); i++) {
+      if (!Character.isDigit(str.charAt(i))) return false;
+    }
+    return true;
+  }
+
+  public static boolean isNumber(String str) {
+    if (Strings.isEmpty(str)) return false;
+    try {
+      new BigDecimal(str);
+    } catch (NumberFormatException e) {
+      return false;
+    }
+    return true;
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Objects.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Objects.java
new file mode 100644
index 0000000..e1fda44
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Objects.java
@@ -0,0 +1,663 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+public final class Objects {
+
+  /**
+   * <p>
+   * Compares two objects for equality, where either one or both objects may be {@code null}.
+   * </p>
+   * 
+   * <pre>
+   * equals(null, null)                  = true
+   * equals(null, "")                    = false
+   * equals("", null)                    = false
+   * equals("", "")                      = true
+   * equals(Boolean.TRUE, null)          = false
+   * equals(Boolean.TRUE, "true")        = false
+   * equals(Boolean.TRUE, Boolean.TRUE)  = true
+   * equals(Boolean.TRUE, Boolean.FALSE) = false
+   * </pre>
+   * 
+   * @param a the first object, may be {@code null}
+   * @param b the second object, may be {@code null}
+   * @return {@code true} if the values of both objects are the same
+   * @since 3.0
+   */
+  public static boolean equals(Object a, Object b) {
+    return (a == b) || (a != null && a.equals(b));
+  }
+
+  /**
+   * <p>
+   * Compares two object array for equality, where either one or both objects may be {@code null}.
+   * </p>
+   */
+  public static boolean equals(Object[] a, Object b[]) {
+    if (a == b) return true;
+    if (null == a || null == b) return false;
+
+    if (a.length != b.length) return false;
+    for (int i = 0; i < a.length; ++i) {
+      if (!Objects.equals(a[i], b[i])) return false;
+    }
+    return true;
+  }
+
+  /**
+   * <p>
+   * Gets the {@code toString} of an {@code Object} returning an empty string ("") if {@code null}
+   * input.
+   * </p>
+   * 
+   * <pre>
+   * toString(null)         = ""
+   * toString("")           = ""
+   * toString("bat")        = "bat"
+   * toString(Boolean.TRUE) = "true"
+   * </pre>
+   * 
+   * @see String#valueOf(Object)
+   * @param obj the Object to {@code toString}, may be null
+   * @return the passed in Object's toString, or nullStr if {@code null} input
+   * @since 3.0
+   */
+  public static String toString(Object obj) {
+    return obj == null ? "" : obj.toString();
+  }
+
+  // -----------------------------------------------------------------------
+  /**
+   * <p>
+   * Returns a default value if the object passed is {@code null}.
+   * </p>
+   * 
+   * <pre>
+   * defaultIfNull(null, null)      = null
+   * defaultIfNull(null, "")        = ""
+   * defaultIfNull(null, "zz")      = "zz"
+   * defaultIfNull("abc", *)        = "abc"
+   * defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
+   * </pre>
+   * 
+   * @param <T> the type of the object
+   * @param object the {@code Object} to test, may be {@code null}
+   * @param defaultValue the default value to return, may be {@code null}
+   * @return {@code object} if it is not {@code null}, defaultValue otherwise
+   * @since 3.0
+   */
+  public static <T> T defaultIfNull(T object, T defaultValue) {
+    return object != null ? object : defaultValue;
+  }
+
+  public static Object defaultValue(Class<?> clazz) {
+    if (clazz.equals(boolean.class)) return false;
+    if (clazz.equals(int.class)) return 0;
+    if (clazz.equals(short.class)) return (short) 0;
+    if (clazz.equals(long.class)) return 0L;
+    if (clazz.equals(float.class)) return 0.0f;
+    if (clazz.equals(double.class)) return 0.0d;
+    if (clazz.equals(char.class)) return (char) 0;
+    if (clazz.equals(byte.class)) return (byte) 0;
+    return null;
+  }
+
+  /**
+   * Return a hex String form of an object's identity hash code.
+   * 
+   * @param obj the object
+   * @return the object's identity code in hex notation
+   */
+  public static String getIdentityHexString(Object obj) {
+    return Integer.toHexString(System.identityHashCode(obj));
+  }
+
+  public static CompareBuilder compareBuilder() {
+    return new CompareBuilder();
+  }
+
+  public static EqualsBuilder equalsBuilder() {
+    return new EqualsBuilder();
+  }
+
+  /**
+   * Creates an instance of {@link ToStringBuilder}.
+   * <p>
+   * This is helpful for implementing {@link Object#toString()}. Specification by example:
+   * 
+   * <pre>
+   * {@code
+   *   // Returns "ClassName{}"
+   *   Objects.toStringBuilder(this)
+   *       .toString();
+   * 
+   *   // Returns "ClassName{x=1}"
+   *   Objects.toStringBuilder(this)
+   *       .add("x", 1)
+   *       .toString();
+   * 
+   *   // Returns "MyObject{x=1}"
+   *   Objects.toStringBuilder("MyObject")
+   *       .add("x", 1)
+   *       .toString();
+   * 
+   *   // Returns "ClassName{x=1, y=foo}"
+   *   Objects.toStringBuilder(this)
+   *       .add("x", 1)
+   *       .add("y", "foo")
+   *       .toString();
+   *   }}
+   * 
+   *   // Returns "ClassName{x=1}"
+   *   Objects.toStringBuilder(this)
+   *       .omitNullValues()
+   *       .add("x", 1)
+   *       .add("y", null)
+   *       .toString();
+   *   }}
+   * </pre>
+   * 
+   * @param self the object to generate the string for (typically {@code this}),
+   *          used only for its class name
+   * @since 3.1
+   */
+  public static ToStringBuilder toStringBuilder(Object self) {
+    return new ToStringBuilder(simpleName(self.getClass()));
+  }
+
+  /**
+   * Creates an instance of {@link ToStringBuilder} in the same manner as
+   * {@link Objects#toStringBuilder(Object)}, but using the name of {@code clazz} instead of using
+   * an
+   * instance's {@link Object#getClass()}.
+   * <p>
+   * 
+   * @param clazz the {@link Class} of the instance
+   */
+  public static ToStringBuilder toStringBuilder(Class<?> clazz) {
+    return new ToStringBuilder(simpleName(clazz));
+  }
+
+  /**
+   * Creates an instance of {@link ToStringBuilder} in the same manner as
+   * {@link Objects#toStringBuilder(Object)}, but using {@code className} instead
+   * of using an instance's {@link Object#getClass()}.
+   * 
+   * @param className the name of the instance type
+   */
+  public static ToStringBuilder toStringBuilder(String className) {
+    return new ToStringBuilder(className);
+  }
+
+  /**
+   * More readable than {@link Class#getSimpleName()}
+   */
+  private static String simpleName(Class<?> clazz) {
+    String name = clazz.getName();
+
+    // the nth anonymous class has a class name ending in "Outer$n"
+    // and local inner classes have names ending in "Outer.$1Inner"
+    name = name.replaceAll("\\$[0-9]+", "\\$");
+
+    // we want the name of the inner class all by its lonesome
+    int start = name.lastIndexOf('$');
+
+    // if this isn't an inner class, just find the start of the
+    // top level class name.
+    if (start == -1) start = name.lastIndexOf('.');
+    return name.substring(start + 1);
+  }
+
+  /**
+   * Support class for {@link Objects#toStringBuilder}.
+   */
+  public static final class ToStringBuilder {
+    private final String className;
+    private final List<ValueHolder> valueHolders = new LinkedList<ValueHolder>();
+    private boolean omitNull = false;
+
+    /**
+     * Use {@link Objects#toStringBuilder(Object)} to create an instance.
+     */
+    private ToStringBuilder(String className) {
+      this.className = className;
+    }
+
+    /**
+     * When called, the formatted output returned by {@link #toString()} will
+     * ignore {@code null} values.
+     */
+    public ToStringBuilder omitNull() {
+      omitNull = true;
+      return this;
+    }
+
+    /**
+     * Adds a name/value pair to the formatted output in {@code name=value} format. If {@code value}
+     * is {@code null}, the string {@code "null"} is used, unless {@link #omitNull()} is
+     * called, in which case this
+     * name/value pair will not be added.
+     */
+    public ToStringBuilder add(String name, Object value) {
+      addHolder(value).builder.append(name).append('=').append(value);
+      return this;
+    }
+
+    /**
+     * Returns a string in the format specified by {@link Objects#toStringBuilder(Object)}.
+     */
+    @Override
+    public String toString() {
+      StringBuilder builder = new StringBuilder(32).append(className).append('{');
+      boolean needsSeparator = false;
+      for (ValueHolder valueHolder : valueHolders) {
+        if (!omitNull || !valueHolder.isNull) {
+          if (needsSeparator) builder.append(", ");
+          else needsSeparator = true;
+          builder.append(valueHolder.builder);
+        }
+      }
+      return builder.append('}').toString();
+    }
+
+    private ValueHolder addHolder() {
+      ValueHolder valueHolder = new ValueHolder();
+      valueHolders.add(valueHolder);
+      return valueHolder;
+    }
+
+    private ValueHolder addHolder(Object value) {
+      ValueHolder valueHolder = addHolder();
+      valueHolder.isNull = (value == null);
+      return valueHolder;
+    }
+
+    private static final class ValueHolder {
+      final StringBuilder builder = new StringBuilder();
+      boolean isNull;
+    }
+  }
+
+  public static final class CompareBuilder {
+    private int comparison = 0;
+
+    public CompareBuilder add(Object lhs, Object rhs) {
+      return add(lhs, rhs, null);
+
+    }
+
+    public CompareBuilder add(Object lhs, Object rhs, Comparator<?> comparator) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.getClass().isArray()) {
+        // switch on type of array, to dispatch to the correct handler
+        // handles multi dimensional arrays
+        // throws a ClassCastException if rhs is not the correct array type
+        if (lhs instanceof long[]) {
+          add((long[]) lhs, (long[]) rhs);
+        } else if (lhs instanceof int[]) {
+          add((int[]) lhs, (int[]) rhs);
+        } else if (lhs instanceof short[]) {
+          add((short[]) lhs, (short[]) rhs);
+        } else if (lhs instanceof char[]) {
+          add((char[]) lhs, (char[]) rhs);
+        } else if (lhs instanceof byte[]) {
+          add((byte[]) lhs, (byte[]) rhs);
+        } else if (lhs instanceof double[]) {
+          add((double[]) lhs, (double[]) rhs);
+        } else if (lhs instanceof float[]) {
+          add((float[]) lhs, (float[]) rhs);
+        } else if (lhs instanceof boolean[]) {
+          add((boolean[]) lhs, (boolean[]) rhs);
+        } else {
+          // not an array of primitives
+          // throws a ClassCastException if rhs is not an array
+          add((Object[]) lhs, (Object[]) rhs, comparator);
+        }
+      } else {
+        // the simple case, not an array, just test the element
+        if (comparator == null) {
+          @SuppressWarnings("unchecked")
+          final Comparable<Object> comparable = (Comparable<Object>) lhs;
+          comparison = comparable.compareTo(rhs);
+        } else {
+          @SuppressWarnings("unchecked")
+          final Comparator<Object> comparator2 = (Comparator<Object>) comparator;
+          comparison = comparator2.compare(lhs, rhs);
+        }
+      }
+      return this;
+    }
+
+    public CompareBuilder add(long lhs, long rhs) {
+      if (comparison != 0) return this;
+      comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
+      return this;
+    }
+
+    public CompareBuilder add(int lhs, int rhs) {
+      if (comparison != 0) return this;
+      comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
+      return this;
+    }
+
+    public CompareBuilder add(short lhs, short rhs) {
+      if (comparison != 0) return this;
+      comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
+      return this;
+    }
+
+    public CompareBuilder add(char lhs, char rhs) {
+      if (comparison != 0) return this;
+      comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
+      return this;
+    }
+
+    public CompareBuilder add(byte lhs, byte rhs) {
+      if (comparison != 0) return this;
+      comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
+      return this;
+    }
+
+    public CompareBuilder add(double lhs, double rhs) {
+      if (comparison != 0) return this;
+      comparison = Double.compare(lhs, rhs);
+      return this;
+    }
+
+    public CompareBuilder add(float lhs, float rhs) {
+      if (comparison != 0) return this;
+      comparison = Float.compare(lhs, rhs);
+      return this;
+    }
+
+    public CompareBuilder add(boolean lhs, boolean rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == false) comparison = -1;
+      else comparison = +1;
+      return this;
+    }
+
+    public CompareBuilder add(Object[] lhs, Object[] rhs) {
+      return add(lhs, rhs, null);
+    }
+
+    public CompareBuilder add(Object[] lhs, Object[] rhs, Comparator<?> comparator) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i], comparator);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(long[] lhs, long[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(int[] lhs, int[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(short[] lhs, short[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(char[] lhs, char[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(byte[] lhs, byte[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(double[] lhs, double[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(float[] lhs, float[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public CompareBuilder add(boolean[] lhs, boolean[] rhs) {
+      if (comparison != 0) return this;
+      if (lhs == rhs) return this;
+      if (lhs == null) {
+        comparison = -1;
+        return this;
+      }
+      if (rhs == null) {
+        comparison = +1;
+        return this;
+      }
+      if (lhs.length != rhs.length) {
+        comparison = (lhs.length < rhs.length) ? -1 : +1;
+        return this;
+      }
+      for (int i = 0; i < lhs.length && comparison == 0; i++) {
+        add(lhs[i], rhs[i]);
+      }
+      return this;
+    }
+
+    public int toComparison() {
+      return comparison;
+    }
+  }
+
+  /**
+   * Equals Builder
+   * 
+   * @author chaostone
+   * @since 3.1.0
+   */
+  public static final class EqualsBuilder {
+    private boolean equals = true;
+
+    public EqualsBuilder add(Object lhs, Object rhs) {
+      if (!equals) return this;
+      equals &= Objects.equals(lhs, rhs);
+      return this;
+    }
+
+    public EqualsBuilder add(Object[] lhs, Object[] rhs) {
+      if (!equals) return this;
+      equals &= Objects.equals(lhs, rhs);
+      return this;
+    }
+
+    public EqualsBuilder add(int lhs, int rhs) {
+      if (!equals) return this;
+      equals &= (lhs == rhs);
+      return this;
+    }
+
+    public EqualsBuilder add(long lhs, long rhs) {
+      if (!equals) return this;
+      equals &= (lhs == rhs);
+      return this;
+    }
+
+    public EqualsBuilder add(short lhs, short rhs) {
+      if (!equals) return this;
+      equals &= (lhs == rhs);
+      return this;
+    }
+
+    public EqualsBuilder add(boolean lhs, boolean rhs) {
+      if (!equals) return this;
+      equals &= (lhs == rhs);
+      return this;
+    }
+
+    public boolean isEquals() {
+      return equals;
+    }
+  }
+
+  public static boolean isArray(Object obj) {
+    if (null == obj) return false;
+    return obj.getClass().isArray();
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Primitives.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Primitives.java
new file mode 100644
index 0000000..5e019b4
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Primitives.java
@@ -0,0 +1,98 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+
+/**
+ * Wrap or Unwrap primitive
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public final class Primitives {
+  private Primitives() {
+  }
+
+  /** Primitive types to their corresponding wrapper types. */
+  private static final Map<Class<?>, Class<?>> PrimitiveToWrappers = CollectUtils.newFastMap(16);
+
+  /** Wrapper types to their corresponding primitive types. */
+  private static final Map<Class<?>, Class<?>> WrapperToPrimitives = CollectUtils.newFastMap(16);
+
+  static {
+    add(boolean.class, Boolean.class);
+    add(byte.class, Byte.class);
+    add(char.class, Character.class);
+    add(double.class, Double.class);
+    add(float.class, Float.class);
+    add(int.class, Integer.class);
+    add(long.class, Long.class);
+    add(short.class, Short.class);
+    add(void.class, Void.class);
+  }
+
+  private static void add(Class<?> key, Class<?> value) {
+    PrimitiveToWrappers.put(key, value);
+    WrapperToPrimitives.put(value, key);
+  }
+
+  /**
+   * Returns {@code true} if {@code type} is one of the nine
+   * primitive-wrapper types, such as {@link Integer}.
+   * 
+   * @see Class#isPrimitive
+   */
+  public static boolean isWrapperType(Class<?> type) {
+    return WrapperToPrimitives.containsKey(type);
+  }
+
+  /**
+   * Returns the corresponding wrapper type of {@code type} if it is a primitive
+   * type; otherwise returns {@code type} itself. Idempotent.
+   * 
+   * <pre>
+   *     wrap(int.class) == Integer.class
+   *     wrap(Integer.class) == Integer.class
+   *     wrap(String.class) == String.class
+   * </pre>
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> Class<T> wrap(Class<T> type) {
+    return (type.isPrimitive() || type == void.class) ? (Class<T>) PrimitiveToWrappers.get(type) : type;
+  }
+
+  /**
+   * Returns the corresponding primitive type of {@code type} if it is a
+   * wrapper type; otherwise returns {@code type} itself. Idempotent.
+   * 
+   * <pre>
+   *     unwrap(Integer.class) == int.class
+   *     unwrap(int.class) == int.class
+   *     unwrap(String.class) == String.class
+   * </pre>
+   */
+  public static <T> Class<T> unwrap(Class<T> type) {
+    @SuppressWarnings("unchecked")
+    Class<T> unwrapped = (Class<T>) WrapperToPrimitives.get(type);
+    return (unwrapped == null) ? type : unwrapped;
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Strings.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Strings.java
new file mode 100755
index 0000000..ba0e90c
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Strings.java
@@ -0,0 +1,1460 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import static java.lang.Character.isLowerCase;
+import static java.lang.Character.isUpperCase;
+import static java.lang.Character.toLowerCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import com.ekingstar.commons.collection.CollectUtils;
+
+/**
+ * <p>
+ * Operations on {@link java.lang.String} that are {@code null} safe.
+ * </p>
+ * 
+ * @author chaostone 2005-11-15
+ * @version $Id: $
+ * @since 3.0
+ */
+public class Strings {
+
+  /** Constant <code>DELIMITER=","</code> */
+  public static final String DELIMITER = ",";
+
+  private static final String Empty = "";
+
+  private static final int Index_not_found = -1;
+
+  Strings() {
+  }
+
+  /**
+   * <p>
+   * Capitalizes a String changing the first letter to title case as per
+   * {@link Character#toTitleCase(char)}. No other letters are changed.
+   * </p>
+   * <p>
+   * For a word based algorithm, see returns {@code null}.
+   * </p>
+   * 
+   * <pre>
+   * capitalize(null)  = null
+   * capitalize("")    = ""
+   * capitalize("cat") = "Cat"
+   * capitalize("cAt") = "CAt"
+   * </pre>
+   * 
+   * @param str the String to capitalize, may be null
+   * @return the capitalized String, {@code null} if null String input
+   * @see #uncapitalize(String)
+   * @since 2.0
+   */
+  public static String capitalize(String str) {
+    int strLen;
+    if (str == null || (strLen = str.length()) == 0) { return str; }
+    return new StringBuilder(strLen).append(Character.toTitleCase(str.charAt(0))).append(str.substring(1))
+        .toString();
+  }
+
+  /**
+   * <p>
+   * concat.
+   * </p>
+   * 
+   * @param seq
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String concat(final String... seq) {
+    return join(seq, "");
+  }
+
+  /**
+   * <p>
+   * Checks if CharSequence contains a search CharSequence, handling {@code null}. This method uses
+   * {@link String#indexOf(String)} if possible.
+   * </p>
+   * <p>
+   * A {@code null} CharSequence will return {@code false}.
+   * </p>
+   * 
+   * <pre>
+   * contains(null, *)     = false
+   * contains(*, null)     = false
+   * contains("", "")      = true
+   * contains("abc", "")   = true
+   * contains("abc", "a")  = true
+   * contains("abc", "z")  = false
+   * </pre>
+   * 
+   * @param seq the CharSequence to check, may be null
+   * @param searchSeq the CharSequence to find, may be null
+   * @return true if the CharSequence contains the search CharSequence,
+   *         false if not or {@code null} string input
+   */
+  public static boolean contains(CharSequence seq, CharSequence searchSeq) {
+    if (seq == null || searchSeq == null) { return false; }
+    return indexOf(seq, searchSeq, 0) >= 0;
+  }
+
+  /**
+   * <p>
+   * Checks if CharSequence contains a search character, handling {@code null}. This method uses
+   * {@link String#indexOf(int)} if possible.
+   * </p>
+   * <p>
+   * A {@code null} or empty ("") CharSequence will return {@code false}.
+   * </p>
+   * 
+   * <pre>
+   * contains(null, *)    = false
+   * contains("", *)      = false
+   * contains("abc", 'a') = true
+   * contains("abc", 'z') = false
+   * </pre>
+   * 
+   * @param seq
+   *          the CharSequence to check, may be null
+   * @param searchChar
+   *          the character to find
+   * @return true if the CharSequence contains the search character,
+   *         false if not or {@code null} string input
+   * @since 2.0
+   * @since 3.0 Changed signature from contains(String, int) to contains(CharSequence, int)
+   */
+  public static boolean contains(CharSequence seq, int searchChar) {
+    if (isEmpty(seq)) { return false; }
+    return indexOf(seq, searchChar, 0) >= 0;
+  }
+
+  /**
+   * count char in host string
+   * 
+   * @param host
+   *          a {@link java.lang.String} object.
+   * @param charactor
+   *          a char.
+   * @return a int.
+   */
+  public static int count(final String host, final char charactor) {
+    int count = 0;
+    for (int i = 0; i < host.length(); i++) {
+      if (host.charAt(i) == charactor) {
+        count++;
+      }
+    }
+    return count;
+  }
+
+  /**
+   * count inner string in host string
+   * 
+   * @param host
+   *          a {@link java.lang.String} object.
+   * @param searchStr
+   *          a {@link java.lang.String} object.
+   * @return a int.
+   */
+  public static int count(final String host, final String searchStr) {
+    int count = 0;
+    for (int startIndex = 0; startIndex < host.length(); startIndex++) {
+      int findLoc = host.indexOf(searchStr, startIndex);
+      if (findLoc == -1) {
+        break;
+      } else {
+        count++;
+        startIndex = findLoc + searchStr.length() - 1;
+      }
+    }
+    return count;
+  }
+
+  /**
+   * Returns index of searchChar in cs with begin index {@code start}
+   * 
+   * @param searchChar
+   * @param start
+   */
+  private static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
+    return cs.toString().indexOf(searchChar.toString(), start);
+  }
+
+  /**
+   * <p>
+   * Finds the first index in the {@code CharSequence} that matches the specified character.
+   * </p>
+   * 
+   * @param cs the {@code CharSequence} to be processed, not null
+   * @param searchChar the char to be searched for
+   * @param start the start index, negative starts at the string start
+   * @return the index where the search char was found, -1 if not found
+   */
+  private static int indexOf(CharSequence cs, int searchChar, int start) {
+    if (cs instanceof String) {
+      return ((String) cs).indexOf(searchChar, start);
+    } else {
+      int sz = cs.length();
+      if (start < 0) {
+        start = 0;
+      }
+      for (int i = start; i < sz; i++) {
+        if (cs.charAt(i) == searchChar) { return i; }
+      }
+      return -1;
+    }
+  }
+
+  /**
+   * <p>
+   * insert.
+   * </p>
+   * 
+   * @param str a {@link java.lang.String} object.
+   * @param c a {@link java.lang.String} object.
+   * @param pos a int.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String insert(final String str, final String c, final int pos) {
+    if (str.length() < pos) { return str; }
+    return str.substring(0, pos - 1) + c + str.substring(pos);
+  }
+
+  /**
+   * replace [bigen,end] [1...end] with givenStr
+   * 可以使用StringBuilder的replace方法替换该方法
+   * 
+   * @param str a {@link java.lang.String} object.
+   * @param begin a int.
+   * @param end a int.
+   * @param given a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String insert(final String str, final String given, final int begin, final int end) {
+    if (begin < 1 || end > str.length() || end < begin) { return str; }
+    return str.substring(0, begin - 1) + given + str.substring(end);
+  }
+
+  /**
+   * <p>
+   * intersectSeq.
+   * </p>
+   * 
+   * @param first
+   *          a {@link java.lang.String} object.
+   * @param second
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String intersectSeq(final String first, final String second) {
+    return intersectSeq(first, second, DELIMITER);
+  }
+
+  /**
+   * 返回一个新的逗号相隔字符串，实现其中的单词a-b的功能
+   * 
+   * @param first a {@link java.lang.String} object.
+   * @param second a {@link java.lang.String} object.
+   * @param delimiter a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String intersectSeq(final String first, final String second, final String delimiter) {
+    if (isEmpty(first) || isEmpty(second)) { return ""; }
+    List<String> firstSeq = Arrays.asList(split(first, ','));
+    List<String> secondSeq = Arrays.asList(split(second, ','));
+    Collection<String> rs = CollectUtils.intersection(firstSeq, secondSeq);
+    StringBuilder buf = new StringBuilder();
+    for (final String ele : rs) {
+      buf.append(delimiter).append(ele);
+    }
+    if (buf.length() > 0) {
+      buf.append(delimiter);
+    }
+    return buf.toString();
+  }
+
+  /**
+   * <p>
+   * Checks if a CharSequence is whitespace, empty ("") or null.
+   * </p>
+   * 
+   * <pre>
+   * isBlank(null)      = true
+   * isBlank("")        = true
+   * isBlank(" ")       = true
+   * isBlank("bob")     = false
+   * isBlank("  bob  ") = false
+   * </pre>
+   * 
+   * @param cs
+   *          the CharSequence to check, may be null
+   * @return {@code true} if the CharSequence is null, empty or whitespace
+   * @since 3.0
+   */
+  public static boolean isBlank(CharSequence cs) {
+    int strLen;
+    if (cs == null || (strLen = cs.length()) == 0) { return true; }
+    for (int i = 0; i < strLen; i++) {
+      if (Character.isWhitespace(cs.charAt(i)) == false) { return false; }
+    }
+    return true;
+  }
+
+  /**
+   * Returns true is cs is null or cs.length equals 0.
+   */
+  public static boolean isEmpty(CharSequence cs) {
+    return cs == null || cs.length() == 0;
+  }
+
+  /**
+   * <p>
+   * isEqualSeq.
+   * </p>
+   * 
+   * @param first not null
+   * @param second not null
+   * @return a boolean.
+   */
+  public static boolean isEqualSeq(final String first, final String second) {
+    return isEqualSeq(first, second, DELIMITER);
+  }
+
+  /**
+   * 判断两个","逗号相隔的字符串中的单词是否完全等同.
+   * 
+   * @param first
+   *          a {@link java.lang.String} object.
+   * @param second
+   *          a {@link java.lang.String} object.
+   * @param delimiter
+   *          a {@link java.lang.String} object.
+   * @return a boolean.
+   */
+  public static boolean isEqualSeq(final String first, final String second, final String delimiter) {
+    if (isNotEmpty(first) && isNotEmpty(second)) {
+      String[] firstWords = split(first, delimiter);
+      Set<String> firstSet = CollectUtils.newHashSet();
+      for (int i = 0; i < firstWords.length; i++) {
+        firstSet.add(firstWords[i]);
+      }
+      String[] secondWords = split(second, delimiter);
+      Set<String> secondSet = CollectUtils.newHashSet();
+      for (int i = 0; i < secondWords.length; i++) {
+        secondSet.add(secondWords[i]);
+      }
+      return firstSet.equals(secondSet);
+    } else {
+      return isEmpty(first) & isEmpty(second);
+    }
+  }
+
+  /**
+   * <p>
+   * Checks if a CharSequence is not empty (""), not null and not whitespace only.
+   * </p>
+   * 
+   * <pre>
+   * isNotBlank(null)      = false
+   * isNotBlank("")        = false
+   * isNotBlank(" ")       = false
+   * isNotBlank("bob")     = true
+   * isNotBlank("  bob  ") = true
+   * </pre>
+   * 
+   * @param cs
+   *          the CharSequence to check, may be null
+   * @return {@code true} if the CharSequence is
+   *         not empty and not null and not whitespace
+   * @since 3.0
+   */
+  public static boolean isNotBlank(CharSequence cs) {
+    return !isBlank(cs);
+  }
+
+  /**
+   * Return true if cs not null and cs has length.
+   */
+  public static boolean isNotEmpty(CharSequence cs) {
+    return !isEmpty(cs);
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param seq
+   *          a {@link java.util.Collection} object.
+   * @param delimiter
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String join(final Collection<String> seq, final String delimiter) {
+    if (null == seq || seq.size() < 1) {
+      return "";
+    } else {
+      StringBuilder aim = new StringBuilder();
+      for (String one : seq) {
+        if (null != delimiter && aim.length() > 0) {
+          aim.append(delimiter);
+        }
+        aim.append(one);
+      }
+      return aim.toString();
+    }
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param seq
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String join(final String... seq) {
+    return join(seq, DELIMITER);
+  }
+
+  public static String join(final Object[] seq, final char delimiter) {
+    if (null == seq || seq.length < 1) return "";
+    StringBuilder aim = new StringBuilder();
+    for (int i = 0; i < seq.length; i++) {
+      if (aim.length() > 0) aim.append(delimiter);
+      aim.append(seq[i]);
+    }
+    return aim.toString();
+  }
+
+  /**
+   * 将数组中的字符串，用delimiter串接起来.<br>
+   * 首尾不加delimiter
+   * 
+   * @param seq an array of {@link java.lang.String} objects.
+   * @param delimiter a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String join(final String[] seq, final String delimiter) {
+    if (null == seq || seq.length < 1) return "";
+    Assert.notNull(delimiter);
+    StringBuilder aim = new StringBuilder();
+    for (int i = 0; i < seq.length; i++) {
+      if (aim.length() > 0) aim.append(delimiter);
+      aim.append(seq[i]);
+    }
+    return aim.toString();
+  }
+
+  /**
+   * 保持逗号分隔的各个单词都是唯一的。并且按照原来的顺序存放。
+   * 
+   * @param keys
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String keepSeqUnique(final String keys) {
+    String[] keysArray = split(keys, ",");
+    List<String> keyList = CollectUtils.newArrayList();
+    for (int i = 0; i < keysArray.length; i++) {
+      if (!keyList.contains(keysArray[i])) {
+        keyList.add(keysArray[i]);
+      }
+    }
+    StringBuilder keyBuf = new StringBuilder();
+    for (Iterator<String> iter = keyList.iterator(); iter.hasNext();) {
+      keyBuf.append(iter.next());
+      if (iter.hasNext()) {
+        keyBuf.append(",");
+      }
+    }
+    return keyBuf.toString();
+  }
+
+  /**
+   * <p>
+   * Left pad a String with a specified character.
+   * </p>
+   * <p>
+   * Pad to a size of {@code size}.
+   * </p>
+   * 
+   * <pre>
+   * leftPad(null, *, *)     = null
+   * leftPad("", 3, 'z')     = "zzz"
+   * leftPad("bat", 3, 'z')  = "bat"
+   * leftPad("bat", 5, 'z')  = "zzbat"
+   * leftPad("bat", 1, 'z')  = "bat"
+   * leftPad("bat", -1, 'z') = "bat"
+   * </pre>
+   * 
+   * @param str the String to pad out, may be null
+   * @param size the size to pad to
+   * @param padChar the character to pad with
+   * @return left padded String or original String if no padding is necessary, {@code null} if null
+   *         String input
+   * @since 3.0
+   */
+  public static String leftPad(String str, int size, char padChar) {
+    if (str == null) { return null; }
+    int pads = size - str.length();
+    if (pads <= 0) { return str; // returns original String when possible
+    }
+    return repeat(padChar, pads).concat(str);
+  }
+
+  /**
+   * <p>
+   * Right pad a String with a specified character.
+   * </p>
+   * <p>
+   * The String is padded to the size of {@code size}.
+   * </p>
+   * 
+   * <pre>
+   * rightPad(null, *, *)     = null
+   * rightPad("", 3, 'z')     = "zzz"
+   * rightPad("bat", 3, 'z')  = "bat"
+   * rightPad("bat", 5, 'z')  = "batzz"
+   * rightPad("bat", 1, 'z')  = "bat"
+   * rightPad("bat", -1, 'z') = "bat"
+   * </pre>
+   * 
+   * @param str the String to pad out, may be null
+   * @param size the size to pad to
+   * @param padChar the character to pad with
+   * @return right padded String or original String if no padding is necessary, {@code null} if null
+   *         String input
+   * @since 3.0
+   */
+  public static String rightPad(String str, int size, char padChar) {
+    if (str == null) { return null; }
+    int pads = size - str.length();
+    if (pads <= 0) { return str; // returns original String when possible
+    }
+    return str.concat(repeat(padChar, pads));
+  }
+
+  /**
+   * <p>
+   * mergeSeq.
+   * </p>
+   * 
+   * @param first
+   *          a {@link java.lang.String} object.
+   * @param second
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String mergeSeq(final String first, final String second) {
+    return mergeSeq(first, second, DELIMITER);
+  }
+
+  /**
+   * 将两个用delimiter串起来的字符串，合并成新的串，重复的"单词"只出现一次.
+   * 如果第一个字符串以delimiter开头，第二个字符串以delimiter结尾，<br>
+   * 合并后的字符串仍以delimiter开头和结尾.<br>
+   * <p>
+   * <blockquote>
+   * 
+   * <pre>
+   * mergeSeq(&quot;,1,2,&quot;, &quot;&quot;) = &quot;,1,2,&quot;;
+   * mergeSeq(&quot;,1,2,&quot;, null) = &quot;,1,2,&quot;;
+   * mergeSeq(&quot;1,2&quot;, &quot;3&quot;) = &quot;1,2,3&quot;;
+   * mergeSeq(&quot;1,2&quot;, &quot;3,&quot;) = &quot;1,2,3,&quot;;
+   * mergeSeq(&quot;,1,2&quot;, &quot;3,&quot;) = &quot;,1,2,3,&quot;;
+   * mergeSeq(&quot;,1,2,&quot;, &quot;,3,&quot;) = &quot;,1,2,3,&quot;;
+   * </pre>
+   * 
+   * </blockquote>
+   * <p>
+   * 
+   * @param first
+   *          a {@link java.lang.String} object.
+   * @param second
+   *          a {@link java.lang.String} object.
+   * @param delimiter
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String mergeSeq(final String first, final String second, final String delimiter) {
+    if (isNotEmpty(second) && isNotEmpty(first)) {
+      List<String> firstSeq = Arrays.asList(split(first, delimiter));
+      List<String> secondSeq = Arrays.asList(split(second, delimiter));
+      Collection<String> rs = CollectUtils.union(firstSeq, secondSeq);
+      StringBuilder buf = new StringBuilder();
+      for (final String ele : rs)
+        buf.append(delimiter).append(ele);
+      if (buf.length() > 0) buf.append(delimiter);
+      return buf.toString();
+    } else {
+      return ((first == null) ? "" : first) + ((second == null) ? "" : second);
+    }
+  }
+
+  /**
+   * <p>
+   * removeWord.
+   * </p>
+   * 
+   * @param host
+   *          a {@link java.lang.String} object.
+   * @param word
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String removeWord(final String host, final String word) {
+    return removeWord(host, word, DELIMITER);
+
+  }
+
+  /**
+   * <p>
+   * removeWord.
+   * </p>
+   * 
+   * @param host
+   *          a {@link java.lang.String} object.
+   * @param word
+   *          a {@link java.lang.String} object.
+   * @param delimiter
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String removeWord(final String host, final String word, final String delimiter) {
+    if (host.indexOf(word) == -1) {
+      return host;
+    } else {
+      int beginIndex = host.indexOf(word);
+      int endIndex = beginIndex + word.length();
+      if (beginIndex == 0) { return host.substring(endIndex + 1); }
+      if (endIndex == host.length()) {
+        return host.substring(0, beginIndex - delimiter.length());
+      } else {
+        String before = host.substring(0, beginIndex);
+        String after = host.substring(endIndex + 1);
+        return before + after;
+      }
+    }
+  }
+
+  /**
+   * <p>
+   * Returns padding using the specified delimiter repeated to a given length.
+   * </p>
+   * 
+   * <pre>
+   * repeat(0, 'e')  = ""
+   * repeat(3, 'e')  = "eee"
+   * repeat(-2, 'e') = ""
+   * </pre>
+   * 
+   * @param ch character to repeat
+   * @param repeat number of times to repeat char, negative treated as zero
+   * @return String with repeated character
+   * @see #repeat(String, int)
+   */
+  public static String repeat(char ch, int repeat) {
+    if (repeat <= 0) return Empty;
+    char[] buf = new char[repeat];
+    for (int i = repeat - 1; i >= 0; i--) {
+      buf[i] = ch;
+    }
+    return new String(buf);
+  }
+
+  /**
+   * <p>
+   * Repeat a String {@code repeat} times to form a new String.
+   * </p>
+   * 
+   * <pre>
+   * repeat(null, 2) = null
+   * repeat("", 0)   = ""
+   * repeat("", 2)   = ""
+   * repeat("a", 3)  = "aaa"
+   * repeat("ab", 2) = "abab"
+   * repeat("a", -2) = ""
+   * </pre>
+   * 
+   * @param str the String to repeat, may be null
+   * @param repeat number of times to repeat str, negative treated as zero
+   * @return a new String consisting of the original String repeated, {@code null} if null String
+   *         input
+   * @since 3.0
+   */
+  public static String repeat(String str, int repeat) {
+    if (str == null) return null;
+    if (repeat <= 0) return Empty;
+    if (repeat == 1) return str;
+    final int len = str.length();
+    final long longSize = (long) len * (long) repeat;
+    final int size = (int) longSize;
+    if (size != longSize) { throw new ArrayIndexOutOfBoundsException("Required array size too large: "
+        + String.valueOf(longSize)); }
+
+    final char[] array = new char[size];
+    str.getChars(0, len, array, 0);
+    int n;
+    for (n = len; n < size - n; n <<= 1) {
+      System.arraycopy(array, 0, array, n, n);
+    }
+    System.arraycopy(array, 0, array, n, size - n);
+    return new String(array);
+
+  }
+
+  /**
+   * <p>
+   * Replaces all occurrences of a String within another String.
+   * </p>
+   * <p>
+   * A {@code null} reference passed to this method is a no-op.
+   * </p>
+   * 
+   * <pre>
+   * replace(null, *, *)        = null
+   * replace("", *, *)          = ""
+   * replace("any", null, *)    = "any"
+   * replace("any", *, null)    = "any"
+   * replace("any", "", *)      = "any"
+   * replace("aba", "a", null)  = "aba"
+   * replace("aba", "a", "")    = "b"
+   * replace("aba", "a", "z")   = "zbz"
+   * </pre>
+   * 
+   * @param text text to search and replace in, may be null
+   * @param searchString the String to search for, may be null
+   * @param replacement the String to replace it with, may be null
+   * @return the text with any replacements processed, {@code null} if null String input
+   */
+  public static String replace(String text, String searchString, String replacement) {
+    if (isEmpty(text) || isEmpty(searchString) || replacement == null) { return text; }
+    int start = 0;
+    int end = text.indexOf(searchString, start);
+    if (end == -1) { return text; }
+    int replLength = searchString.length();
+    int increase = replacement.length() - replLength;
+    increase = increase < 0 ? 0 : increase;
+    increase *= 16;
+    StringBuilder buf = new StringBuilder(text.length() + increase);
+    while (end != -1) {
+      buf.append(text.substring(start, end)).append(replacement);
+      start = end + replLength;
+      end = text.indexOf(searchString, start);
+    }
+    buf.append(text.substring(start));
+    return buf.toString();
+  }
+
+  /**
+   * <p>
+   * split.
+   * </p>
+   * 
+   * @param target
+   *          a {@link java.lang.String} object.
+   * @return an array of {@link java.lang.String} objects.
+   */
+  public static String[] split(String target) {
+    return split(target, new char[] { ',', ';', '\r', '\n', ' ' });
+  }
+
+  /**
+   * <p>
+   * Splits the provided text into an array, separator specified. This is an alternative to using
+   * StringTokenizer.
+   * </p>
+   * A {@code null} input String returns {@code null}.
+   * </p>
+   * 
+   * <pre>
+   * split(null, *)         = null
+   * split("", *)           = []
+   * split("a.b.c", '.')    = ["a", "b", "c"]
+   * split("a..b.c", '.')   = ["a", "b", "c"]
+   * split("a:b:c", '.')    = ["a:b:c"]
+   * split("a b c", ' ')    = ["a", "b", "c"]
+   * </pre>
+   */
+  public static String[] split(String str, char separatorChar) {
+    if (str == null) { return null; }
+    int len = str.length();
+    if (len == 0) return new String[0];
+    List<String> list = new ArrayList<String>();
+    int i = 0, start = 0;
+    boolean match = false;
+    while (i < len) {
+      if (str.charAt(i) == separatorChar) {
+        if (match) {
+          list.add(str.substring(start, i));
+          match = false;
+        }
+        start = ++i;
+        continue;
+      }
+      match = true;
+      i++;
+    }
+    if (match) list.add(str.substring(start, i));
+    return list.toArray(new String[list.size()]);
+
+  }
+
+  /**
+   * <p>
+   * split.
+   * </p>
+   * 
+   * @param target
+   *          a {@link java.lang.String} object.
+   * @param separatorChars
+   *          an array of char.
+   * @return an array of {@link java.lang.String} objects.
+   */
+  public static String[] split(String target, char[] separatorChars) {
+    if (null == target) { return new String[0]; }
+    char[] sb = target.toCharArray();
+    for (char separator : separatorChars) {
+      if (separator != ',') {
+        for (int i = 0; i < sb.length; i++)
+          if (sb[i] == separator) sb[i] = ',';
+      }
+    }
+    String[] targets = split(new String(sb), ',');
+    List<String> list = CollectUtils.newArrayList();
+    for (String one : targets) {
+      if (isNotBlank(one)) list.add(one.trim());
+    }
+    String[] rs = new String[list.size()];
+    list.toArray(rs);
+    return rs;
+  }
+
+  /**
+   * *
+   * <p>
+   * Splits the provided text into an array, separators specified. This is an alternative to using
+   * StringTokenizer.
+   * </p>
+   * <p>
+   * A {@code null} input String returns {@code null}. A {@code null} separatorChars splits on
+   * whitespace.
+   * </p>
+   * 
+   * <pre>
+   * split(null, *)         = null
+   * split("", *)           = []
+   * split("abc def", null) = ["abc", "def"]
+   * split("abc def", " ")  = ["abc", "def"]
+   * split("abc  def", " ") = ["abc", "def"]
+   * split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
+   * </pre>
+   */
+  public static String[] split(String str, String separatorChars) {
+    if (str == null) { return null; }
+    int len = str.length();
+    if (len == 0) return new String[0];
+    List<String> list = new ArrayList<String>();
+    int i = 0, start = 0;
+    boolean match = false;
+    if (null == separatorChars) separatorChars = " ";
+    while (i < len) {
+      if (separatorChars.indexOf(str.charAt(i)) >= 0) {
+        if (match) {
+          list.add(str.substring(start, i));
+          match = false;
+        }
+        start = ++i;
+        continue;
+      }
+      match = true;
+      i++;
+    }
+    if (match) list.add(str.substring(start, i));
+    return list.toArray(new String[list.size()]);
+  }
+
+  /**
+   * 将1-2,3,4-9之类的序列拆分成数组
+   * 
+   * @param numSeq
+   *          a {@link java.lang.String} object.
+   * @return an array of {@link java.lang.Integer} objects.
+   */
+  public static Integer[] splitNumSeq(final String numSeq) {
+    if (isEmpty(numSeq)) { return null; }
+    String[] numArray = split(numSeq, ',');
+    Set<Integer> numSet = CollectUtils.newHashSet();
+    for (int i = 0; i < numArray.length; i++) {
+      String num = numArray[i];
+      if (num.contains("-")) {
+        String[] termFromTo = split(num, '-');
+        int from = Numbers.toInt(termFromTo[0]);
+        int to = Numbers.toInt(termFromTo[1]);
+        for (int j = from; j <= to; j++) {
+          numSet.add(Integer.valueOf(j));
+        }
+      } else {
+        numSet.add(new Integer(num));
+      }
+    }
+    Integer[] nums = new Integer[numSet.size()];
+    numSet.toArray(nums);
+    return nums;
+  }
+
+  /**
+   * <p>
+   * splitToInt.
+   * </p>
+   * 
+   * @param ids
+   *          a {@link java.lang.String} object.
+   * @return an array of {@link java.lang.Integer} objects.
+   */
+  public static Integer[] splitToInt(final String ids) {
+    if (isEmpty(ids)) return new Integer[0];
+    else return transformToInt(split(ids, ','));
+  }
+
+  /**
+   * <p>
+   * splitToLong.
+   * </p>
+   * 
+   * @param ids
+   *          a {@link java.lang.String} object.
+   * @return an array of {@link java.lang.Long} objects.
+   */
+  public static Long[] splitToLong(final String ids) {
+    if (isEmpty(ids)) {
+      return new Long[0];
+    } else {
+      return transformToLong(split(ids, ','));
+    }
+  }
+
+  /**
+   * <p>
+   * Gets a substring from the specified String avoiding exceptions.
+   * </p>
+   * <p>
+   * A negative start position can be used to start/end {@code n} characters from the end of the
+   * String.
+   * </p>
+   * <p>
+   * The returned substring starts with the character in the {@code start} position and ends before
+   * the {@code end} position. All position counting is zero-based -- i.e., to start at the
+   * beginning of the string use {@code start = 0}. Negative start and end positions can be used to
+   * specify offsets relative to the end of the String.
+   * </p>
+   * <p>
+   * If {@code start} is not strictly to the left of {@code end}, "" is returned.
+   * </p>
+   * 
+   * <pre>
+   * substring(null, *, *)    = null
+   * substring("", * ,  *)    = "";
+   * substring("abc", 0, 2)   = "ab"
+   * substring("abc", 2, 0)   = ""
+   * substring("abc", 2, 4)   = "c"
+   * substring("abc", 4, 6)   = ""
+   * substring("abc", 2, 2)   = ""
+   * substring("abc", -2, -1) = "b"
+   * substring("abc", -4, 2)  = "ab"
+   * </pre>
+   * 
+   * @param str
+   *          the String to get the substring from, may be null
+   * @param start
+   *          the position to start from, negative means
+   *          count back from the end of the String by this many characters
+   * @param end
+   *          the position to end at (exclusive), negative means
+   *          count back from the end of the String by this many characters
+   * @return substring from start position to end position, {@code null} if null String input
+   */
+  public static String substring(String str, int start, int end) {
+    if (str == null) return null;
+    // handle negatives
+    if (end < 0) end = str.length() + end; // remember end is negative
+    if (start < 0) start = str.length() + start; // remember start is negative
+    // check length next
+    if (end > str.length()) end = str.length();
+    // if start is greater than end, return ""
+    if (start > end) return "";
+    if (start < 0) start = 0;
+    if (end < 0) end = 0;
+    return str.substring(start, end);
+  }
+
+  /**
+   * <p>
+   * subtractSeq.
+   * </p>
+   * 
+   * @param first
+   *          a {@link java.lang.String} object.
+   * @param second
+   *          a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String subtractSeq(final String first, final String second) {
+    return subtractSeq(first, second, DELIMITER);
+  }
+
+  /**
+   * 返回一个新的逗号相隔字符串，实现其中的单词a-b的功能. 新的字符串将以,开始,结束<br>
+   */
+  public static String subtractSeq(String first, String second, String delimiter) {
+    if (isEmpty(first)) { return ""; }
+    if (isEmpty(second)) {
+      StringBuilder builder = new StringBuilder();
+      if (!first.startsWith(delimiter)) builder.append(delimiter).append(first);
+      if (!first.endsWith(delimiter)) builder.append(first).append(delimiter);
+      return builder.toString();
+    }
+    List<String> firstSeq = Arrays.asList(split(first, delimiter));
+    List<String> secondSeq = Arrays.asList(split(second, delimiter));
+    Collection<String> rs = CollectUtils.subtract(firstSeq, secondSeq);
+    StringBuilder buf = new StringBuilder();
+    for (final String ele : rs)
+      buf.append(delimiter).append(ele);
+    if (buf.length() > 0) buf.append(delimiter);
+    return buf.toString();
+  }
+
+  /**
+   * <p>
+   * transformToInt.
+   * </p>
+   * 
+   * @param ids
+   *          an array of {@link java.lang.String} objects.
+   * @return an array of {@link java.lang.Integer} objects.
+   */
+  public static Integer[] transformToInt(final String[] ids) {
+    Integer[] idsOfInteger = new Integer[ids.length];
+    for (int i = 0; i < ids.length; i++) {
+      idsOfInteger[i] = new Integer(ids[i]);
+    }
+    return idsOfInteger;
+  }
+
+  /**
+   * <p>
+   * transformToLong.
+   * </p>
+   * 
+   * @param ids
+   *          an array of {@link java.lang.String} objects.
+   * @return an array of {@link java.lang.Long} objects.
+   */
+  public static Long[] transformToLong(final String[] ids) {
+    if (null == ids) { return null; }
+    Long[] idsOfLong = new Long[ids.length];
+    for (int i = 0; i < ids.length; i++) {
+      idsOfLong[i] = new Long(ids[i]);
+    }
+    return idsOfLong;
+  }
+
+  /**
+   * <p>
+   * unCamel.
+   * </p>
+   */
+  public static String unCamel(String str) {
+    return unCamel(str, '-', true);
+  }
+
+  /**
+   * <p>
+   * unCamel.
+   * </p>
+   * 
+   * @param str
+   *          a {@link java.lang.String} object.
+   * @param seperator
+   *          a char.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String unCamel(String str, char seperator) {
+    return unCamel(str, seperator, true);
+  }
+
+  /**
+   * 将驼峰表示法转换为下划线小写表示
+   * 
+   * @param str
+   *          a {@link java.lang.String} object.
+   * @param seperator
+   *          a char.
+   * @param lowercase
+   *          a boolean.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String unCamel(String str, char seperator, boolean lowercase) {
+    char[] ca = str.toCharArray();
+    if (3 > ca.length) { return lowercase ? str.toLowerCase() : str; }
+    // about five seperator
+    StringBuilder build = new StringBuilder(ca.length + 5);
+    build.append(lowercase ? toLowerCase(ca[0]) : ca[0]);
+
+    boolean lower1 = isLowerCase(ca[0]);
+    int i = 1;
+    while (i < ca.length - 1) {
+      char cur = ca[i];
+      char next = ca[i + 1];
+      boolean upper2 = isUpperCase(cur);
+      boolean lower3 = isLowerCase(next);
+      if (lower1 && upper2 && lower3) {
+        build.append(seperator);
+        build.append(lowercase ? toLowerCase(cur) : cur);
+        build.append(next);
+        i += 2;
+      } else {
+        if (lowercase && upper2) {
+          build.append(toLowerCase(cur));
+        } else {
+          build.append(cur);
+        }
+        lower1 = !upper2;
+        i++;
+      }
+    }
+    if (i == ca.length - 1) {
+      build.append(lowercase ? toLowerCase(ca[i]) : ca[i]);
+    }
+    return build.toString();
+  }
+
+  /**
+   * <p>
+   * Gets the substring before the first occurrence of a separator. The separator is not returned.
+   * </p>
+   * <p>
+   * A {@code null} string input will return {@code null}. An empty ("") string input will return
+   * the empty string. A {@code null} separator will return the input string.
+   * </p>
+   * <p>
+   * If nothing is found, the string input is returned.
+   * </p>
+   * 
+   * <pre>
+   * substringBefore(null, *)      = null
+   * substringBefore("", *)        = ""
+   * substringBefore("abc", "a")   = ""
+   * substringBefore("abcba", "b") = "a"
+   * substringBefore("abc", "c")   = "ab"
+   * substringBefore("abc", "d")   = "abc"
+   * substringBefore("abc", "")    = ""
+   * substringBefore("abc", null)  = "abc"
+   * </pre>
+   * 
+   * @param str the String to get a substring from, may be null
+   * @param separator the String to search for, may be null
+   * @return the substring before the first occurrence of the separator, {@code null} if null String
+   *         input
+   * @since 2.0
+   */
+  public static String substringBefore(String str, String separator) {
+    if (isEmpty(str) || separator == null) { return str; }
+    if (separator.length() == 0) { return Empty; }
+    int pos = str.indexOf(separator);
+    if (pos == Index_not_found) { return str; }
+    return str.substring(0, pos);
+  }
+
+  /**
+   * <p>
+   * Gets the substring after the first occurrence of a separator. The separator is not returned.
+   * </p>
+   * <p>
+   * A {@code null} string input will return {@code null}. An empty ("") string input will return
+   * the empty string. A {@code null} separator will return the empty string if the input string is
+   * not {@code null}.
+   * </p>
+   * <p>
+   * If nothing is found, the empty string is returned.
+   * </p>
+   * 
+   * <pre>
+   * substringAfter(null, *)      = null
+   * substringAfter("", *)        = ""
+   * substringAfter(*, null)      = ""
+   * substringAfter("abc", "a")   = "bc"
+   * substringAfter("abcba", "b") = "cba"
+   * substringAfter("abc", "c")   = ""
+   * substringAfter("abc", "d")   = ""
+   * substringAfter("abc", "")    = "abc"
+   * </pre>
+   * 
+   * @param str the String to get a substring from, may be null
+   * @param separator the String to search for, may be null
+   * @return the substring after the first occurrence of the separator, {@code null} if null String
+   *         input
+   * @since 2.0
+   */
+  public static String substringAfter(String str, String separator) {
+    if (isEmpty(str)) { return str; }
+    if (separator == null) { return Empty; }
+    int pos = str.indexOf(separator);
+    if (pos == Index_not_found) { return Empty; }
+    return str.substring(pos + separator.length());
+  }
+
+  /**
+   * <p>
+   * Gets the String that is nested in between two Strings. Only the first match is returned.
+   * </p>
+   * <p>
+   * A {@code null} input String returns {@code null}. A {@code null} open/close returns
+   * {@code null} (no match). An empty ("") open and close returns an empty string.
+   * </p>
+   * 
+   * <pre>
+   * substringBetween("wx[b]yz", "[", "]") = "b"
+   * substringBetween(null, *, *)          = null
+   * substringBetween(*, null, *)          = null
+   * substringBetween(*, *, null)          = null
+   * substringBetween("", "", "")          = ""
+   * substringBetween("", "", "]")         = null
+   * substringBetween("", "[", "]")        = null
+   * substringBetween("yabcz", "", "")     = ""
+   * substringBetween("yabcz", "y", "z")   = "abc"
+   * substringBetween("yabczyabcz", "y", "z")   = "abc"
+   * </pre>
+   * 
+   * @param str the String containing the substring, may be null
+   * @param open the String before the substring, may be null
+   * @param close the String after the substring, may be null
+   * @return the substring, {@code null} if no match
+   * @since 3.0
+   */
+  public static String substringBetween(String str, String open, String close) {
+    if (str == null || open == null || close == null) { return null; }
+    int start = str.indexOf(open);
+    if (start != Index_not_found) {
+      int end = str.indexOf(close, start + open.length());
+      if (end != Index_not_found) { return str.substring(start + open.length(), end); }
+    }
+    return null;
+  }
+
+  /**
+   * <p>
+   * Gets the substring before the last occurrence of a separator. The separator is not returned.
+   * </p>
+   * <p>
+   * A {@code null} string input will return {@code null}. An empty ("") string input will return
+   * the empty string. An empty or {@code null} separator will return the input string.
+   * </p>
+   * <p>
+   * If nothing is found, the string input is returned.
+   * </p>
+   * 
+   * <pre>
+   * substringBeforeLast(null, *)      = null
+   * substringBeforeLast("", *)        = ""
+   * substringBeforeLast("abcba", "b") = "abc"
+   * substringBeforeLast("abc", "c")   = "ab"
+   * substringBeforeLast("a", "a")     = ""
+   * substringBeforeLast("a", "z")     = "a"
+   * substringBeforeLast("a", null)    = "a"
+   * substringBeforeLast("a", "")      = "a"
+   * </pre>
+   * 
+   * @param str the String to get a substring from, may be null
+   * @param separator the String to search for, may be null
+   * @return the substring before the last occurrence of the separator, {@code null} if null String
+   *         input
+   * @since 3.0
+   */
+  public static String substringBeforeLast(String str, String separator) {
+    if (isEmpty(str) || isEmpty(separator)) { return str; }
+    int pos = str.lastIndexOf(separator);
+    if (pos == Index_not_found) { return str; }
+    return str.substring(0, pos);
+  }
+
+  /**
+   * <p>
+   * Gets the substring after the last occurrence of a separator. The separator is not returned.
+   * </p>
+   * <p>
+   * A {@code null} string input will return {@code null}. An empty ("") string input will return
+   * the empty string. An empty or {@code null} separator will return the empty string if the input
+   * string is not {@code null}.
+   * </p>
+   * <p>
+   * If nothing is found, the empty string is returned.
+   * </p>
+   * 
+   * <pre>
+   * substringAfterLast(null, *)      = null
+   * substringAfterLast("", *)        = ""
+   * substringAfterLast(*, "")        = ""
+   * substringAfterLast(*, null)      = ""
+   * substringAfterLast("abc", "a")   = "bc"
+   * substringAfterLast("abcba", "b") = "a"
+   * substringAfterLast("abc", "c")   = ""
+   * substringAfterLast("a", "a")     = ""
+   * substringAfterLast("a", "z")     = ""
+   * </pre>
+   * 
+   * @param str the String to get a substring from, may be null
+   * @param separator the String to search for, may be null
+   * @return the substring after the last occurrence of the separator, {@code null} if null String
+   *         input
+   * @since 3.0
+   */
+  public static String substringAfterLast(String str, String separator) {
+    if (isEmpty(str)) { return str; }
+    if (isEmpty(separator)) { return Empty; }
+    int pos = str.lastIndexOf(separator);
+    if (pos == Index_not_found || pos == str.length() - separator.length()) { return Empty; }
+    return str.substring(pos + separator.length());
+  }
+
+  /**
+   * <p>
+   * Removes control characters (char &lt;= 32) from both ends of this String, handling {@code null}
+   * by returning {@code null}.
+   * </p>
+   * <p>
+   * The String is trimmed using {@link String#trim()}. Trim removes start and end characters &lt;=
+   * 32.
+   * </p>
+   * 
+   * <pre>
+   * trim(null)          = null
+   * trim("")            = ""
+   * trim("     ")       = ""
+   * trim("abc")         = "abc"
+   * trim("    abc    ") = "abc"
+   * </pre>
+   * 
+   * @param str the String to be trimmed, may be null
+   * @return the trimmed string, {@code null} if null String input
+   * @since 3.0
+   */
+  public static String trim(String str) {
+    return str == null ? null : str.trim();
+  }
+
+  /**
+   * <p>
+   * Uncapitalizes a String changing the first letter to title case as per
+   * {@link Character#toLowerCase(char)}. No other letters are changed.
+   * </p>
+   * <p>
+   * For a word based algorithm, see String returns {@code null}.
+   * </p>
+   * 
+   * <pre>
+   * uncapitalize(null)  = null
+   * uncapitalize("")    = ""
+   * uncapitalize("Cat") = "cat"
+   * uncapitalize("CAT") = "cAT"
+   * </pre>
+   * 
+   * @param str the String to uncapitalize, may be null
+   * @return the uncapitalized String, {@code null} if null String input
+   * @see #capitalize(String)
+   * @since 3.0
+   */
+  public static String uncapitalize(String str) {
+    int strLen;
+    if (str == null || (strLen = str.length()) == 0) { return str; }
+    return new StringBuilder(strLen).append(Character.toLowerCase(str.charAt(0))).append(str.substring(1))
+        .toString();
+  }
+
+  /**
+   * <p>
+   * Returns either the passed in CharSequence, or if the CharSequence is whitespace, empty ("") or
+   * {@code null}, the value of {@code defaultStr}.
+   * </p>
+   * 
+   * @param str
+   * @param defaultStr
+   */
+  public static <T extends CharSequence> T defaultIfBlank(T str, T defaultStr) {
+    return isBlank(str) ? defaultStr : str;
+  }
+
+  public static String abbreviate(String str, int maxWidth) {
+    return abbreviate(str, 0, maxWidth);
+  }
+
+  public static String abbreviate(String str, int offset, int maxWidth) {
+    if (str == null) return null;
+    if (maxWidth < 4) throw new IllegalArgumentException("Minimum abbreviation width is 4");
+    if (str.length() <= maxWidth) return str;
+    if (offset > str.length()) offset = str.length();
+
+    if (str.length() - offset < maxWidth - 3) offset = str.length() - (maxWidth - 3);
+    final String abrevMarker = "...";
+    if (offset <= 4) return str.substring(0, maxWidth - 3) + abrevMarker;
+    if (maxWidth < 7) throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
+    if (offset + maxWidth - 3 < str.length()) { return abrevMarker
+        + abbreviate(str.substring(offset), maxWidth - 3); }
+    return abrevMarker + str.substring(str.length() - (maxWidth - 3));
+  }
+
+  /**
+   * <p>
+   * Removes all occurrences of a character from within the source string.
+   * </p>
+   * <p>
+   * A {@code null} source string will return {@code null}. An empty ("") source string will return
+   * the empty string.
+   * </p>
+   * 
+   * <pre>
+   * StringUtils.remove(null, *)       = null
+   * StringUtils.remove("", *)         = ""
+   * StringUtils.remove("queued", 'u') = "qeed"
+   * StringUtils.remove("queued", 'z') = "queued"
+   * </pre>
+   * 
+   * @param str the source String to search, may be null
+   * @param remove the char to search for and remove, may be null
+   * @return the substring with the char removed if found, {@code null} if null String input
+   */
+  public static String remove(String str, char remove) {
+    if (isEmpty(str) || str.indexOf(remove) == -1) { return str; }
+    char[] chars = str.toCharArray();
+    int pos = 0;
+    for (int i = 0; i < chars.length; i++) {
+      if (chars[i] != remove) chars[pos++] = chars[i];
+    }
+    return new String(chars, 0, pos);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/Throwables.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/Throwables.java
new file mode 100644
index 0000000..a23d504
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/Throwables.java
@@ -0,0 +1,99 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Static utility methods pertaining to instances of {@link Throwable}.
+ * 
+ * @author chaostone
+ * @since 3.0
+ */
+public final class Throwables {
+  private Throwables() {
+  }
+
+  /**
+   * Propagates {@code throwable} exactly as-is, if and only if it is an
+   * instance of {@code declaredType}. Example usage:
+   * 
+   * <pre>
+   * try {
+   *   someMethodThatCouldThrowAnything();
+   * } catch (IKnowWhatToDoWithThisException e) {
+   *   handle(e);
+   * } catch (Throwable t) {
+   *   Throwables.propagateIfInstanceOf(t, IOException.class);
+   *   Throwables.propagateIfInstanceOf(t, SQLException.class);
+   *   throw Throwables.propagate(t);
+   * }
+   * </pre>
+   */
+  public static <X extends Throwable> void propagateIfInstanceOf(Throwable throwable, Class<X> declaredType)
+      throws X {
+    // Check for null is needed to avoid frequent JNI calls to isInstance().
+    if (throwable != null && declaredType.isInstance(throwable)) { throw declaredType.cast(throwable); }
+  }
+
+  /**
+   * Propagates {@code throwable} as-is if it is an instance of {@link RuntimeException} or
+   * {@link Error}, or else as a last resort, wraps
+   * it in a {@code RuntimeException} then propagates.
+   * <p>
+   * This method always throws an exception. The {@code RuntimeException} return type is only for
+   * client code to make Java type system happy in case a return value is required by the enclosing
+   * method. Example usage:
+   * 
+   * <pre>
+   * T doSomething() {
+   *   try {
+   *     return someMethodThatCouldThrowAnything();
+   *   } catch (IKnowWhatToDoWithThisException e) {
+   *     return handle(e);
+   *   } catch (Throwable t) {
+   *     throw Throwables.propagate(t);
+   *   }
+   * }
+   * </pre>
+   * 
+   * @param throwable the Throwable to propagate
+   * @return nothing will ever be returned; this return type is only for your
+   *         convenience, as illustrated in the example above
+   */
+  public static RuntimeException propagate(Throwable throwable) {
+    propagateIfInstanceOf(throwable, Error.class);
+    propagateIfInstanceOf(throwable, RuntimeException.class);
+    throw new RuntimeException(throwable);
+  }
+
+  /**
+   * Returns a string containing the result of {@link Throwable#toString() toString()}, followed by
+   * the full, recursive
+   * stack trace of {@code throwable}. Note that you probably should not be
+   * parsing the resulting string; if you need programmatic access to the stack
+   * frames, you can call {@link Throwable#getStackTrace()}.
+   */
+  public static String getStackTrace(Throwable throwable) {
+    StringWriter sw = new StringWriter();
+    throwable.printStackTrace(new PrintWriter(sw));
+    return sw.toString();
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/BinaryFunction.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/BinaryFunction.java
new file mode 100644
index 0000000..0701e8d
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/BinaryFunction.java
@@ -0,0 +1,46 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+import com.ekingstar.commons.lang.Objects;
+
+/**
+ * Binary Function Object
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ * @param <I1> first input type
+ * @param <I2> second input type
+ * @param <R> returned output type
+ */
+public interface BinaryFunction<I1, I2, R> {
+  /**
+   * Returns the result of applying this function to {@code input}. This method is <i>generally
+   * expected</i>, but not absolutely required, to have the following properties:
+   * <ul>
+   * <li>Its execution does not cause any observable side effects.
+   * <li>The computation is <i>consistent with equals</i>; that is, {@link Objects#equal
+   * Objects.equal}{@code (a, b)} implies that {@code Objects.equal(function.apply(a),
+   * function.apply(b))}.
+   * </ul>
+   * 
+   * @throws NullPointerException if {@code input} is null
+   */
+  R apply(I1 arg1, I2 arg2);
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/CollectionHasUpto1ElementPredicate.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/CollectionHasUpto1ElementPredicate.java
new file mode 100755
index 0000000..e636768
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/CollectionHasUpto1ElementPredicate.java
@@ -0,0 +1,37 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+import java.util.Collection;
+
+/**
+ * <p>
+ * CollectionHasUpto1ElementPredicate class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class CollectionHasUpto1ElementPredicate implements Predicate<Collection<?>> {
+
+  public Boolean apply(final Collection<?> object) {
+    return object.size() < 2;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/ContainsPredicate.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/ContainsPredicate.java
new file mode 100755
index 0000000..72eefef
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/ContainsPredicate.java
@@ -0,0 +1,51 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+import java.util.Collection;
+
+/**
+ * <p>
+ * ContainsPredicate class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class ContainsPredicate<T> implements Predicate<T> {
+
+  private final Collection<? extends T> objs;
+
+  /**
+   * <p>
+   * Constructor for ContainsPredicate.
+   * </p>
+   * 
+   * @param objs a {@link java.util.Collection} object.
+   */
+  public ContainsPredicate(Collection<? extends T> objs) {
+    super();
+    this.objs = objs;
+  }
+
+  public Boolean apply(T arg0) {
+    return objs.contains(arg0);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/InStrPredicate.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/InStrPredicate.java
new file mode 100755
index 0000000..01a2c55
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/InStrPredicate.java
@@ -0,0 +1,49 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+/**
+ * <p>
+ * InStrPredicate class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class InStrPredicate implements Predicate<String> {
+
+  private final String str;
+
+  /**
+   * <p>
+   * Constructor for InStrPredicate.
+   * </p>
+   * 
+   * @param str a {@link java.lang.String} object.
+   */
+  public InStrPredicate(final String str) {
+    this.str = str;
+  }
+
+  public Boolean apply(final String arg0) {
+    String target = arg0.toString();
+    return -1 != str.indexOf(target);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NotEmptyStringPredicate.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NotEmptyStringPredicate.java
new file mode 100755
index 0000000..ad221f1
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NotEmptyStringPredicate.java
@@ -0,0 +1,39 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * <p>
+ * NotEmptyStringPredicate class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class NotEmptyStringPredicate implements Predicate<String> {
+  /** Constant <code>INSTANCE</code> */
+  public static final NotEmptyStringPredicate Instance = new NotEmptyStringPredicate();
+
+  public Boolean apply(final String value) {
+    return (null != value) && (value instanceof String) && Strings.isNotEmpty((String) value);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NotZeroNumberPredicate.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NotZeroNumberPredicate.java
new file mode 100755
index 0000000..2b7b852
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NotZeroNumberPredicate.java
@@ -0,0 +1,49 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+
+/**
+ * <p>
+ * NotZeroNumberPredicate class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class NotZeroNumberPredicate implements Predicate<Number> {
+
+  public Boolean apply(final Number value) {
+    return 0 != ((Number) value).intValue();
+  }
+
+  /** Constant <code>INSTANCE</code> */
+  public static final NotZeroNumberPredicate Instance = new NotZeroNumberPredicate();
+
+  /**
+   * <p>
+   * getInstance.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.lang.functor.NotZeroNumberPredicate} object.
+   */
+  public static NotZeroNumberPredicate getInstance() {
+    return Instance;
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NumRangePredicate.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NumRangePredicate.java
new file mode 100755
index 0000000..e3eb23c
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/NumRangePredicate.java
@@ -0,0 +1,53 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+/**
+ * 有效整型判断谓词
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class NumRangePredicate implements Predicate<Number> {
+
+  private final int floor, upper;
+
+  /**
+   * <p>
+   * Constructor for NumRangePredicate.
+   * </p>
+   * 
+   * @param floor a int.
+   * @param upper a int.
+   */
+  public NumRangePredicate(final int floor, final int upper) {
+    this.floor = floor;
+    this.upper = upper;
+  }
+
+  public Boolean apply(final Number value) {
+    if (null == value) {
+      return false;
+    } else {
+      int valueInt = value.intValue();
+      return valueInt <= upper && valueInt >= floor;
+    }
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/Predicate.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/Predicate.java
new file mode 100644
index 0000000..8af4bc3
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/Predicate.java
@@ -0,0 +1,29 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+/**
+ * Prediate
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public interface Predicate<T> extends UnaryFunction<T, Boolean> {
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/Transformer.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/Transformer.java
new file mode 100644
index 0000000..7baff61
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/Transformer.java
@@ -0,0 +1,31 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+/**
+ * Transform object to another
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ * @param <I>
+ * @param <R>
+ */
+public interface Transformer<I, R> extends UnaryFunction<I, R> {
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/UnaryFunction.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/UnaryFunction.java
new file mode 100644
index 0000000..be374eb
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/functor/UnaryFunction.java
@@ -0,0 +1,46 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.functor;
+
+import com.ekingstar.commons.lang.Objects;
+
+/**
+ * Unary Function Object
+ * 
+ * @param <I> input type
+ * @param <R> returned output type
+ * @author chaostone
+ * @since 3.2.0
+ */
+public interface UnaryFunction<I, R> {
+
+  /**
+   * Returns the result of applying this function to {@code input}. This method is <i>generally
+   * expected</i>, but not absolutely required, to have the following properties:
+   * <ul>
+   * <li>Its execution does not cause any observable side effects.
+   * <li>The computation is <i>consistent with equals</i>; that is, {@link Objects#equal
+   * Objects.equal}{@code (a, b)} implies that {@code Objects.equal(function.apply(a),
+   * function.apply(b))}.
+   * </ul>
+   * 
+   * @throws NullPointerException if {@code input} is null
+   */
+  R apply(I input);
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/reflect/ClassInfo.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/reflect/ClassInfo.java
new file mode 100644
index 0000000..7fd05c0
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/reflect/ClassInfo.java
@@ -0,0 +1,247 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.reflect;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.FastHashMap;
+import com.ekingstar.commons.lang.tuple.Pair;
+
+/**
+ * Class meta information.It contains method signature,property names
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public final class ClassInfo {
+
+  /** class info cache */
+  public static Map<Class<?>, ClassInfo> cache = CollectUtils.newHashMap();
+
+  /** unqiue method indexes,without any override */
+  private final FastHashMap<String, Integer> methodIndexs = CollectUtils.newFastMap(64);
+
+  /** all method indexes */
+  private final FastHashMap<String, List<MethodInfo>> methods = CollectUtils.newFastMap(64);
+
+  /** property read method indexes */
+  private final FastHashMap<String, MethodInfo> propertyReadMethods = CollectUtils.newFastMap(64);
+
+  /** property write method indexes */
+  private final FastHashMap<String, MethodInfo> propertyWriteMethods = CollectUtils.newFastMap(64);
+
+  /**
+   * Construct Classinfo by method list.
+   */
+  public ClassInfo(Collection<MethodInfo> methodinfos) {
+    super();
+    for (MethodInfo info : methodinfos) {
+      List<MethodInfo> named = methods.get(info.method.getName());
+      if (null == named) {
+        named = CollectUtils.newArrayList();
+        methods.put(info.method.getName(), named);
+      }
+      named.add(info);
+      // true is get,false is set.
+      Pair<Boolean, String> propertyInfo = info.property();
+      if (null != propertyInfo) {
+        if (propertyInfo.getLeft()) {
+          MethodInfo old = propertyReadMethods.put(propertyInfo.getRight(), info);
+          // old return type is subtype
+          if (null != old && info.method.getReturnType().isAssignableFrom(old.method.getReturnType())) propertyReadMethods
+              .put(propertyInfo.getRight(), old);
+        } else propertyWriteMethods.put(propertyInfo.getRight(), info);
+      }
+    }
+    for (Map.Entry<String, List<MethodInfo>> entry : methods.entrySet()) {
+      if (entry.getValue().size() == 1) methodIndexs.put(entry.getKey(),
+          Integer.valueOf(entry.getValue().get(0).index));
+    }
+  }
+
+  /**
+   * Return property read index,return -1 when not found.
+   */
+  public final int getReadIndex(String property) {
+    MethodInfo method = propertyReadMethods.get(property);
+    return (null == method) ? -1 : method.index;
+  }
+
+  /**
+   * Return property read index,return -1 when not found.
+   */
+  public final MethodInfo getReader(String property) {
+    return propertyReadMethods.get(property);
+  }
+
+  /**
+   * Return property type,return null when not found.
+   */
+  public final Class<?> getPropertyType(String property) {
+    MethodInfo info = propertyWriteMethods.get(property);
+    if (null == info) return null;
+    else return info.parameterTypes[0];
+  }
+
+  /**
+   * Return property write index,return -1 if not found.
+   */
+  public final int getWriteIndex(String property) {
+    MethodInfo method = propertyWriteMethods.get(property);
+    return (null == method) ? -1 : method.index;
+  }
+
+  /**
+   * Return property write method,return null if not found.
+   */
+  public final MethodInfo getWriter(String property) {
+    return propertyWriteMethods.get(property);
+  }
+
+  /**
+   * Return method index,return -1 if not found.
+   */
+  public final int getIndex(String name, Object... args) {
+    Integer defaultIndex = methodIndexs.get(name);
+    if (null != defaultIndex) return defaultIndex.intValue();
+    else {
+      final List<MethodInfo> exists = methods.get(name);
+      if (null != exists) {
+        for (MethodInfo info : exists)
+          if (info.matches(args)) return info.index;
+      }
+      return -1;
+    }
+  }
+
+  /**
+   * Return public metheds according to given name
+   */
+  public final List<MethodInfo> getMethods(String name) {
+    List<MethodInfo> namedMethod = methods.get(name);
+    if (null == namedMethod) return Collections.emptyList();
+    else return namedMethod;
+  }
+
+  /**
+   * Return all public methods.
+   */
+  public final List<MethodInfo> getMethods() {
+    List<MethodInfo> methodInfos = CollectUtils.newArrayList();
+    for (Map.Entry<String, List<MethodInfo>> entry : methods.entrySet()) {
+      for (MethodInfo info : entry.getValue())
+        methodInfos.add(info);
+    }
+    Collections.sort(methodInfos);
+    return methodInfos;
+  }
+
+  /**
+   * Return true when Method is public and not static and not volatile.
+   * <p>
+   * javassist.util.proxy.ProxyFactory.getMethods has error due to bridge method.
+   */
+  private static boolean goodMethod(Method method) {
+    int modifiers = method.getModifiers();
+    if (Modifier.isStatic(modifiers) || Modifier.isPrivate(modifiers)) return false;
+    // Skip bridge methods generated method by compiler
+    // For example. CompareTo(Some) and CompareTo(Object).
+    if (method.isBridge()) return false;
+    // Skip method in Object
+    String methodName = method.getName();
+    if (method.getParameterTypes().length == 0
+        && (methodName.equals("hashCode") || methodName.equals("toString"))) return false;
+    if (method.getParameterTypes().length == 1 & methodName.equals("equals")) return false;
+    return true;
+  }
+
+  /**
+   * Get ClassInfo by type.
+   * It search from cache, when failure build it and put it into cache.
+   */
+  public static final ClassInfo get(Class<?> type) {
+    ClassInfo exist = cache.get(type);
+    if (null != exist) return exist;
+    synchronized (cache) {
+      exist = cache.get(type);
+      if (null != exist) return exist;
+
+      Set<MethodInfo> methods = CollectUtils.newHashSet();
+      Class<?> nextClass = type;
+      int index = 0;
+      Map<String, Class<?>> nextParamTypes = null;
+      while (null != nextClass && Object.class != nextClass) {
+        Method[] declaredMethods = nextClass.getDeclaredMethods();
+        for (int i = 0, n = declaredMethods.length; i < n; i++) {
+          Method method = declaredMethods[i];
+          if (!goodMethod(method)) continue;
+          Type[] types = method.getGenericParameterTypes();
+          Class<?>[] paramsTypes = new Class<?>[types.length];
+          for (int j = 0; j < types.length; j++) {
+            Type t = types[j];
+            if (t instanceof ParameterizedType) {
+              paramsTypes[j] = (Class<?>) ((ParameterizedType) t).getRawType();
+            } else if (t instanceof TypeVariable) {
+              paramsTypes[j] = nextParamTypes.get(((TypeVariable<?>) t).getName());
+            } else {
+              paramsTypes[j] = (Class<?>) t;
+            }
+            if (null == paramsTypes[j]) paramsTypes[j] = Object.class;
+          }
+          if (!methods.add(new MethodInfo(index++, method, paramsTypes))) index--;
+        }
+
+        Type nextType = nextClass.getGenericSuperclass();
+        nextClass = nextClass.getSuperclass();
+        if (nextType instanceof ParameterizedType) {
+          Map<String, Class<?>> tmp = CollectUtils.newHashMap();
+          Type[] ps = ((ParameterizedType) nextType).getActualTypeArguments();
+          TypeVariable<?>[] tvs = nextClass.getTypeParameters();
+          for (int k = 0; k < ps.length; k++) {
+            if (ps[k] instanceof Class<?>) {
+              tmp.put(tvs[k].getName(), (Class<?>) ps[k]);
+            } else if (ps[k] instanceof TypeVariable) {
+              tmp.put(tvs[k].getName(), nextParamTypes.get(((TypeVariable<?>) ps[k]).getName()));
+            }
+          }
+          nextParamTypes = tmp;
+        } else {
+          nextParamTypes = Collections.emptyMap();
+        }
+      }
+      exist = new ClassInfo(methods);
+      cache.put(type, exist);
+      return exist;
+    }
+  }
+
+  public Set<String> getWritableProperties() {
+    return CollectUtils.newHashSet(propertyWriteMethods.keySet());
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/reflect/MethodInfo.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/reflect/MethodInfo.java
new file mode 100644
index 0000000..87bcd7e
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/reflect/MethodInfo.java
@@ -0,0 +1,117 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.reflect;
+
+import static com.ekingstar.commons.lang.Strings.substringAfter;
+import static com.ekingstar.commons.lang.Strings.uncapitalize;
+import static java.lang.Character.isUpperCase;
+
+import java.lang.reflect.Method;
+
+import com.ekingstar.commons.lang.Objects;
+import com.ekingstar.commons.lang.tuple.Pair;
+
+/**
+ * Method name and return type and parameters type
+ * 
+ * @author chaostone
+ * @since 3.2.0
+ */
+public final class MethodInfo implements Comparable<MethodInfo> {
+
+  public final int index;
+  public final Method method;
+  public final Class<?>[] parameterTypes;
+
+  public MethodInfo(int index, Method method, Class<?>[] parameterTypes) {
+    super();
+    this.index = index;
+    this.method = method;
+    this.parameterTypes = parameterTypes;
+  }
+
+  /**
+   * Return thid method is property read method (0) or write method(1) or none(-1).
+   */
+  public Pair<Boolean, String> property() {
+    String name = method.getName();
+    if (name.length() > 3 && name.startsWith("get") && isUpperCase(name.charAt(3))
+        && parameterTypes.length == 0) {
+      return Pair.of(Boolean.TRUE, uncapitalize(substringAfter(name, "get")));
+    } else if (name.length() > 2 && name.startsWith("is") && isUpperCase(name.charAt(2))
+        && parameterTypes.length == 0) {
+      return Pair.of(Boolean.TRUE, uncapitalize(substringAfter(name, "is")));
+    } else if (name.length() > 3 && name.startsWith("set") && isUpperCase(name.charAt(3))
+        && parameterTypes.length == 1) { return Pair.of(Boolean.FALSE,
+        uncapitalize(substringAfter(name, "set"))); }
+    return null;
+  }
+
+  @Override
+  public int compareTo(MethodInfo o) {
+    return this.index - o.index;
+  }
+
+  public boolean matches(Object[] args) {
+    if (parameterTypes.length != args.length) return false;
+    for (int i = 0; i < args.length; i++) {
+      if (null != args[i] && !parameterTypes[i].isInstance(args[i])) return false;
+    }
+    return true;
+  }
+
+  @Override
+  public String toString() {
+    final Class<?> returnType = method.getReturnType();
+    StringBuilder sb = new StringBuilder();
+    sb.append((null == returnType) ? "void" : returnType.getSimpleName());
+    sb.append(' ').append(method.getName());
+    if (parameterTypes.length == 0) {
+      sb.append("()");
+    } else {
+      sb.append('(');
+      for (Class<?> type : parameterTypes) {
+        sb.append(type.getSimpleName()).append(",");
+      }
+      sb.deleteCharAt(sb.length() - 1);
+      sb.append(')');
+    }
+    return sb.toString();
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = 0;
+    for (Class<?> t : parameterTypes)
+      hash += t.hashCode();
+    return method.getName().hashCode() + hash;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof MethodInfo) {
+      MethodInfo other = (MethodInfo) obj;
+      return Objects.equalsBuilder().add(method.getName(), other.method.getName())
+          .add(parameterTypes, other.parameterTypes).isEquals();
+    } else {
+      return false;
+    }
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/time/Stopwatch.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/Stopwatch.java
new file mode 100644
index 0000000..c7c445e
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/Stopwatch.java
@@ -0,0 +1,181 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.time;
+
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.TimeUnit;
+
+import com.ekingstar.commons.lang.Assert;
+
+/**
+ * @author chaostone
+ * @since 3.0.0
+ */
+public final class Stopwatch {
+  private final Ticker ticker;
+  private boolean isRunning;
+  private long elapsedNanos;
+  private long startTick;
+
+  /**
+   * Creates (but does not start) a new stopwatch using {@link System#nanoTime} as its time source.
+   */
+  public Stopwatch() {
+    this(Ticker.systemTicker(), false);
+  }
+
+  public Stopwatch(boolean start) {
+    this(Ticker.systemTicker(), true);
+  }
+
+  /**
+   * Creates (but does not start) a new stopwatch, using the specified time
+   * source.
+   */
+  public Stopwatch(Ticker ticker, boolean start) {
+    this.ticker = ticker;
+    if (start) {
+      isRunning = true;
+      startTick = ticker.read();
+    }
+  }
+
+  /**
+   * Returns {@code true} if {@link #start()} has been called on this stopwatch,
+   * and {@link #stop()} has not been called since the last call to {@code start()}.
+   */
+  public boolean isRunning() {
+    return isRunning;
+  }
+
+  /**
+   * Starts the stopwatch.
+   * 
+   * @return this {@code Stopwatch} instance
+   * @throws IllegalStateException if the stopwatch is already running.
+   */
+  public Stopwatch start() {
+    Assert.isTrue(!isRunning);
+    isRunning = true;
+    startTick = ticker.read();
+    return this;
+  }
+
+  /**
+   * Stops the stopwatch. Future reads will return the fixed duration that had
+   * elapsed up to this point.
+   * 
+   * @return this {@code Stopwatch} instance
+   * @throws IllegalStateException if the stopwatch is already stopped.
+   */
+  public Stopwatch stop() {
+    long tick = ticker.read();
+    Assert.isTrue(isRunning);
+    isRunning = false;
+    elapsedNanos += tick - startTick;
+    return this;
+  }
+
+  /**
+   * Sets the elapsed time for this stopwatch to zero,
+   * and places it in a stopped state.
+   * 
+   * @return this {@code Stopwatch} instance
+   */
+  public Stopwatch reset() {
+    elapsedNanos = 0;
+    isRunning = false;
+    return this;
+  }
+
+  private long elapsedNanos() {
+    return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos;
+  }
+
+  /**
+   * Returns the current elapsed time shown on this stopwatch, expressed
+   * in the desired time unit, with any fraction rounded down.
+   * <p>
+   * Note that the overhead of measurement can be more than a microsecond, so it is generally not
+   * useful to specify {@link TimeUnit#NANOSECONDS} precision here.
+   */
+  public long elapsedTime(TimeUnit desiredUnit) {
+    return desiredUnit.convert(elapsedNanos(), NANOSECONDS);
+  }
+
+  /**
+   * Returns the current elapsed time shown on this stopwatch, expressed
+   * in milliseconds, with any fraction rounded down. This is identical to
+   * {@code elapsedTime(TimeUnit.MILLISECONDS}.
+   */
+  public long elapsedMillis() {
+    return elapsedTime(MILLISECONDS);
+  }
+
+  /**
+   * Returns a string representation of the current elapsed time; equivalent to {@code toString(4)}
+   * (four significant figures).
+   */
+  @Override
+  public String toString() {
+    return toString(4);
+  }
+
+  /**
+   * Returns a string representation of the current elapsed time, choosing an
+   * appropriate unit and using the specified number of significant figures.
+   * For example, at the instant when {@code elapsedTime(NANOSECONDS)} would
+   * return {1234567}, {@code toString(4)} returns {@code "1.235 ms"}.
+   */
+  public String toString(int significantDigits) {
+    long nanos = elapsedNanos();
+
+    TimeUnit unit = chooseUnit(nanos);
+    double value = (double) nanos / NANOSECONDS.convert(1, unit);
+
+    // Too bad this functionality is not exposed as a regular method call
+    return String.format("%." + significantDigits + "g %s", value, abbreviate(unit));
+  }
+
+  private static TimeUnit chooseUnit(long nanos) {
+    if (SECONDS.convert(nanos, NANOSECONDS) > 0) { return SECONDS; }
+    if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) { return MILLISECONDS; }
+    if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) { return MICROSECONDS; }
+    return NANOSECONDS;
+  }
+
+  private static String abbreviate(TimeUnit unit) {
+    switch (unit) {
+    case NANOSECONDS:
+      return "ns";
+    case MICROSECONDS:
+      return "\u03bcs"; // μs
+    case MILLISECONDS:
+      return "ms";
+    case SECONDS:
+      return "s";
+    default:
+      throw new AssertionError();
+    }
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/time/Ticker.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/Ticker.java
new file mode 100644
index 0000000..b569ade
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/Ticker.java
@@ -0,0 +1,50 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.time;
+
+/**
+ * Time source generator
+ * 
+ * @author chaostone
+ * @since 3.0.0
+ */
+public abstract class Ticker {
+
+  protected Ticker() {
+  }
+
+  /**
+   * Returns the number of nanoseconds elapsed
+   */
+  public abstract long read();
+
+  /**
+   * A ticker that reads the current time using {@link System#nanoTime}.
+   */
+  public static Ticker systemTicker() {
+    return SYSTEM_TICKER;
+  }
+
+  private static final Ticker SYSTEM_TICKER = new Ticker() {
+    @Override
+    public long read() {
+      return System.nanoTime();
+    }
+  };
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerNode.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerNode.java
new file mode 100644
index 0000000..68cbb62
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerNode.java
@@ -0,0 +1,78 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.time;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Timer Node in stack
+ * 
+ * @author chaostone
+ * @since 3.0.0
+ */
+public class TimerNode implements java.io.Serializable {
+
+  private static final long serialVersionUID = -6180672043920208784L;
+
+  List<TimerNode> children = new ArrayList<TimerNode>();
+
+  String resource;
+
+  long startTime;
+
+  long totalTime;
+
+  public TimerNode(String resource, long startTime) {
+    this.resource = resource;
+    this.startTime = startTime;
+  }
+
+  public void start(long startTime) {
+    this.startTime = startTime;
+  }
+
+  public long end() {
+    this.totalTime = System.currentTimeMillis() - startTime;
+    return this.totalTime;
+  }
+
+  public String getResource() {
+    return resource;
+  }
+
+  /**
+   * Get a formatted string representing all the methods that took longer than a specified time.
+   */
+  public String getPrintable() {
+    return getPrintable("");
+  }
+
+  protected String getPrintable(String indent) {
+    StringBuilder buffer = new StringBuilder();
+    buffer.append(indent);
+    buffer.append("[" + totalTime + "ms] - " + resource);
+
+    for (TimerNode child : children) {
+      buffer.append('\n').append(child.getPrintable(indent + "  "));
+    }
+    return buffer.toString();
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerStack.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerStack.java
new file mode 100644
index 0000000..8b2c3e4
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerStack.java
@@ -0,0 +1,70 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.time;
+
+import java.util.Arrays;
+
+/**
+ * Record timer nodes
+ * 
+ * @author chaostone
+ * @since 3.0.0
+ */
+public class TimerStack {
+
+  int index = -1;
+
+  TimerNode[] nodes;
+
+  public TimerStack(TimerNode root, int initCapacity) {
+    super();
+    nodes = new TimerNode[initCapacity];
+    push(root);
+  }
+
+  public TimerStack(TimerNode root) {
+    this(root, 15);
+  }
+
+  private void ensureCapacity() {
+    if (index >= nodes.length) {
+      int newCapacity = nodes.length * 2;
+      nodes = Arrays.copyOf(nodes, newCapacity);
+    }
+  }
+
+  public void push(TimerNode node) {
+    ensureCapacity();
+    nodes[++index] = node;
+  }
+
+  public TimerNode pop() {
+    if (index < 0) return null;
+    TimerNode top = nodes[index];
+    nodes[index] = null;
+    index--;
+    return top;
+  }
+
+  public TimerNode peek() {
+    if (index < 0) return null;
+    return nodes[index];
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerTrace.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerTrace.java
new file mode 100644
index 0000000..78e694b
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/time/TimerTrace.java
@@ -0,0 +1,161 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.time;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author chaostone
+ * @since 3.0.0
+ */
+public final class TimerTrace {
+
+  private static final Logger logger = LoggerFactory.getLogger(TimerTrace.class);
+
+  // A reference to the current TimerNode
+  protected static ThreadLocal<TimerStack> curStack = new ThreadLocal<TimerStack>();
+
+  /**
+   * System property that controls whether this timer should be used or not. Set to "true" activates
+   * the timer. Set to "false" to disactivate.
+   */
+  public static final String ACTIVATE_PROPERTY = "beangle.profile.activate";
+
+  /**
+   * System property that controls the min time, that if exceeded will cause a log (at INFO level)
+   * to be created.
+   */
+  public static final String MIN_TIME = "beangle.profile.mintime";
+
+  /**
+   * Initialized in a static block, it can be changed at runtime by calling setActive(...)
+   */
+  private static boolean active;
+
+  /**
+   * Get the min time for this profiling, it searches for a System property
+   * 'beangle.profile.mintime' and default to 0.
+   */
+  private static int mintime;
+
+  static {
+    active = "true".equalsIgnoreCase(System.getProperty(ACTIVATE_PROPERTY));
+    try {
+      mintime = Integer.parseInt(System.getProperty(MIN_TIME, "0"));
+    } catch (NumberFormatException e) {
+    }
+  }
+
+  /**
+   * Create and start a performance profiling with the <code>name</code> given. Deal with
+   * profile hierarchy automatically, so caller don't have to be concern about it.
+   * 
+   * @param name profile name
+   */
+  public static void start(String name) {
+    if (!active) return;
+
+    TimerNode root = new TimerNode(name, System.currentTimeMillis());
+    TimerStack stack = (TimerStack) curStack.get();
+    if (null == stack) curStack.set(new TimerStack(root));
+    else stack.push(root);
+  }
+
+  /**
+   * End a preformance profiling with the <code>name</code> given. Deal with
+   * profile hierarchy automatically, so caller don't have to be concern about it.
+   */
+  public static void end() {
+    if (!active) return;
+
+    TimerStack stack = curStack.get();
+    if (null == stack) return;
+
+    TimerNode currentNode = stack.pop();
+
+    if (currentNode != null) {
+      TimerNode parent = stack.peek();
+      long total = currentNode.end();
+      // if we are the root timer, then print out the times
+      if (parent == null) {
+        printTimes(currentNode);
+        curStack.set(null); // for those servers that use thread pooling
+      } else {
+        if (total > mintime) parent.children.add(currentNode);
+      }
+    }
+  }
+
+  public void clear() {
+    curStack.set(null);
+  }
+
+  /**
+   * Do a log (at INFO level) of the time taken for this particular profiling.
+   * 
+   * @param currentTimer profiling timer bean
+   */
+  private static void printTimes(TimerNode currentTimer) {
+    if (logger.isInfoEnabled()) logger.info(currentTimer.getPrintable());
+
+  }
+
+  /**
+   * Get the min time for this profiling, it searches for a System property
+   * 'beangle.profile.mintime' and default to 0.
+   * 
+   * @return long
+   */
+  public static int getMinTime() {
+    return mintime;
+  }
+
+  /**
+   * Change mintime
+   * 
+   * @param mintime
+   */
+  public static void setMinTime(int mintime) {
+    System.setProperty(MIN_TIME, String.valueOf(mintime));
+    TimerTrace.mintime = mintime;
+  }
+
+  /**
+   * Determine if profiling is being activated, by searching for a system property
+   * 'beangle.profile.activate', default to false (profiling is off).
+   * 
+   * @return <tt>true</tt>, if active, <tt>false</tt> otherwise.
+   */
+  public static boolean isActive() {
+    return active;
+  }
+
+  /**
+   * Turn profiling on or off.
+   * 
+   * @param active
+   */
+  public static void setActive(boolean active) {
+    if (active) System.setProperty(ACTIVATE_PROPERTY, "true");
+    else System.clearProperty(ACTIVATE_PROPERTY);
+    TimerTrace.active = active;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/tuple/Pair.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/tuple/Pair.java
new file mode 100644
index 0000000..01ef701
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/tuple/Pair.java
@@ -0,0 +1,172 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.tuple;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import com.ekingstar.commons.lang.Objects;
+
+/**
+ * <p>
+ * A immutable pair consisting of two elements.
+ * </p>
+ * 
+ * @author chaostone
+ * @param <L> the left element type
+ * @param <R> the right element type
+ */
+public class Pair<L, R> implements Map.Entry<L, R>, Serializable {
+
+  private static final long serialVersionUID = -7643900124010501814L;
+
+  /** Left object */
+  public final L _1;
+  /** Right object */
+  public final R _2;
+
+  /**
+   * <p>
+   * Obtains an immutable pair of from two objects inferring the generic types.
+   * </p>
+   * <p>
+   * This factory allows the pair to be created using inference to obtain the generic types.
+   * </p>
+   * 
+   * @param <L> the left element type
+   * @param <R> the right element type
+   * @param left the left element, may be null
+   * @param right the right element, may be null
+   * @return a pair formed from the two parameters, not null
+   */
+  public static <L, R> Pair<L, R> of(L left, R right) {
+    return new Pair<L, R>(left, right);
+  }
+
+  /**
+   * Create a new pair instance.
+   * 
+   * @param left the left value, may be null
+   * @param right the right value, may be null
+   */
+  public Pair(L left, R right) {
+    super();
+    this._1 = left;
+    this._2 = right;
+  }
+
+  public L getLeft() {
+    return _1;
+  }
+
+  public R getRight() {
+    return _2;
+  }
+
+  /**
+   * <p>
+   * Throws {@code UnsupportedOperationException}.
+   * </p>
+   * <p>
+   * This pair is immutable, so this operation is not supported.
+   * </p>
+   * 
+   * @param value the value to set
+   * @return never
+   * @throws UnsupportedOperationException as this operation is not supported
+   */
+  public R setValue(R value) {
+    throw new UnsupportedOperationException();
+  }
+
+  public L get_1() {
+    return _1;
+  }
+
+  public R get_2() {
+    return _2;
+  }
+
+  /**
+   * <p>
+   * Gets the key from this pair.
+   * </p>
+   * <p>
+   * This method implements the {@code Map.Entry} interface returning the left element as the key.
+   * </p>
+   * 
+   * @return the left element as the key, may be null
+   */
+  public final L getKey() {
+    return _1;
+  }
+
+  /**
+   * <p>
+   * Gets the value from this pair.
+   * </p>
+   * <p>
+   * This method implements the {@code Map.Entry} interface returning the right element as the
+   * value.
+   * </p>
+   * 
+   * @return the right element as the value, may be null
+   */
+  public R getValue() {
+    return _2;
+  }
+
+  /**
+   * <p>
+   * Compares this pair to another based on the two elements.
+   * </p>
+   * 
+   * @param obj the object to compare to, null returns false
+   * @return true if the elements of the pair are equal
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) { return true; }
+    if (obj instanceof Map.Entry<?, ?>) {
+      Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
+      return Objects.equals(getKey(), other.getKey()) && Objects.equals(getValue(), other.getValue());
+    }
+    return false;
+  }
+
+  /**
+   * <p>
+   * Returns a suitable hash code. The hash code follows the definition in {@code Map.Entry}.
+   * </p>
+   * 
+   * @return the hash code
+   */
+  @Override
+  public int hashCode() {
+    // see Map.Entry API specification
+    return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode());
+  }
+
+  @Override
+  public String toString() {
+    return new StringBuilder().append('(').append(getLeft()).append(',').append(getRight()).append(')')
+        .toString();
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/lang/tuple/Triple.java b/tools/commons/src/main/java/com/ekingstar/commons/lang/tuple/Triple.java
new file mode 100644
index 0000000..3f6b11d
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/lang/tuple/Triple.java
@@ -0,0 +1,70 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.tuple;
+
+import com.ekingstar.commons.lang.Objects;
+
+public class Triple<X, Y, Z> {
+
+  public final X _1;
+  public final Y _2;
+  public final Z _3;
+
+  public Triple(X e1, Y e2, Z e3) {
+    this._1 = e1;
+    this._2 = e2;
+    this._3 = e3;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((_1 == null) ? 0 : _1.hashCode());
+    result = prime * result + ((_2 == null) ? 0 : _2.hashCode());
+    result = prime * result + ((_3 == null) ? 0 : _3.hashCode());
+    return result;
+  }
+
+  
+  public X get_1() {
+    return _1;
+  }
+
+  public Y get_2() {
+    return _2;
+  }
+
+  public Z get_3() {
+    return _3;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) return true;
+    if (obj == null) return false;
+    Triple<?, ?, ?> other = (Triple<?, ?, ?>) obj;
+    return Objects.equalsBuilder().add(_1, other._1).add(_2, other._2).add(_3, other._3).isEquals();
+  }
+
+  @Override
+  public String toString() {
+    return Objects.toStringBuilder(this).add("_1", _1).add("_2", _2).add("_3", _3).toString();
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/page/Limit.java b/tools/commons/src/main/java/com/ekingstar/commons/page/Limit.java
new file mode 100755
index 0000000..f2d03a8
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/page/Limit.java
@@ -0,0 +1,29 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.page;
+
+/**
+ * 查询中的数目限制
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface Limit {
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/page/Page.java b/tools/commons/src/main/java/com/ekingstar/commons/page/Page.java
new file mode 100755
index 0000000..5813e17
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/page/Page.java
@@ -0,0 +1,130 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.page;
+
+import java.util.List;
+
+/**
+ * 分页对象
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface Page<E> extends List<E> {
+  /** Constant <code>DEFAULT_PAGE_NUM=1</code> */
+  public static final int DEFAULT_PAGE_NUM = 1;
+
+  /** Constant <code>DEFAULT_PAGE_SIZE=20</code> */
+  public static final int DEFAULT_PAGE_SIZE = 20;
+
+  /**
+   * 第一页.
+   * 
+   * @return 1
+   */
+  int getFirstPageNo();
+
+  /**
+   * 最大页码
+   * 
+   * @return a int.
+   */
+  int getMaxPageNo();
+
+  /**
+   * 下一页页码
+   * 
+   * @return a int.
+   */
+  int getNextPageNo();
+
+  /**
+   * 上一页页码
+   * 
+   * @return a int.
+   */
+  int getPreviousPageNo();
+
+  /**
+   * 当前页码
+   * 
+   * @return a int.
+   */
+  int getPageNo();
+
+  /**
+   * 每页大小
+   * 
+   * @return a int.
+   */
+  int getPageSize();
+
+  /**
+   * 数据总量
+   * 
+   * @return a int.
+   */
+  int getTotal();
+
+  /**
+   * 下一页
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  Page<E> next();
+
+  /**
+   * 是否还有下一页
+   * 
+   * @return a boolean.
+   */
+  boolean hasNext();
+
+  /**
+   * 上一页
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  Page<E> previous();
+
+  /**
+   * 是否还有上一页
+   * 
+   * @return a boolean.
+   */
+  boolean hasPrevious();
+
+  /**
+   * 调转到指定页
+   * 
+   * @param pageNo a int.
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  Page<E> moveTo(int pageNo);
+
+  /**
+   * <p>
+   * getItems.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  List<E> getItems();
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/page/PageLimit.java b/tools/commons/src/main/java/com/ekingstar/commons/page/PageLimit.java
new file mode 100755
index 0000000..a59476c
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/page/PageLimit.java
@@ -0,0 +1,128 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.page;
+
+
+/**
+ * 查询分页限制
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class PageLimit implements Limit {
+
+  private int pageNo;
+
+  private int pageSize;
+
+  /**
+   * <p>
+   * Constructor for PageLimit.
+   * </p>
+   */
+  public PageLimit() {
+    super();
+  }
+
+  /**
+   * <p>
+   * Constructor for PageLimit.
+   * </p>
+   * 
+   * @param pageNo
+   *          a int.
+   * @param pageSize
+   *          a int.
+   */
+  public PageLimit(final int pageNo, final int pageSize) {
+    this.pageNo = pageNo;
+    this.pageSize = pageSize;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageSize</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageSize() {
+    return pageSize;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>pageSize</code>.
+   * </p>
+   * 
+   * @param pageSize
+   *          a int.
+   */
+  public void setPageSize(final int pageSize) {
+    this.pageSize = pageSize;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageNo() {
+    return pageNo;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>pageNo</code>.
+   * </p>
+   * 
+   * @param pageNo
+   *          a int.
+   */
+  public void setPageNo(final int pageNo) {
+    this.pageNo = pageNo;
+  }
+
+  /**
+   * <p>
+   * isValid.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isValid() {
+    return pageNo > 0 && pageSize > 0;
+  }
+
+  /**
+   * <p>
+   * toString.
+   * </p>
+   * 
+   * @see java.lang.Object#toString()
+   * @return a {@link java.lang.String} object.
+   */
+  public String toString() {
+    return new StringBuilder().append("pageNo:").append(pageNo).append(" pageSize:").append(pageSize)
+        .toString();
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/page/PageWapper.java b/tools/commons/src/main/java/com/ekingstar/commons/page/PageWapper.java
new file mode 100755
index 0000000..0c25f11
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/page/PageWapper.java
@@ -0,0 +1,267 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.page;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * <p>
+ * Abstract PageWapper class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public abstract class PageWapper<E> implements Page<E> {
+
+  private Page<E> page;
+
+  /**
+   * <p>
+   * getFirstPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getFirstPageNo() {
+    return 1;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>page</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<E> getPage() {
+    return page;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>page</code>.
+   * </p>
+   * 
+   * @param page a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public void setPage(Page<E> page) {
+    this.page = page;
+  }
+
+  /**
+   * <p>
+   * getItems.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<E> getItems() {
+    return page.getItems();
+  }
+
+  /**
+   * <p>
+   * iterator.
+   * </p>
+   * 
+   * @return a {@link java.util.Iterator} object.
+   */
+  public Iterator<E> iterator() {
+    return page.iterator();
+  }
+
+  /**
+   * <p>
+   * add.
+   * </p>
+   * 
+   * @param obj a E object.
+   * @return a boolean.
+   */
+  public boolean add(E obj) {
+    return page.add(obj);
+  }
+
+  /** {@inheritDoc} */
+  public boolean addAll(Collection<? extends E> datas) {
+    return page.addAll(datas);
+  }
+
+  /**
+   * <p>
+   * clear.
+   * </p>
+   */
+  public void clear() {
+    page.clear();
+  }
+
+  /** {@inheritDoc} */
+  public boolean contains(Object obj) {
+    return page.contains(obj);
+  }
+
+  /** {@inheritDoc} */
+  public boolean containsAll(Collection<?> datas) {
+    return page.containsAll(datas);
+  }
+
+  /**
+   * <p>
+   * isEmpty.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isEmpty() {
+    return page.isEmpty();
+  }
+
+  /**
+   * <p>
+   * size.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int size() {
+    return page.size();
+  }
+
+  /**
+   * <p>
+   * toArray.
+   * </p>
+   * 
+   * @return an array of {@link java.lang.Object} objects.
+   */
+  public Object[] toArray() {
+    return page.toArray();
+  }
+
+  /**
+   * <p>
+   * toArray.
+   * </p>
+   * 
+   * @param datas an array of T objects.
+   * @param <T> a T object.
+   * @return an array of T objects.
+   */
+  public <T> T[] toArray(T[] datas) {
+    return page.toArray(datas);
+  }
+
+  /** {@inheritDoc} */
+  public boolean remove(Object obj) {
+    return page.remove(obj);
+  }
+
+  /** {@inheritDoc} */
+  public boolean removeAll(Collection<?> datas) {
+    return page.removeAll(datas);
+  }
+
+  /** {@inheritDoc} */
+  public boolean retainAll(Collection<?> datas) {
+    return page.retainAll(datas);
+  }
+
+  /**
+   * <p>
+   * add.
+   * </p>
+   * 
+   * @param index a int.
+   * @param arg1 a E object.
+   */
+  public void add(int index, E arg1) {
+    page.add(index, arg1);
+  }
+
+  /** {@inheritDoc} */
+  public boolean addAll(int index, Collection<? extends E> arg1) {
+    return page.addAll(index, arg1);
+  }
+
+  /** {@inheritDoc} */
+  public E get(int index) {
+    return page.get(index);
+  }
+
+  /** {@inheritDoc} */
+  public int lastIndexOf(Object o) {
+    return page.lastIndexOf(o);
+  }
+
+  /**
+   * <p>
+   * listIterator.
+   * </p>
+   * 
+   * @return a {@link java.util.ListIterator} object.
+   */
+  public ListIterator<E> listIterator() {
+    return page.listIterator();
+  }
+
+  /** {@inheritDoc} */
+  public ListIterator<E> listIterator(int index) {
+    return page.listIterator(index);
+  }
+
+  /**
+   * <p>
+   * remove.
+   * </p>
+   * 
+   * @param index a int.
+   * @return a E object.
+   */
+  public E remove(int index) {
+    return page.remove(index);
+  }
+
+  /**
+   * <p>
+   * set.
+   * </p>
+   * 
+   * @param index a int.
+   * @param arg1 a E object.
+   * @return a E object.
+   */
+  public E set(int index, E arg1) {
+    return page.set(index, arg1);
+  }
+
+  /** {@inheritDoc} */
+  public List<E> subList(int fromIndex, int toIndex) {
+    return page.subList(fromIndex, toIndex);
+  }
+
+  /** {@inheritDoc} */
+  public int indexOf(Object o) {
+    return page.indexOf(o);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/page/PagedList.java b/tools/commons/src/main/java/com/ekingstar/commons/page/PagedList.java
new file mode 100755
index 0000000..f4f496b
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/page/PagedList.java
@@ -0,0 +1,197 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.page;
+
+import java.util.List;
+
+/**
+ * <p>
+ * PagedList class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class PagedList<E> extends PageWapper<E> {
+
+  private final List<E> datas;
+
+  private int pageNo = 0;
+
+  private int maxPageNo;
+
+  private int pageSize;
+
+  /**
+   * <p>
+   * Constructor for PagedList.
+   * </p>
+   * 
+   * @param datas a {@link java.util.List} object.
+   * @param pageSize a int.
+   */
+  public PagedList(List<E> datas, int pageSize) {
+    this(datas, new PageLimit(1, pageSize));
+  }
+
+  /**
+   * <p>
+   * Constructor for PagedList.
+   * </p>
+   * 
+   * @param datas a {@link java.util.List} object.
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public PagedList(List<E> datas, PageLimit limit) {
+    super();
+    this.datas = datas;
+    this.pageSize = limit.getPageSize();
+    this.pageNo = limit.getPageNo() - 1;
+    if (datas.size() <= pageSize) {
+      this.maxPageNo = 1;
+    } else {
+      final int remainder = datas.size() % pageSize;
+      final int quotient = datas.size() / pageSize;
+      this.maxPageNo = (0 == remainder) ? quotient : (quotient + 1);
+    }
+    this.next();
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>maxPageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getMaxPageNo() {
+    return maxPageNo;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageNo() {
+    return pageNo;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageSize</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageSize() {
+    return pageSize;
+  }
+
+  /**
+   * <p>
+   * getTotal.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getTotal() {
+    return datas.size();
+  }
+
+  /**
+   * <p>
+   * getNextPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getNextPageNo() {
+    return getPage().getNextPageNo();
+  }
+
+  /**
+   * <p>
+   * getPreviousPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getPreviousPageNo() {
+    return getPage().getPreviousPageNo();
+  }
+
+  /**
+   * <p>
+   * hasNext.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasNext() {
+    return getPageNo() < getMaxPageNo();
+  }
+
+  /**
+   * <p>
+   * hasPrevious.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasPrevious() {
+    return getPageNo() > 1;
+  }
+
+  /**
+   * <p>
+   * next.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<E> next() {
+    return moveTo(pageNo + 1);
+  }
+
+  /**
+   * <p>
+   * previous.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<E> previous() {
+    return moveTo(pageNo - 1);
+  }
+
+  /** {@inheritDoc} */
+  public Page<E> moveTo(int pageNo) {
+    if (pageNo < 1) { throw new RuntimeException("error pageNo:" + pageNo); }
+    this.pageNo = pageNo;
+    int toIndex = pageNo * pageSize;
+    SinglePage<E> newPage = new SinglePage<E>(pageNo, pageSize, datas.size(), datas.subList((pageNo - 1)
+        * pageSize, (toIndex < datas.size()) ? toIndex : datas.size()));
+    setPage(newPage);
+    return this;
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/page/Pages.java b/tools/commons/src/main/java/com/ekingstar/commons/page/Pages.java
new file mode 100755
index 0000000..67a64b4
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/page/Pages.java
@@ -0,0 +1,114 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.page;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * Pages class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class Pages {
+
+  private static final Page<Object> EMPTY_PAGE = new EmptyPage<Object>();
+
+  /**
+   * <p>
+   * emptyPage.
+   * </p>
+   * 
+   * @param <T> a T object.
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  @SuppressWarnings("unchecked")
+  public static final <T> Page<T> emptyPage() {
+    return (Page<T>) EMPTY_PAGE;
+  }
+
+  private static class EmptyPage<E> extends AbstractList<E> implements Page<E> {
+
+    public int getFirstPageNo() {
+      return 0;
+    }
+
+    public int getMaxPageNo() {
+      return 0;
+    }
+
+    public int getNextPageNo() {
+      return 0;
+    }
+
+    public int getPageNo() {
+      return 0;
+    }
+
+    public int getPageSize() {
+      return 0;
+    }
+
+    public int getPreviousPageNo() {
+      return 0;
+    }
+
+    public int getTotal() {
+      return 0;
+    }
+
+    public boolean hasNext() {
+      return false;
+    }
+
+    public boolean hasPrevious() {
+      return false;
+    }
+
+    public Page<E> next() {
+      return this;
+    }
+
+    public Page<E> previous() {
+      return this;
+    }
+
+    public E get(int index) {
+      return null;
+    }
+
+    public int size() {
+      return 0;
+    }
+
+    public Page<E> moveTo(int pageNo) {
+      return this;
+    }
+
+    public List<E> getItems() {
+      return new ArrayList<E>(0);
+    }
+
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/page/SinglePage.java b/tools/commons/src/main/java/com/ekingstar/commons/page/SinglePage.java
new file mode 100755
index 0000000..aaa948f
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/page/SinglePage.java
@@ -0,0 +1,451 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.page;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * 分页对象
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class SinglePage<E> implements Page<E> {
+
+  private int pageNo;
+
+  private int pageSize;
+
+  private int total;
+
+  private List<E> items;
+
+  /**
+   * <p>
+   * Constructor for SinglePage.
+   * </p>
+   */
+  public SinglePage() {
+    super();
+  }
+
+  /**
+   * <p>
+   * Constructor for SinglePage.
+   * </p>
+   * 
+   * @param pageNo a int.
+   * @param pageSize a int.
+   * @param total a int.
+   * @param dataItems a {@link java.util.List} object.
+   */
+  public SinglePage(int pageNo, int pageSize, int total, List<E> dataItems) {
+    this.items = dataItems;
+    if (pageSize < 1) {
+      this.pageSize = 2;
+    } else {
+      this.pageSize = pageSize;
+    }
+    if (pageNo < 1) {
+      this.pageNo = 1;
+    } else {
+      this.pageNo = pageNo;
+    }
+    this.total = total;
+  }
+
+  /**
+   * <p>
+   * getFirstPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getFirstPageNo() {
+    return 1;
+  }
+
+  /**
+   * <p>
+   * getMaxPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getMaxPageNo() {
+    if (getTotal() < getPageSize()) {
+      return 1;
+    } else {
+      final int remainder = getTotal() % getPageSize();
+      final int quotient = getTotal() / getPageSize();
+      return (0 == remainder) ? quotient : (quotient + 1);
+    }
+  }
+
+  /**
+   * <p>
+   * getNextPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getNextPageNo() {
+    if (getPageNo() == getMaxPageNo()) {
+      return getMaxPageNo();
+    } else {
+      return getPageNo() + 1;
+    }
+  }
+
+  /**
+   * <p>
+   * getPreviousPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getPreviousPageNo() {
+    if (getPageNo() == 1) {
+      return getPageNo();
+    } else {
+      return getPageNo() - 1;
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getPageNo() {
+    return pageNo;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageSize</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getPageSize() {
+    return pageSize;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>items</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public final List<E> getItems() {
+    return items;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>total</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public final int getTotal() {
+    return total;
+  }
+
+  /** {@inheritDoc} */
+  public boolean add(final Object obj) {
+    throw new RuntimeException("unsupported add");
+  }
+
+  /** {@inheritDoc} */
+  public boolean addAll(final Collection<? extends E> datas) {
+    throw new RuntimeException("unsupported addAll");
+  }
+
+  /**
+   * <p>
+   * clear.
+   * </p>
+   */
+  public void clear() {
+    throw new RuntimeException("unsupported clear");
+  }
+
+  /** {@inheritDoc} */
+  public boolean contains(final Object obj) {
+    return items.contains(obj);
+  }
+
+  /** {@inheritDoc} */
+  public boolean containsAll(final Collection<?> datas) {
+    return items.containsAll(datas);
+  }
+
+  /**
+   * <p>
+   * isEmpty.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isEmpty() {
+    return items.isEmpty();
+  }
+
+  /**
+   * <p>
+   * iterator.
+   * </p>
+   * 
+   * @return a {@link java.util.Iterator} object.
+   */
+  public Iterator<E> iterator() {
+    return items.iterator();
+  }
+
+  /** {@inheritDoc} */
+  public boolean remove(final Object obj) {
+    throw new RuntimeException("unsupported removeAll");
+  }
+
+  /** {@inheritDoc} */
+  public boolean removeAll(final Collection<?> datas) {
+    throw new RuntimeException("unsupported removeAll");
+  }
+
+  /** {@inheritDoc} */
+  public boolean retainAll(final Collection<?> datas) {
+    throw new RuntimeException("unsupported retailAll");
+  }
+
+  /**
+   * <p>
+   * size.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int size() {
+    return items.size();
+  }
+
+  /**
+   * <p>
+   * toArray.
+   * </p>
+   * 
+   * @return an array of {@link java.lang.Object} objects.
+   */
+  public Object[] toArray() {
+    return items.toArray();
+  }
+
+  /**
+   * <p>
+   * toArray.
+   * </p>
+   * 
+   * @param datas an array of T objects.
+   * @param <T> a T object.
+   * @return an array of T objects.
+   */
+  public <T> T[] toArray(final T[] datas) {
+    return items.toArray(datas);
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>pageNo</code>.
+   * </p>
+   * 
+   * @param pageNo a int.
+   */
+  public void setPageNo(final int pageNo) {
+    this.pageNo = pageNo;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>pageSize</code>.
+   * </p>
+   * 
+   * @param pageSize a int.
+   */
+  public void setPageSize(final int pageSize) {
+    this.pageSize = pageSize;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>total</code>.
+   * </p>
+   * 
+   * @param total a int.
+   */
+  public void setTotal(final int total) {
+    this.total = total;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>items</code>.
+   * </p>
+   * 
+   * @param dataItems a {@link java.util.List} object.
+   */
+  public void setItems(final List<E> dataItems) {
+    this.items = dataItems;
+  }
+
+  // dummy method
+  /**
+   * <p>
+   * hasNext.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasNext() {
+    return getMaxPageNo() > pageNo;
+  }
+
+  /**
+   * <p>
+   * hasPrevious.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasPrevious() {
+    return pageNo > 1;
+  }
+
+  /**
+   * <p>
+   * next.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<E> next() {
+    return this;
+  }
+
+  /**
+   * <p>
+   * previous.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<E> previous() {
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public Page<E> moveTo(int pageNo) {
+    return this;
+  }
+
+  /**
+   * <p>
+   * add.
+   * </p>
+   * 
+   * @param arg0 a int.
+   * @param arg1 a E object.
+   */
+  public void add(int arg0, E arg1) {
+    items.add(arg0, arg1);
+  }
+
+  /** {@inheritDoc} */
+  public E get(int index) {
+    return items.get(index);
+  }
+
+  /** {@inheritDoc} */
+  public int indexOf(Object o) {
+    return items.indexOf(o);
+  }
+
+  /** {@inheritDoc} */
+  public int lastIndexOf(Object o) {
+    return items.lastIndexOf(o);
+  }
+
+  /**
+   * <p>
+   * listIterator.
+   * </p>
+   * 
+   * @return a {@link java.util.ListIterator} object.
+   */
+  public ListIterator<E> listIterator() {
+    return items.listIterator();
+  }
+
+  /** {@inheritDoc} */
+  public ListIterator<E> listIterator(int index) {
+    return items.listIterator(index);
+  }
+
+  /**
+   * <p>
+   * remove.
+   * </p>
+   * 
+   * @param index a int.
+   * @return a E object.
+   */
+  public E remove(int index) {
+    return items.remove(index);
+  }
+
+  /** {@inheritDoc} */
+  public boolean addAll(int arg0, Collection<? extends E> arg1) {
+    return items.addAll(arg0, arg1);
+  }
+
+  /**
+   * <p>
+   * set.
+   * </p>
+   * 
+   * @param arg0 a int.
+   * @param arg1 a E object.
+   * @return a E object.
+   */
+  public E set(int arg0, E arg1) {
+    return items.set(arg0, arg1);
+  }
+
+  /** {@inheritDoc} */
+  public List<E> subList(int fromIndex, int toIndex) {
+    return items.subList(fromIndex, toIndex);
+  }
+
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/script/EvaluationException.java b/tools/commons/src/main/java/com/ekingstar/commons/script/EvaluationException.java
new file mode 100644
index 0000000..d572948
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/script/EvaluationException.java
@@ -0,0 +1,53 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.script;
+
+/**
+ * <p>
+ * EvaluationException class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: EvaluationException.java Mar 5, 2012 12:13:41 AM chaostone $
+ */
+public class EvaluationException extends RuntimeException {
+
+  private static final long serialVersionUID = 7366966661039007890L;
+
+  /**
+   * <p>
+   * Constructor for EvaluationException.
+   * </p>
+   * 
+   * @param cause a {@link java.lang.Throwable} object.
+   */
+  public EvaluationException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * Constructs the exception using a message and cause.
+   * 
+   * @param message the message to use
+   * @param cause the underlying cause
+   */
+  public EvaluationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}
diff --git a/tools/commons/src/main/java/com/ekingstar/commons/script/ExpressionEvaluator.java b/tools/commons/src/main/java/com/ekingstar/commons/script/ExpressionEvaluator.java
new file mode 100644
index 0000000..a3b3782
--- /dev/null
+++ b/tools/commons/src/main/java/com/ekingstar/commons/script/ExpressionEvaluator.java
@@ -0,0 +1,60 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.script;
+
+
+
+/**
+ * 表达式执行器
+ * 
+ * @author chaostone
+ * @version $Id: ExpressionEvaluator.java Mar 5, 2012 12:13:41 AM chaostone $
+ * @since 2012-03-05
+ */
+public interface ExpressionEvaluator {
+  /**
+   * Parse the expression
+   * @param exp
+   * @throws EvaluationException
+   */
+  void parse(String exp) throws EvaluationException;
+  /**
+   * <p>
+   * Eval a expression within context
+   * </p>
+   * 
+   * @param exp a java's expression
+   * @param root params.
+   * @return evaluate result
+   */
+  Object eval(String exp, Object root);
+
+  /**
+   * <p>
+   * Eval a expression within context,Return the given type
+   * </p>
+   * 
+   * @param exp a java's expression
+   * @param root params.
+   * @param resultType What type of the result
+   * @return evaluate result
+   */
+  <T> T eval(String exp, Object root, Class<T> resultType);
+
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/bean/PropertyUtilsTest.java b/tools/commons/src/test/java/com/ekingstar/commons/bean/PropertyUtilsTest.java
new file mode 100644
index 0000000..918b16c
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/bean/PropertyUtilsTest.java
@@ -0,0 +1,52 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.bean.PropertyUtils;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.testbean.TestBean;
+
+@Test
+public class PropertyUtilsTest {
+
+  public void testSet() {
+    TestBean bean = new TestBean();
+    PropertyUtils.setProperty(bean, "intValue", 2);
+    assertEquals(bean.getIntValue(), 2);
+
+    PropertyUtils.setProperty(bean, "nested.datas(key)", "value");
+    assertEquals(PropertyUtils.getProperty(bean, "nested.datas(key)"), "value");
+
+    PropertyUtils.setProperty(bean, "nested.id", 4L);
+    assertEquals(PropertyUtils.getProperty(bean, "nested.id"), 4L);
+  }
+
+  public static void main(String[] args) {
+    TestBean bean = new TestBean();
+    PropertyUtils.setProperty(bean, "nested.datas(key)", "value");
+    Assert.isTrue("value".equals(PropertyUtils.getProperty(bean, "nested.datas(key)")));
+
+    PropertyUtils.setProperty(bean, "nested.id", 4L);
+    Assert.isTrue(PropertyUtils.getProperty(bean, "nested.id").equals(4L));
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/bean/comparators/PropertyComparatorTest.java b/tools/commons/src/test/java/com/ekingstar/commons/bean/comparators/PropertyComparatorTest.java
new file mode 100755
index 0000000..d7bacf9
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/bean/comparators/PropertyComparatorTest.java
@@ -0,0 +1,32 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.bean.comparators;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+@Test
+public class PropertyComparatorTest {
+
+  public void testSingleProperty() {
+    Logger logger = LoggerFactory.getLogger(PropertyComparatorTest.class);
+    logger.info("dd");
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/collection/MapConverterTest.java b/tools/commons/src/test/java/com/ekingstar/commons/collection/MapConverterTest.java
new file mode 100755
index 0000000..a554e83
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/collection/MapConverterTest.java
@@ -0,0 +1,93 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.collection;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+import java.sql.Date;
+import java.util.Calendar;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.MapConverter;
+
+@Test
+public class MapConverterTest {
+
+  Map<String, Object> datas = CollectUtils.newHashMap();
+  MapConverter converter = new MapConverter();
+
+  @BeforeClass
+  public void setUp() {
+    datas.put("empty1", "");
+    datas.put("empty2", null);
+    datas.put("empty3", new String[] { "" });
+  }
+
+  public void testGetDate() {
+    int year = 2010;
+    int month = 9;
+    int day = 1;
+    datas.put("birthday", year + "-" + month + "-" + day);
+
+    Date birthday = converter.get(datas, "birthday", Date.class);
+    Calendar calendar = Calendar.getInstance();
+    calendar.setTime(birthday);
+    assertEquals(calendar.get(Calendar.YEAR), year);
+    assertEquals(calendar.get(Calendar.MONTH), month - 1);
+    assertEquals(calendar.get(Calendar.DAY_OF_MONTH), day);
+
+    datas.put("birthday", new Date[] { birthday });
+    Date birthday2 = converter.get(datas, "birthday", Date.class);
+    assertEquals(birthday, birthday2);
+  }
+
+  public void testGetArray() {
+    datas.put("name", new String[] { "me" });
+    Object name = converter.get(datas, "name");
+    assertNotNull(name);
+    assertEquals(name, "me");
+
+  }
+
+  public void testGetNull() {
+    boolean empty1 = converter.getBool(datas, "empty1");
+    assertFalse(empty1);
+    empty1 = converter.getBool(datas, "empty2");
+    assertFalse(empty1);
+    Boolean emptyB1 = converter.getBoolean(datas, "empty1");
+    assertNull(emptyB1);
+    emptyB1 = converter.getBoolean(datas, "empty2");
+    assertNull(emptyB1);
+
+    Long id = converter.getLong(datas, "empty1");
+    assertNull(id);
+    id = converter.getLong(datas, "empty2");
+    assertNull(id);
+
+    id = converter.getLong(datas, "empty3");
+    assertNull(id);
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/collection/OrderTest.java b/tools/commons/src/test/java/com/ekingstar/commons/collection/OrderTest.java
new file mode 100755
index 0000000..b6d07ae
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/collection/OrderTest.java
@@ -0,0 +1,84 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.collection;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+
+public class OrderTest {
+  @Test
+  public void testToString1() throws Exception {
+    List<Order> sorts = Order.parse(null);
+    if (sorts.isEmpty()) {
+      sorts.add(new Order(" teachPlan.grade desc "));
+      sorts.add(new Order(" teachPlan.major.code "));
+      // sorts.add(new Order("teachPlan.stdType"));
+    }
+    assertEquals(Order.toSortString(sorts), "order by teachPlan.grade desc,teachPlan.major.code");
+  }
+
+  @Test
+  public void testToString() throws Exception {
+    List<Order> sorts = CollectUtils.newArrayList();
+    sorts.add(new Order("id", false));
+    sorts.add(Order.asc("name"));
+    assertEquals(Order.toSortString(sorts), "order by id desc,name");
+  }
+
+  public void testParserOrder() throws Exception {
+    List<Order> orders = Order.parse("std.code asc");
+    for (final Order order : orders) {
+      assertTrue(order.isAscending());
+      assertEquals(order.getProperty(), "std.code");
+    }
+  }
+
+  @Test
+  public void testParserMutiOrder() throws Exception {
+    List<Order> sorts = Order
+        .parse("activity.time.year desc,activity.time.validWeeksNum,activity.time.weekId desc");
+    assertEquals(sorts.size(), 3);
+    Order order = (Order) sorts.get(0);
+    assertEquals(order.getProperty(), "activity.time.year");
+    assertFalse(order.isAscending());
+    order = (Order) sorts.get(1);
+    assertEquals(order.getProperty(), "activity.time.validWeeksNum");
+    assertTrue(order.isAscending());
+    order = (Order) sorts.get(2);
+    assertEquals(order.getProperty(), "activity.time.weekId");
+    assertFalse(order.isAscending());
+  }
+
+  @Test
+  public void testParserComplexOrder() {
+    List<Order> sorts = Order.parse("(case when ware.price is null then 0 else ware.price end) desc");
+    assertEquals(sorts.size(), 1);
+    Order order = (Order) sorts.get(0);
+    assertEquals(order.getProperty(), "(case when ware.price is null then 0 else ware.price end)");
+    assertFalse(order.isAscending());
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/conversion/ConversionTest.java b/tools/commons/src/test/java/com/ekingstar/commons/conversion/ConversionTest.java
new file mode 100644
index 0000000..3adef6f
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/conversion/ConversionTest.java
@@ -0,0 +1,53 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.conversion.impl.DefaultConversion;
+
+@Test
+public class ConversionTest {
+
+  public void testConvert() {
+    DefaultConversion con = new DefaultConversion();
+    Assert.assertEquals(con.convert(2.5f, Integer.class), new Integer(2));
+    Assert.assertEquals(con.convert("", Boolean.class),null);
+    Assert.assertEquals((boolean)con.convert(null, boolean.class),false);
+  }
+  
+  public void testConvertArray() {
+    DefaultConversion con = new DefaultConversion();
+    Assert.assertEquals(con.convert(new String[] { "2", "3" }, Integer[].class), new Integer[] { 2, 3 });
+  }
+
+  public void testConvertPrimitive() {
+    DefaultConversion con = new DefaultConversion();
+    Assert.assertEquals((int) con.convert("2", int.class), 2);
+
+    Assert.assertEquals(con.convert(3, Integer.class), new Integer(3));
+  }
+
+  public void testConvertPrimitiveArray() {
+    DefaultConversion con = new DefaultConversion();
+    Assert.assertEquals((float[]) con.convert(new String[] { "2", "3.4" }, float[].class), new float[] { 2f,
+        3.4f });
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/DateConverterTest.java b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/DateConverterTest.java
new file mode 100755
index 0000000..c492d6b
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/DateConverterTest.java
@@ -0,0 +1,57 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.conversion.Converter;
+import com.ekingstar.commons.conversion.converter.String2DateConverter;
+
+public class DateConverterTest {
+  @Test
+  public void testConvertoDate() throws Exception {
+    String date1 = "19800909";
+    converToDate(date1, 1980, 8, 9);
+    date1 = "1980-09-09";
+    converToDate(date1, 1980, 8, 9);
+  }
+
+  private void converToDate(String dateStr, int year, int month, int day) {
+    Converter<String, Date> c = new String2DateConverter().getConverter(Date.class);
+    Date date = c.apply(dateStr);
+    Calendar calendar = new GregorianCalendar();
+    calendar.setTime(date);
+    assertEquals(calendar.get(Calendar.YEAR), year);
+    assertEquals(calendar.get(Calendar.MONTH), month);
+    assertEquals(calendar.get(Calendar.DAY_OF_MONTH), day);
+  }
+
+  public void testNormalize() {
+    assertEquals("1980-09-01", String2DateConverter.normalize("1980-9-1"));
+    assertEquals("1980-09-01", String2DateConverter.normalize("1980-09-1"));
+    assertEquals("1980-09-01", String2DateConverter.normalize("1980-9-01"));
+    assertEquals("1980-09-01", String2DateConverter.normalize("1980-09-01"));
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/DefaultConverterTest.java b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/DefaultConverterTest.java
new file mode 100644
index 0000000..aa2980e
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/DefaultConverterTest.java
@@ -0,0 +1,38 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.conversion.Conversion;
+import com.ekingstar.commons.conversion.impl.DefaultConversion;
+
+@Test
+public class DefaultConverterTest {
+
+  public void testConvertNull() {
+    Conversion conversion = DefaultConversion.Instance;
+    Assert.assertNull(conversion.convert("", Long.class));
+    Assert.assertNull(conversion.convert((String) null, Long.class));
+    Assert.assertNull(conversion.convert("abc", Long.class));
+    Assert.assertEquals((Object) conversion.convert("1", Long.class), (Object) 1L);
+    Assert.assertEquals((Object) conversion.convert(1L, Long.class), (Object) 1L);
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/EnumConverterTest.java b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/EnumConverterTest.java
new file mode 100644
index 0000000..c8df788
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/EnumConverterTest.java
@@ -0,0 +1,39 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.conversion.impl.DefaultConversion;
+import com.ekingstar.commons.lang.testbean.TestEnum;
+
+/**
+ * @author chaostone
+ * @since 3.0.0
+ */
+@Test
+public class EnumConverterTest {
+
+  public void testConvertEnum() throws IllegalAccessException, InvocationTargetException {
+    Assert.assertEquals(DefaultConversion.Instance.convert("Private", TestEnum.class), TestEnum.Private);
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/Object2StringConverterTest.java b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/Object2StringConverterTest.java
new file mode 100644
index 0000000..891b762
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/conversion/converter/Object2StringConverterTest.java
@@ -0,0 +1,42 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.conversion.converter;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.conversion.converter.Object2StringConverter;
+
+/**
+ * @author chaostone
+ * @since 3.3.7
+ */
+@Test
+public class Object2StringConverterTest {
+
+  public void testConvert() {
+    Object2StringConverter converter = new Object2StringConverter();
+    assertNull(converter.apply(null), null);
+    assertEquals(converter.apply("abc"), "abc");
+    assertEquals(converter.apply(new Object[] { 1, 3, "abc" }), "1,3,abc");
+    assertEquals(converter.apply(new Object[] { 1, }), "1");
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/BitStringsTest.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/BitStringsTest.java
new file mode 100755
index 0000000..aff268e
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/BitStringsTest.java
@@ -0,0 +1,35 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.lang.BitStrings;
+
+public class BitStringsTest {
+
+  @Test
+  public void binValueOf() {
+    assertEquals(BitStrings.binValueOf("00000000000000000000000000000000011111111111111111111"), 1048575);
+
+    assertEquals(BitStrings.binValueOf("00000000000000000000000000000000000011100000000000000"), 114688);
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/CalendarTest.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/CalendarTest.java
new file mode 100644
index 0000000..4d5ff6f
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/CalendarTest.java
@@ -0,0 +1,42 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import static org.testng.Assert.assertTrue;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.lang.Dates;
+
+/**
+ * @author chaostone
+ * @version $Id: CalendarTest.java Jul 26, 2011 4:12:17 PM chaostone $
+ */
+@Test
+public class CalendarTest {
+
+  public void testRoll() {
+    Calendar calendar = Calendar.getInstance();
+    Date ajusted = Dates.rollMinutes(calendar.getTime(), -30);
+    assertTrue(ajusted.before(calendar.getTime()));
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/MapTest.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/MapTest.java
new file mode 100644
index 0000000..dcc02c6
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/MapTest.java
@@ -0,0 +1,41 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.collection.CollectUtils;
+
+@Test
+public class MapTest {
+
+  /**
+   * test map's key set
+   */
+  public void testRemove() {
+    Map<String, String> favorates = CollectUtils.newHashMap();
+    favorates.put("john", "sports,music");
+    favorates.put("mack", "food");
+    favorates.keySet().remove("john");
+    org.testng.Assert.assertTrue(favorates.size() == 1);
+  }
+
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/ObjectsTest.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/ObjectsTest.java
new file mode 100755
index 0000000..3ca0bde
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/ObjectsTest.java
@@ -0,0 +1,33 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.lang.Objects;
+
+@Test
+public class ObjectsTest {
+
+  public void testNullEquals() {
+    assertTrue(Objects.equals(null, null));
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/StringsTest.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/StringsTest.java
new file mode 100755
index 0000000..6e9a1ea
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/StringsTest.java
@@ -0,0 +1,107 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang;
+
+import static com.ekingstar.commons.lang.Strings.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+@Test
+public class StringsTest {
+
+  public void testCount() {
+    String targetStr = "11001101101111";
+    String searchStr = "11";
+    assertEquals(count(targetStr, searchStr), 5);
+  }
+
+  public void testUnCamel() {
+    assertEquals(unCamel("MyCountInI_cbc", '-'), "my-count-ini_cbc");
+    assertEquals(unCamel("MyCounT", '_'), "my_count");
+    assertEquals(unCamel("MYCOUNT", '-'), "mycount");
+    assertEquals(unCamel("parent_id", '_'), "parent_id");
+    assertEquals(unCamel("parentId", '_'), "parent_id");
+  }
+
+  public void testSplit2() {
+    String target = " abc ,; def ,;; ghi\r\n opq";
+    String[] codes = split(target);
+    assertEquals(codes.length, 4);
+    assertEquals(codes[3], "opq");
+  }
+
+  public void testIsEqualSeq() {
+    String first = "123,4546,";
+    String second = ",4546,123";
+    assertTrue(isEqualSeq(first, second));
+    assertTrue(isEqualSeq(first, second, ","));
+  }
+
+  public void testMergeSeq() {
+    String first = ",1,2,";
+    String second = "3,";
+    String third = "";
+    String forth = null;
+    assertTrue(isEqualSeq(mergeSeq(first, second), ",1,2,3,"));
+    assertTrue(isEqualSeq(mergeSeq(first, second), ",1,2,3,"));
+    assertTrue(isEqualSeq(mergeSeq(first, third), ",1,2,"));
+    assertTrue(isEqualSeq(mergeSeq(first, forth), ",1,2,"));
+  }
+
+  public void testSplitNumSeq() throws Exception {
+    String a = "1-2,3,5-9,3,";
+    Integer[] nums = splitNumSeq(a);
+    assertEquals(nums.length, 8);
+  }
+
+  public void testMisc() {
+    assertEquals(",2,", subtractSeq("1,2", "1"));
+    assertFalse(isEqualSeq(",2005-9,", ",2005-9,2006-9,"));
+  }
+
+  public void testRepeat() {
+    assertEquals("", repeat("ad", 0));
+    assertEquals("adadad", repeat("ad", 3));
+  }
+
+  public void testSplit() {
+    assertEquals(new String[] { "a", "b", "c" }, split("a.b.c.", '.'));
+    assertEquals(new String[] { "a", "b", "c" }, split(".a..b.c", '.'));
+    assertEquals(new String[] { "a:b:c" }, split("a:b:c", '.'));
+    assertEquals(new String[] {}, split("", (String)null));
+    assertEquals(new String[] { "abc", "def" }, split("abc def", (String)null));
+    assertEquals(new String[] { "abc", "def" }, split("abc def", " "));
+    assertEquals(new String[] { "ab", "cd", "ef" }, split("ab:cd:ef", ":"));
+  }
+
+  public void testReplace() {
+    assertEquals(replace(null, "x", null), null);
+    assertEquals(replace("", "dd", "xx"), "");
+    assertEquals(replace("any", null, "xx"), "any");
+    assertEquals(replace("any", "d", null), "any");
+    assertEquals(replace("any", "", "dd"), "any");
+    assertEquals(replace("aba", "a", null), "aba");
+    assertEquals(replace("aba", "a", ""), "b");
+    assertEquals(replace("aba", "a", "z"), "zbz");
+
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/reflect/BridgeMethodTest.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/reflect/BridgeMethodTest.java
new file mode 100644
index 0000000..8a81c5e
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/reflect/BridgeMethodTest.java
@@ -0,0 +1,52 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.reflect;
+
+import java.lang.reflect.Method;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+@Test
+public class BridgeMethodTest {
+
+  public void testBridgeMethods() {
+
+    for (Method m : Dog.class.getMethods()) {
+      if (m.getName().equals("getAge") && null == m.getReturnType()) {
+        if (m.getReturnType().equals(Integer.class)) Assert.assertFalse(m.isBridge());
+
+        else if (m.getReturnType().equals(Number.class)) {
+          Assert.assertTrue(m.isBridge());
+          Assert.assertEquals(m.getDeclaringClass(), Dog.class);
+        }
+      }
+    }
+  }
+}
+
+interface Animal {
+  Number getAge();
+}
+
+class Dog implements Animal {
+  public Integer getAge() {
+    return 0;
+  }
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/NestedBean.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/NestedBean.java
new file mode 100644
index 0000000..8bde946
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/NestedBean.java
@@ -0,0 +1,48 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.testbean;
+
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+
+public class NestedBean {
+
+  Long id;
+  
+  Map<Object,Object> datas=CollectUtils.newHashMap();
+
+  public Long getId() {
+    return id;
+  }
+
+  public void setId(Long id) {
+    this.id = id;
+  }
+
+  public Map<Object, Object> getDatas() {
+    return datas;
+  }
+
+  public void setDatas(Map<Object, Object> datas) {
+    this.datas = datas;
+  }
+  
+  
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/TestBean.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/TestBean.java
new file mode 100644
index 0000000..3deb866
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/TestBean.java
@@ -0,0 +1,74 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.testbean;
+
+public class TestBean {
+  private Integer id;
+  private String name;
+  private int intValue;
+  TestEnum testEnum;
+
+  private NestedBean nested= new NestedBean();
+  
+  public Integer getId() {
+    return id;
+  }
+
+  public void setId(Integer id) {
+    this.id = id;
+  }
+
+  public TestEnum getTestEnum() {
+    return testEnum;
+  }
+
+  public void setTestEnum(TestEnum testEnum) {
+    this.testEnum = testEnum;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public int getIntValue() {
+    return intValue;
+  }
+
+  public void setIntValue(int intValue) {
+    this.intValue = intValue;
+  }
+
+  public String methodWithManyArguments(int i, float f, Integer I, Float F, TestBean c, TestBean c1,
+      TestBean c2) {
+    return "test";
+  }
+
+  public NestedBean getNested() {
+    return nested;
+  }
+
+  public void setNested(NestedBean nested) {
+    this.nested = nested;
+  }
+  
+}
diff --git a/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/TestEnum.java b/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/TestEnum.java
new file mode 100644
index 0000000..f71122f
--- /dev/null
+++ b/tools/commons/src/test/java/com/ekingstar/commons/lang/testbean/TestEnum.java
@@ -0,0 +1,24 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.commons.lang.testbean;
+
+public enum TestEnum {
+
+  Public, Protected, Private;
+}
diff --git a/tools/hqlbuilder/pom.xml b/tools/hqlbuilder/pom.xml
new file mode 100755
index 0000000..ab5ad47
--- /dev/null
+++ b/tools/hqlbuilder/pom.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<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.ekingstar.hibernate</groupId>
+	<artifactId>hql-builder</artifactId>
+	<version>1.0.0</version>
+	<name>HQL Builder</name>
+	<properties>
+		<mockito.version>1.9.5</mockito.version>
+		<testng.version>6.5.2</testng.version>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<downloadJavadocs>true</downloadJavadocs>
+		<logback.version>1.0.7</logback.version>
+		<slf4j.version>1.6.6</slf4j.version>
+	</properties>
+	<distributionManagement>
+		<repository>
+			<id>ekingstar-releases</id>
+			<name>internal release</name>
+			<url>http://app.supwisdom.com:81/artifactory/libs-release-local</url>
+		</repository>
+		<snapshotRepository>
+			<id>ekingstar-snapshots</id>
+			<name>internal Snapshots</name>
+			<url>http://app.supwisdom.com:81/artifactory/libs-snapshot-local</url>
+		</snapshotRepository>
+		<downloadUrl>http://app.supwisdom.com:81/artifactory</downloadUrl>
+	</distributionManagement>
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.slf4j</groupId>
+				<artifactId>slf4j-api</artifactId>
+				<version>1.6.6</version>
+			</dependency>
+			<dependency>
+				<groupId>ch.qos.logback</groupId>
+				<artifactId>logback-core</artifactId>
+				<version>1.0.7</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>ch.qos.logback</groupId>
+				<artifactId>logback-classic</artifactId>
+				<version>1.0.7</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.mockito</groupId>
+				<artifactId>mockito-all</artifactId>
+				<version>1.9.5</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.testng</groupId>
+				<artifactId>testng</artifactId>
+				<version>6.5.2</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>com.ekingstar.commons</groupId>
+				<artifactId>commons</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+	<dependencies>
+		<dependency>
+			<groupId>com.ekingstar.commons</groupId>
+			<artifactId>commons</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.jxls</groupId>
+			<artifactId>jxls-core</artifactId>
+			<version>1.0.3</version>
+			<scope>compile</scope>
+			<optional>true</optional>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.6.6</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.testng</groupId>
+			<artifactId>testng</artifactId>
+			<version>6.5.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-all</artifactId>
+			<version>1.9.5</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-core</artifactId>
+			<version>1.0.7</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-classic</artifactId>
+			<version>1.0.7</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-core</artifactId>
+			<version>4.2.4.Final</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.0</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+					<encoding>UTF-8</encoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>jar-no-fork</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-javadocs</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<!-- explicitly define maven-deploy-plugin after other to force exec 
+					order -->
+				<artifactId>maven-deploy-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>deploy</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>deploy</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
+
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/QuerySupport.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/QuerySupport.java
new file mode 100644
index 0000000..97ec96a
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/QuerySupport.java
@@ -0,0 +1,159 @@
+package com.ekingstar.hibernate;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.Query;
+import org.hibernate.Session;
+
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.builder.Condition;
+
+ public final class QuerySupport {
+    private QuerySupport() {
+      super();
+    }
+
+    private static Query buildHibernateQuery(com.ekingstar.hibernate.query.Query<?> bquery,
+        final Session session) {
+      Query hibernateQuery = null;
+      if (bquery.getLang().equals(com.ekingstar.hibernate.query.Lang.HQL)) {
+        hibernateQuery = session.createQuery(bquery.getStatement());
+      } else {
+        hibernateQuery = session.createSQLQuery(bquery.getStatement());
+      }
+      if (bquery.isCacheable()) hibernateQuery.setCacheable(bquery.isCacheable());
+      setParameter(hibernateQuery, bquery.getParams());
+      return hibernateQuery;
+    }
+
+    /**
+     * 统计该查询的记录数
+     * 
+     * @param limitQuery
+     * @param hibernateSession
+     * @return data count
+     */
+    public static int count(final com.ekingstar.hibernate.query.LimitQuery<?> limitQuery,
+        final Session hibernateSession) {
+      final com.ekingstar.hibernate.query.Query<?> cntQuery = limitQuery.getCountQuery();
+      if (null == cntQuery) {
+        Query hibernateQuery = buildHibernateQuery(limitQuery, hibernateSession);
+        return hibernateQuery.list().size();
+      } else {
+        Query hibernateQuery = buildHibernateQuery(cntQuery, hibernateSession);
+        final Number count = (Number) (hibernateQuery.uniqueResult());
+        if (null == count) {
+          return 0;
+        } else {
+          return count.intValue();
+        }
+      }
+    }
+
+    /**
+     * 查询结果集
+     * 
+     * @param query
+     * @param session
+     * @return result list
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> find(final com.ekingstar.hibernate.query.Query<T> query, final Session session) {
+      if (query instanceof LimitQuery<?>) {
+        LimitQuery<T> limitQuery = (LimitQuery<T>) query;
+        Query hibernateQuery = buildHibernateQuery(limitQuery, session);
+        if (null == limitQuery.getLimit()) {
+          return hibernateQuery.list();
+        } else {
+          final PageLimit limit = limitQuery.getLimit();
+          hibernateQuery.setFirstResult((limit.getPageNo() - 1) * limit.getPageSize()).setMaxResults(
+              limit.getPageSize());
+          return hibernateQuery.list();
+        }
+      } else {
+        return buildHibernateQuery(query, session).list();
+      }
+    }
+
+    /**
+     * 为query设置JPA style参数
+     * 
+     * @param query
+     * @param argument
+     */
+    public static Query setParameter(final Query query, final Object[] argument) {
+      if (argument != null && argument.length > 0) {
+        for (int i = 0; i < argument.length; i++)
+          query.setParameter(String.valueOf(i + 1), argument[i]);
+      }
+      return query;
+    }
+
+    /**
+     * 为query设置参数
+     * 
+     * @param query
+     * @param parameterMap
+     * @return query
+     */
+    public static Query setParameter(final Query query, final Map<String, Object> parameterMap) {
+      if (parameterMap != null && !parameterMap.isEmpty()) {
+        for (final Iterator<String> ite = parameterMap.keySet().iterator(); ite.hasNext();) {
+          final String parameterName = ite.next();
+          if (null == parameterName) {
+            break;
+          }
+          final Object parameterValue = parameterMap.get(parameterName);
+          if (null == parameterValue) {
+            query.setParameter(parameterName, (Object) null);
+          } else if (parameterValue.getClass().isArray()) {
+            query.setParameterList(parameterName, (Object[]) parameterValue);
+          } else if (parameterValue instanceof Collection<?>) {
+            query.setParameterList(parameterName, (Collection<?>) parameterValue);
+          } else {
+            query.setParameter(parameterName, parameterValue);
+          }
+        }
+      }
+      return query;
+    }
+
+    /**
+     * 针对查询条件绑定查询的值
+     * 
+     * @param query
+     * @param conditions
+     */
+    public static void bindValues(final Query query, final List<Condition> conditions) {
+      int position = 0;
+      boolean hasInterrogation = false; // 含有问号
+      for (final Iterator<Condition> iter = conditions.iterator(); iter.hasNext();) {
+        final Condition condition = (Condition) iter.next();
+        if (Strings.contains(condition.getContent(), "?")) {
+          hasInterrogation = true;
+        }
+        if (hasInterrogation) {
+          for (final Iterator<?> iterator = condition.getParams().iterator(); iterator.hasNext();) {
+            query.setParameter(position++, iterator.next());
+          }
+        } else {
+          final List<String> paramNames = condition.getParamNames();
+          for (int i = 0; i < paramNames.size(); i++) {
+            final String name = paramNames.get(i);
+            final Object value = condition.getParams().get(i);
+            if (value.getClass().isArray()) {
+              query.setParameterList(name, (Object[]) value);
+            } else if (value instanceof Collection<?>) {
+              query.setParameterList(name, (Collection<?>) value);
+            } else {
+              query.setParameter(name, value);
+            }
+          }
+        }
+      }
+    }
+  }
\ No newline at end of file
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EmptyKeyPredicate.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EmptyKeyPredicate.java
new file mode 100755
index 0000000..d3b6eb3
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EmptyKeyPredicate.java
@@ -0,0 +1,48 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.lang.functor.Predicate;
+
+/**
+ * <p>
+ * EmptyKeyPredicate class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class EmptyKeyPredicate implements Predicate<Object> {
+
+  public Boolean apply(final Object value) {
+    boolean success = false;
+    if (null != value) {
+      if (value instanceof String) {
+        success = Strings.isEmpty((String) value);
+      } else if (value instanceof Number) {
+        success = (0 == ((Number) value).intValue());
+      } else {
+        throw new RuntimeException("unsupported key type");
+      }
+    }
+    return success;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EntityUtils.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EntityUtils.java
new file mode 100644
index 0000000..421269c
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EntityUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 实体类辅助工具箱
+ * 
+ * @author chaostone 2005-10-31
+ * @version $Id: $
+ */
+public final class EntityUtils {
+
+  private static final Logger logger = LoggerFactory.getLogger(EntityUtils.class);
+
+  private EntityUtils() {
+  }
+
+  /**
+   * <p>
+   * getCommandName.
+   * </p>
+   * 
+   * @param clazz a {@link java.lang.Class} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getCommandName(Class<?> clazz) {
+    String name = clazz.getName();
+    return Strings.uncapitalize(name.substring(name.lastIndexOf('.') + 1));
+  }
+
+  /**
+   * <p>
+   * getCommandName.
+   * </p>
+   * 
+   * @param entityName a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getCommandName(String entityName) {
+    return Strings.uncapitalize(Strings.substringAfterLast(entityName, "."));
+  }
+
+  /**
+   * <p>
+   * getCommandName.
+   * </p>
+   * 
+   * @param obj a {@link java.lang.Object} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getCommandName(Object obj) {
+    String name = obj.getClass().getName();
+    int dollar = name.indexOf('$');
+    if (-1 == dollar) {
+      name = name.substring(name.lastIndexOf('.') + 1);
+    } else {
+      name = name.substring(name.lastIndexOf('.') + 1, dollar);
+    }
+    return Strings.uncapitalize(name);
+  }
+
+  /**
+   * 为了取出CGLIB代来的代理命名
+   * 
+   * @param clazz a {@link java.lang.Class} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getEntityClassName(Class<?> clazz) {
+    String name = clazz.getName();
+    int dollar = name.indexOf('$');
+    if (-1 == dollar) {
+      return name;
+    } else {
+      return name.substring(0, dollar);
+    }
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityKeyPredicate.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityKeyPredicate.java
new file mode 100755
index 0000000..69d6866
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityKeyPredicate.java
@@ -0,0 +1,40 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import com.ekingstar.commons.lang.functor.NotEmptyStringPredicate;
+import com.ekingstar.commons.lang.functor.NotZeroNumberPredicate;
+import com.ekingstar.commons.lang.functor.Predicate;
+
+/**
+ * 判断实体类中的主键是否是有效主键
+ * 
+ * @author chaostone
+ */
+public class ValidEntityKeyPredicate implements Predicate<Object> {
+
+  public Boolean apply(Object value) {
+    if (null == value) return Boolean.FALSE;
+    if (value instanceof Number) return NotZeroNumberPredicate.Instance.apply((Number) value);
+    return NotEmptyStringPredicate.Instance.apply(value.toString());
+  }
+
+  public static final ValidEntityKeyPredicate Instance = new ValidEntityKeyPredicate();
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityPredicate.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityPredicate.java
new file mode 100755
index 0000000..0c307da
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityPredicate.java
@@ -0,0 +1,57 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import java.io.Serializable;
+
+import com.ekingstar.commons.bean.PropertyUtils;
+import com.ekingstar.commons.lang.functor.Predicate;
+
+/**
+ * 有效实体判断谓词
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class ValidEntityPredicate implements Predicate<Object> {
+
+  public Boolean apply(final Object value) {
+    if (null == value) { return false; }
+    try {
+      Serializable key = PropertyUtils.getProperty(value, "id");
+      return ValidEntityKeyPredicate.Instance.apply(key);
+    } catch (Exception e) {
+      return false;
+    }
+  }
+
+  /** Constant <code>INSTANCE</code> */
+  public static final ValidEntityPredicate Instance = new ValidEntityPredicate();
+
+  /**
+   * <p>
+   * getInstance.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.entity.ValidEntityPredicate} object.
+   */
+  public static ValidEntityPredicate getInstance() {
+    return Instance;
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Lang.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Lang.java
new file mode 100755
index 0000000..fc14f24
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Lang.java
@@ -0,0 +1,48 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+/**
+ * <p>
+ * Lang class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public enum Lang {
+  SQL("sql"), HQL("hql");
+  private final String lang;
+
+  private Lang(String name) {
+    this.lang = name;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>lang</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getLang() {
+    return lang;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/LimitQuery.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/LimitQuery.java
new file mode 100755
index 0000000..0f982cd
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/LimitQuery.java
@@ -0,0 +1,60 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+import com.ekingstar.commons.page.PageLimit;
+
+/**
+ * <p>
+ * LimitQuery interface.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface LimitQuery<T> extends Query<T> {
+
+  /**
+   * <p>
+   * getLimit.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  PageLimit getLimit();
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   * @return a {@link com.ekingstar.hibernate.query.LimitQuery} object.
+   */
+  LimitQuery<T> limit(final PageLimit limit);
+
+  /**
+   * <p>
+   * getCountQuery.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  Query<T> getCountQuery();
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Query.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Query.java
new file mode 100755
index 0000000..16e53cb
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Query.java
@@ -0,0 +1,62 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+import java.util.Map;
+
+/**
+ * 数据查询接口
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface Query<T> {
+
+  /**
+   * Returns query statement.
+   */
+  String getStatement();
+
+  /**
+   * <p>
+   * getParams.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  Map<String, Object> getParams();
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  boolean isCacheable();
+
+  /**
+   * <p>
+   * getLang.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  Lang getLang();
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/QueryBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/QueryBuilder.java
new file mode 100755
index 0000000..d65ba0f
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/QueryBuilder.java
@@ -0,0 +1,72 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+import java.util.Map;
+
+import com.ekingstar.commons.page.PageLimit;
+
+/**
+ * <p>
+ * QueryBuilder interface.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface QueryBuilder<T> {
+
+  /**
+   * <p>
+   * build.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  Query<T> build();
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   * @return a {@link com.ekingstar.hibernate.query.QueryBuilder} object.
+   */
+  QueryBuilder<T> limit(PageLimit limit);
+
+  /**
+   * <p>
+   * getParams.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  Map<String, Object> getParams();
+
+  /**
+   * <p>
+   * params.
+   * </p>
+   * 
+   * @param newParams a {@link java.util.Map} object.
+   * @return a {@link com.ekingstar.hibernate.query.QueryBuilder} object.
+   */
+  QueryBuilder<T> params(Map<String, Object> newParams);
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQuery.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQuery.java
new file mode 100755
index 0000000..4986430
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQuery.java
@@ -0,0 +1,174 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Map;
+
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.QueryBuilder;
+
+/**
+ * 抽象查询
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public abstract class AbstractQuery<T> implements QueryBuilder<T> {
+  /** query 查询语句 */
+  protected String queryStr;
+
+  /** count 计数语句 */
+  protected String countStr;
+
+  /** 分页 */
+  protected PageLimit limit;
+
+  /** 参数 */
+  protected Map<String, Object> params;
+
+  /** 缓存查询结果 */
+  protected boolean cacheable = false;
+
+  /**
+   * Returns limit
+   */
+  public PageLimit getLimit() {
+    return limit;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public void setLimit(final PageLimit limit) {
+    this.limit = limit;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>params</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> getParams() {
+    return params;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>countStr</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getCountStr() {
+    return countStr;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>countStr</code>.
+   * </p>
+   * 
+   * @param countStr a {@link java.lang.String} object.
+   */
+  public void setCountStr(final String countStr) {
+    this.countStr = countStr;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>queryStr</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getQueryStr() {
+    return queryStr;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>queryStr</code>.
+   * </p>
+   * 
+   * @param queryStr a {@link java.lang.String} object.
+   */
+  public void setQueryStr(final String queryStr) {
+    this.queryStr = queryStr;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>params</code>.
+   * </p>
+   * 
+   * @param params a {@link java.util.Map} object.
+   */
+  public void setParams(final Map<String, Object> params) {
+    this.params = params;
+  }
+
+  /**
+   * <p>
+   * toQueryString.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public abstract String toQueryString();
+
+  /**
+   * <p>
+   * toCountString.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String toCountString() {
+    return countStr;
+  }
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isCacheable() {
+    return cacheable;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>cacheable</code>.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   */
+  public void setCacheable(final boolean cacheable) {
+    this.cacheable = cacheable;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQueryBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQueryBuilder.java
new file mode 100755
index 0000000..7a66f9c
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQueryBuilder.java
@@ -0,0 +1,193 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+import com.ekingstar.hibernate.query.Query;
+import com.ekingstar.hibernate.query.QueryBuilder;
+
+/**
+ * <p>
+ * Abstract AbstractQueryBuilder class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public abstract class AbstractQueryBuilder<T> implements QueryBuilder<T> {
+
+  /** Constant <code>INNER_JOIN=" left join "</code> */
+  public static final String INNER_JOIN = " left join ";
+
+  /** Constant <code>OUTER_JOIN=" outer join "</code> */
+  public static final String OUTER_JOIN = " outer join ";
+
+  /** Constant <code>LEFT_OUTER_JOIN=" left outer join "</code> */
+  public static final String LEFT_OUTER_JOIN = " left outer join ";
+
+  /** Constant <code>RIGHT_OUTER_JOIN=" right outer join "</code> */
+  public static final String RIGHT_OUTER_JOIN = " right outer join ";
+
+  /** query 查询语句 */
+  protected String statement;
+
+  /** 分页 */
+  protected PageLimit limit;
+
+  /** 参数 */
+  protected Map<String, Object> params;
+
+  protected String select;
+
+  protected String from;
+
+  /** 别名 */
+  protected String alias;
+
+  protected List<Condition> conditions = CollectUtils.newArrayList();
+
+  protected List<Order> orders = CollectUtils.newArrayList();
+
+  protected List<String> groups = CollectUtils.newArrayList();
+
+  protected String having;
+
+  /** 缓存查询结果 */
+  protected boolean cacheable = false;
+
+  /**
+   * Returns params.
+   */
+  public Map<String, Object> getParams() {
+    return (null == params) ? Conditions.getParamMap(conditions) : CollectUtils.newHashMap(params);
+  }
+
+  /**
+   * Return entity's alias
+   */
+  public String getAlias() {
+    return alias;
+  }
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isCacheable() {
+    return cacheable;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public PageLimit getLimit() {
+    return limit;
+  }
+
+  /**
+   * <p>
+   * build.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  public Query<T> build() {
+    QueryBean<T> queryBean = new QueryBean<T>();
+    queryBean.setStatement(genStatement());
+    queryBean.setParams(getParams());
+    if (null != limit) {
+      queryBean.setLimit(new PageLimit(limit.getPageNo(), limit.getPageSize()));
+    }
+    queryBean.setCountStatement(genCountStatement());
+    queryBean.setCacheable(cacheable);
+    queryBean.setLang(getLang());
+    return queryBean;
+  }
+
+  /**
+   * <p>
+   * getLang.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  abstract protected Lang getLang();
+
+  /**
+   * 生成查询语句（如果查询语句已经存在则不进行生成）
+   */
+  protected String genStatement() {
+    if (Strings.isNotEmpty(statement)) return statement;
+    else return genQueryStatement(true);
+  }
+
+  /**
+   * <p>
+   * genCountStatement.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  abstract protected String genCountStatement();
+
+  /**
+   * <p>
+   * genQueryStatement.
+   * </p>
+   * 
+   * @param hasOrder a boolean.
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genQueryStatement(final boolean hasOrder) {
+    if (null == from) return statement;
+    final StringBuilder buf = new StringBuilder(50);
+    buf.append((select == null) ? "" : (select + " ")).append(from);
+    if (!conditions.isEmpty()) buf.append(" where ").append(Conditions.toQueryString(conditions));
+
+    if (!groups.isEmpty()) {
+      buf.append(" group by ");
+      for (final String groupBy : groups)
+        buf.append(groupBy).append(',');
+      buf.deleteCharAt(buf.length() - 1);
+    }
+    if (hasOrder && !CollectUtils.isEmpty(orders)) buf.append(' ').append(Order.toSortString(orders));
+
+    if (null != having) buf.append(" having ").append(having);
+    return buf.toString();
+  }
+
+  public List<Condition> getConditions() {
+    return conditions;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Condition.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Condition.java
new file mode 100755
index 0000000..35f44f9
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Condition.java
@@ -0,0 +1,324 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 查询条件 使用例子如下
+ * <p>
+ * <blockquote>
+ * 
+ * <pre>
+ *      new Condition(&quot;std.id=?&quot;,new Long(2));
+ *      或者 Condition(&quot;std.id=:std_id&quot;,new Long(2));
+ *      ?绑定单值.命名参数允许绑定多值.但是只能由字母,数组和下划线组成
+ *      一组condition只能采取上面一种形式
+ * </pre>
+ * 
+ * </blockquote>
+ * <p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class Condition {
+
+  private final String content;
+
+  private final List<Object> params = new ArrayList<Object>(1);
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   */
+  public Condition(final String content) {
+    this.content = content;
+  }
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   */
+  public Condition(final String content, Object param1) {
+    this.content = content;
+    params.add(param1);
+  }
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   */
+  public Condition(final String content, Object param1, Object param2) {
+    this(content, param1, param2, null);
+  }
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @param param3 a {@link java.lang.Object} object.
+   */
+  public Condition(final String content, Object param1, Object param2, Object param3) {
+    this.content = content;
+    if (null != param1) {
+      params.add(param1);
+    }
+    if (null != param2) {
+      params.add(param2);
+    }
+    if (null != param3) {
+      params.add(param3);
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>content</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getContent() {
+    return content;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>params</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<Object> getParams() {
+    return params;
+  }
+
+  /**
+   * <p>
+   * isNamed.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isNamed() {
+    return !Strings.contains(content, "?");
+  }
+
+  /**
+   * 得到查询条件中所有的命名参数.
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<String> getParamNames() {
+    if (!Strings.contains(content, ":")) { return Collections.emptyList(); }
+    final List<String> params = new ArrayList<String>();
+    int index = 0;
+    do {
+      final int colonIndex = content.indexOf(':', index);
+      if (-1 == colonIndex) {
+        break;
+      }
+      index = colonIndex + 1;
+      while (index < content.length()) {
+        final char c = content.charAt(index);
+        if (isValidIdentifierStarter(c)) {
+          index++;
+        } else {
+          break;
+        }
+      }
+      final String paramName = content.substring(colonIndex + 1, index);
+      if (!params.contains(paramName)) {
+        params.add(paramName);
+      }
+    } while (index < content.length());
+    return params;
+  }
+
+  private static boolean isValidIdentifierStarter(final char ch) {
+    return (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_') || ('0' <= ch && ch <= '9'));
+  }
+
+  /**
+   * <p>
+   * param.
+   * </p>
+   * 
+   * @param value a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public Condition param(final Object value) {
+    params.add(value);
+    return this;
+  }
+
+  /**
+   * <p>
+   * params.
+   * </p>
+   * 
+   * @param values a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public Condition params(final List<?> values) {
+    params.clear();
+    params.addAll(values);
+    return this;
+  }
+
+  /**
+   * <p>
+   * toString.
+   * </p>
+   * 
+   * @see java.lang.Object#toString()
+   * @return a {@link java.lang.String} object.
+   */
+  public String toString() {
+    final StringBuilder str = new StringBuilder(content).append(" ");
+    for (final Object value : params) {
+      str.append(value);
+    }
+    return str.toString();
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(final Object obj) {
+    if (null == getContent() || !(obj instanceof Condition)) {
+      return false;
+    } else {
+      return getContent().equals(((Condition) obj).getContent());
+    }
+  }
+
+  /**
+   * <p>
+   * hashCode.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int hashCode() {
+    if (null == content) {
+      return 0;
+    } else {
+      return content.hashCode();
+    }
+  }
+
+  // 以下是几个方便的方法
+  /**
+   * <p>
+   * eq.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition eq(final String content, final Number value) {
+    return new Condition(content + " = " + value);
+  }
+
+  /**
+   * <p>
+   * eq.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition eq(final String content, final String value) {
+    return new Condition(content + " = '" + value + "'");
+  }
+
+  /**
+   * <p>
+   * le.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition le(final String content, final Number value) {
+    return new Condition(content + " <= " + value);
+  }
+
+  /**
+   * <p>
+   * ge.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition ge(final String content, final Number value) {
+    return new Condition(content + " >= " + value);
+  }
+
+  /**
+   * <p>
+   * ne.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition ne(final String content, final Number value) {
+    return new Condition(content + " <> " + value);
+  }
+
+  /**
+   * <p>
+   * like.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition like(final String content, final String value) {
+    return new Condition(content + " like '%" + value + "%'");
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Conditions.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Conditions.java
new file mode 100755
index 0000000..75603ec
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Conditions.java
@@ -0,0 +1,123 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 条件提取辅助类
+ * 
+ * @author chaostone
+ */
+public final class Conditions {
+  private static final Logger logger = LoggerFactory.getLogger(Conditions.class);
+
+  private Conditions() {
+    super();
+  }
+
+  public static Condition and(Condition... conditions) {
+    return concat(Arrays.asList(conditions), "and");
+  }
+
+  public static Condition and(List<Condition> conditions) {
+    return concat(conditions, "and");
+  }
+
+  public static Condition or(Condition... conditions) {
+    return concat(Arrays.asList(conditions), "or");
+  }
+
+  public static Condition or(List<Condition> conditions) {
+    return concat(conditions, "or");
+  }
+
+  static Condition concat(List<Condition> conditions, String andor) {
+    Assert.isTrue(!conditions.isEmpty(), "conditions shouldn't be empty!");
+    if (conditions.size() == 1) return conditions.get(0);
+    StringBuffer sb = new StringBuffer();
+    List<Object> params = CollectUtils.newArrayList();
+    sb.append("(");
+    for (Condition con : conditions) {
+      sb.append(" " + andor + " (");
+      sb.append(con.getContent());
+      sb.append(')');
+      params.addAll(con.getParams());
+    }
+    sb.append(")");
+    sb.replace(0, (" " + andor + " ").length() + 1, "(");
+    return new Condition(sb.toString()).params(params);
+  }
+
+  public static String toQueryString(final List<Condition> conditions) {
+    if (null == conditions || conditions.isEmpty()) { return ""; }
+    final StringBuilder buf = new StringBuilder("");
+    for (final Iterator<Condition> iter = conditions.iterator(); iter.hasNext();) {
+      final Condition con = iter.next();
+      buf.append('(').append(con.getContent()).append(')');
+      if (iter.hasNext()) {
+        buf.append(" and ");
+      }
+    }
+    return buf.toString();
+  }
+
+  /**
+   * 获得条件的绑定参数映射
+   * 
+   * @param conditions
+   */
+  public static Map<String, Object> getParamMap(final List<Condition> conditions) {
+    final Map<String, Object> params = new HashMap<String, Object>();
+    for (final Condition con : conditions) {
+      params.putAll(getParamMap(con));
+    }
+    return params;
+  }
+
+  /**
+   * 获得条件的绑定参数映射
+   * 
+   * @param condition
+   */
+  public static Map<String, Object> getParamMap(final Condition condition) {
+    final Map<String, Object> params = new HashMap<String, Object>();
+    if (!Strings.contains(condition.getContent(), "?")) {
+      final List<String> paramNames = condition.getParamNames();
+      if (paramNames.size() > condition.getParams().size()) { throw new RuntimeException(
+          "condition params not set [" + condition.getContent() + "] with value:" + condition.getParams()); }
+      for (int i = 0; i < paramNames.size(); i++) {
+        params.put(paramNames.get(i), condition.getParams().get(i));
+      }
+    }
+    return params;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/OqlBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/OqlBuilder.java
new file mode 100755
index 0000000..5e11130
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/OqlBuilder.java
@@ -0,0 +1,561 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import static com.ekingstar.commons.lang.Strings.concat;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.entity.EntityUtils;
+import com.ekingstar.hibernate.query.Lang;
+
+/**
+ * 实体类查询 Object Query Language Builder
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class OqlBuilder<T> extends AbstractQueryBuilder<T> {
+
+  /** 查询实体类 */
+  protected Class<T> entityClass;
+
+  /**
+   * <p>
+   * Constructor for OqlBuilder.
+   * </p>
+   */
+  protected OqlBuilder() {
+    super();
+  }
+
+  /**
+   * <p>
+   * hql.
+   * </p>
+   * 
+   * @param hql a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public static <E> OqlBuilder<E> hql(final String hql) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.statement = hql;
+    return query;
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public static <E> OqlBuilder<E> from(final String from) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.newFrom(from);
+    return query;
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param entityName a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  @SuppressWarnings("unchecked")
+  public static <E> OqlBuilder<E> from(final String entityName, final String alias) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.alias = alias;
+    query.select = "select " + alias;
+    query.from = concat("from ", entityName, " ", alias);
+    return query;
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param entityClass a {@link java.lang.Class} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public static <E> OqlBuilder<E> from(final Class<E> entityClass) {
+    return from(entityClass, EntityUtils.getCommandName(entityClass.getName()));
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param entityClass a {@link java.lang.Class} object.
+   * @param alias a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  @SuppressWarnings("unchecked")
+  public static <E> OqlBuilder<E> from(final Class<E> entityClass, final String alias) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.entityClass = entityClass;
+    query.alias = alias;
+    query.select = "select " + alias;
+    query.from = concat("from ", entityClass.getName(), " ", alias);
+    return query;
+  }
+
+  /**
+   * <p>
+   * alias.
+   * </p>
+   * 
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> alias(final String alias) {
+    this.alias = alias;
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> join(final String path, final String alias) {
+    from = concat(from, " join ", path, " ", alias);
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param joinMode a {@link java.lang.String} object.
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> join(final String joinMode, final String path, final String alias) {
+    from = concat(from, " ", joinMode, " join ", path, " ", alias);
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public OqlBuilder<T> params(final Map<String, Object> params) {
+    this.params = CollectUtils.newHashMap(params);
+    return this;
+  }
+
+  /**
+   * <p>
+   * param.
+   * </p>
+   * 
+   * @param name a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> param(String name, Object value) {
+    if (null == this.params) {
+      params = new HashMap<String, Object>();
+    }
+    params.put(name, value);
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public OqlBuilder<T> limit(final PageLimit limit) {
+    this.limit = limit;
+    return this;
+  }
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param pageNo a int.
+   * @param pageSize a int.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> limit(final int pageNo, final int pageSize) {
+    this.limit = new PageLimit(pageNo, pageSize);
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> cacheable() {
+    this.cacheable = true;
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> cacheable(final boolean cacheable) {
+    this.cacheable = cacheable;
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param condition a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final Condition condition) {
+    if (Strings.isNotEmpty(statement)) { throw new RuntimeException(
+        "cannot add condition to a exists statement"); }
+    conditions.add(condition);
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content) {
+    return where(new Condition(content));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content, Object param1) {
+    return where(new Condition(content, param1));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content, Object param1, Object param2) {
+    return where(new Condition(content, param1, param2, null));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @param param3 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content, Object param1, Object param2, Object param3) {
+    return where(new Condition(content, param1, param2, param3));
+  }
+
+  /**
+   * 添加一组条件<br>
+   * query中不能添加条件集合作为一个条件,因此这里命名没有采用有区别性的addAll
+   * 
+   * @param cons a {@link java.util.Collection} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final Collection<Condition> cons) {
+    conditions.addAll(cons);
+    return this;
+  }
+
+  /**
+   * 声明排序字符串
+   * 
+   * @param orderBy 排序字符串
+   * @return 查询构建器
+   */
+  public OqlBuilder<T> orderBy(final String orderBy) {
+    return orderBy(Order.parse(orderBy));
+  }
+
+  /**
+   * 指定排序字符串的位置
+   * 
+   * @param index 从0开始
+   * @param orderBy 排序字符串
+   * @return 查询构建器
+   */
+  public OqlBuilder<T> orderBy(final int index, final String orderBy) {
+    if (null != orders) {
+      if (Strings.isNotEmpty(statement)) { throw new RuntimeException(
+          "cannot add order by to a exists statement."); }
+      this.orders.addAll(index, Order.parse(orderBy));
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param order a {@link com.ekingstar.commons.collection.Order} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> orderBy(final Order order) {
+    if (null != order) { return orderBy(Collections.singletonList(order)); }
+    return this;
+  }
+
+  /**
+   * <p>
+   * cleanOrders.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> clearOrders() {
+    this.orders.clear();
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> orderBy(final List<Order> orders) {
+    if (null != orders) {
+      if (Strings.isNotEmpty(statement)) { throw new RuntimeException(
+          "cannot add order by to a exists statement."); }
+      this.orders.addAll(orders);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * select.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> select(final String what) {
+    if (null == what) {
+      this.select = null;
+    } else {
+      if (what.toLowerCase().trim().startsWith("select")) {
+        this.select = what;
+      } else {
+        this.select = "select " + what;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * newFrom.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> newFrom(final String from) {
+    if (null == from) {
+      this.from = null;
+    } else {
+      if (Strings.contains(from.toLowerCase(), "from")) {
+        this.from = from;
+      } else {
+        this.from = "from " + from;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * groupBy.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> groupBy(final String what) {
+    if (Strings.isNotEmpty(what)) {
+      groups.add(what);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * Having subclause.
+   * </p>
+   * 
+   * @param what having subclause
+   * @return this
+   */
+  public OqlBuilder<T> having(final String what) {
+    Assert.isTrue(null != groups && !groups.isEmpty());
+    if (Strings.isNotEmpty(what)) having = what;
+    return this;
+  }
+
+  /**
+   * 形成计数查询语句，如果不能形成，则返回""
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genCountStatement() {
+    StringBuilder countString = new StringBuilder("select count(*) ");
+    // 原始查询语句
+    final String genQueryStr = genQueryStatement(false);
+    if (Strings.isEmpty(genQueryStr)) { return ""; }
+    final String lowerCaseQueryStr = genQueryStr.toLowerCase();
+
+    if (Strings.contains(lowerCaseQueryStr, " group ")) { return ""; }
+    if (Strings.contains(lowerCaseQueryStr, " union ")) { return ""; }
+
+    final int indexOfFrom = findIndexOfFrom(lowerCaseQueryStr);
+    final String selectWhat = lowerCaseQueryStr.substring(0, indexOfFrom);
+    final int indexOfDistinct = selectWhat.indexOf("distinct");
+    // select distinct a from table;
+    if (-1 != indexOfDistinct) {
+      if (Strings.contains(selectWhat, ",")) {
+        return "";
+      } else {
+        countString = new StringBuilder("select count(");
+        countString.append(genQueryStr.substring(indexOfDistinct, indexOfFrom)).append(") ");
+      }
+    }
+
+    int orderIdx = genQueryStr.lastIndexOf(" order ");
+    if (-1 == orderIdx) orderIdx = genQueryStr.length();
+    countString.append(genQueryStr.substring(indexOfFrom, orderIdx));
+    return countString.toString();
+  }
+
+  /**
+   * Find index of from
+   * 
+   * @param query
+   * @return -1 or from index
+   */
+  private int findIndexOfFrom(String query) {
+    if (query.startsWith("from")) return 0;
+    int fromIdx = query.indexOf(" from ");
+    if (-1 == fromIdx) return -1;
+    final int first = query.substring(0, fromIdx).indexOf("(");
+    if (first > 0) {
+      int leftCnt = 1;
+      int i = first + 1;
+      while (leftCnt != 0 && i < query.length()) {
+        if (query.charAt(i) == '(') leftCnt++;
+        else if (query.charAt(i) == ')') leftCnt--;
+        i++;
+      }
+      if (leftCnt > 0) return -1;
+      else {
+        fromIdx = query.indexOf(" from ", i);
+        return (fromIdx == -1) ? -1 : fromIdx + 1;
+      }
+    } else {
+      return fromIdx + 1;
+    }
+  }
+
+  /**
+   * <p>
+   * forEntity.
+   * </p>
+   * 
+   * @param entityClass a {@link java.lang.Class} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> forEntity(final Class<T> entityClass) {
+    this.entityClass = entityClass;
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected Lang getLang() {
+    return Lang.HQL;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>entityClass</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.Class} object.
+   */
+  public Class<T> getEntityClass() {
+    return entityClass;
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/QueryBean.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/QueryBean.java
new file mode 100755
index 0000000..5dda29d
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/QueryBean.java
@@ -0,0 +1,198 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Map;
+
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.Query;
+
+/**
+ * <p>
+ * QueryBean class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class QueryBean<T> implements LimitQuery<T> {
+
+  private Lang lang;
+
+  private String statement;
+
+  private String countStatement;
+
+  private PageLimit limit;
+
+  private boolean cacheable;
+
+  private Map<String, Object> params;
+
+  /**
+   * Returns count query {@link com.ekingstar.hibernate.query.Query}.
+   */
+  public Query<T> getCountQuery() {
+    if (Strings.isEmpty(countStatement)) { return null; }
+    QueryBean<T> bean = new QueryBean<T>();
+    bean.setStatement(countStatement);
+    bean.setLang(lang);
+    bean.setParams(params);
+    bean.setCacheable(cacheable);
+    return bean;
+  }
+
+  /**
+   * Returns statement.
+   */
+  public String getStatement() {
+    return statement;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>countStatement</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getCountStatement() {
+    return countStatement;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public PageLimit getLimit() {
+    return limit;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>params</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> getParams() {
+    return params;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>statement</code>.
+   * </p>
+   * 
+   * @param statement a {@link java.lang.String} object.
+   */
+  public void setStatement(String statement) {
+    this.statement = statement;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>countStatement</code>.
+   * </p>
+   * 
+   * @param countStatement a {@link java.lang.String} object.
+   */
+  public void setCountStatement(String countStatement) {
+    this.countStatement = countStatement;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public void setLimit(PageLimit limit) {
+    this.limit = limit;
+  }
+
+  /** {@inheritDoc} */
+  public LimitQuery<T> limit(PageLimit limit) {
+    this.limit = new PageLimit(limit.getPageNo(), limit.getPageSize());
+    return this;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>cacheable</code>.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   */
+  public void setCacheable(boolean cacheable) {
+    this.cacheable = cacheable;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>params</code>.
+   * </p>
+   * 
+   * @param params a {@link java.util.Map} object.
+   */
+  public void setParams(Map<String, Object> params) {
+    this.params = params;
+  }
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isCacheable() {
+    return cacheable;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>lang</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  public Lang getLang() {
+    return lang;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>lang</code>.
+   * </p>
+   * 
+   * @param lang a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  public void setLang(Lang lang) {
+    this.lang = lang;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlBuilder.java
new file mode 100755
index 0000000..42d8bf0
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlBuilder.java
@@ -0,0 +1,384 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+
+/**
+ * sql查询
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class SqlBuilder extends AbstractQueryBuilder<Object[]> {
+  /**
+   * <p>
+   * sql.
+   * </p>
+   * 
+   * @param queryStr a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public static SqlBuilder sql(final String queryStr) {
+    SqlBuilder sqlQuery = new SqlBuilder();
+    sqlQuery.statement = queryStr;
+    return sqlQuery;
+  }
+
+  /**
+   * <p>
+   * genCountStatement.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genCountStatement() {
+    return "select count(*) from (" + genQueryStatement(false) + ")";
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected Lang getLang() {
+    return Lang.SQL;
+  }
+
+  /**
+   * <p>
+   * alias.
+   * </p>
+   * 
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder alias(final String alias) {
+    this.alias = alias;
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder join(final String path, final String alias) {
+    from += " join " + path + " " + alias;
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param joinMode a {@link java.lang.String} object.
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder join(final String joinMode, final String path, final String alias) {
+    from += " " + joinMode + " join " + path + " " + alias;
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public SqlBuilder params(final Map<String, Object> params) {
+    this.params = CollectUtils.newHashMap(params);
+    ;
+    return this;
+  }
+
+  /**
+   * <p>
+   * param.
+   * </p>
+   * 
+   * @param name a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder param(String name, Object value) {
+    if (null == this.params) {
+      params = new HashMap<String, Object>();
+    }
+    params.put(name, value);
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public SqlBuilder limit(final PageLimit limit) {
+    this.limit = limit;
+    return this;
+  }
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param pageNo a int.
+   * @param pageSize a int.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder limit(final int pageNo, final int pageSize) {
+    this.limit = new PageLimit(pageNo, pageSize);
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder cacheable() {
+    this.cacheable = true;
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder cacheable(final boolean cacheable) {
+    this.cacheable = cacheable;
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param condition a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final Condition condition) {
+    conditions.add(condition);
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content) {
+    return where(new Condition(content));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content, Object param1) {
+    return where(new Condition(content, param1));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content, Object param1, Object param2) {
+    return where(new Condition(content, param1, param2, null));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @param param3 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content, Object param1, Object param2, Object param3) {
+    return where(new Condition(content, param1, param2, param3));
+  }
+
+  /**
+   * 添加一组条件<br>
+   * query中不能添加条件集合作为一个条件,因此这里命名没有采用有区别性的addAll
+   * 
+   * @param cons a {@link java.util.Collection} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final Collection<Condition> cons) {
+    conditions.addAll(cons);
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param orderBy a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder orderBy(final String orderBy) {
+    this.orders.addAll(Order.parse(orderBy));
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param order a {@link com.ekingstar.commons.collection.Order} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder orderBy(final Order order) {
+    if (null != order) {
+      this.orders.add(order);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * cleanOrders.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder clearOrders() {
+    this.orders.clear();
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder orderBy(final List<Order> orders) {
+    if (null != orders) {
+      this.orders.addAll(orders);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * select.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder select(final String what) {
+    if (null == what) {
+      this.select = null;
+    } else {
+      if (Strings.contains(what.toLowerCase(), "select")) {
+        this.select = what;
+      } else {
+        this.select = "select " + what;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * newFrom.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder newFrom(final String from) {
+    if (null == from) {
+      this.from = null;
+    } else {
+      if (Strings.contains(from.toLowerCase(), "from")) {
+        this.from = from;
+      } else {
+        this.from = " from " + from;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * groupBy.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder groupBy(final String what) {
+    if (Strings.isNotEmpty(what)) groups.add(what);
+    return this;
+  }
+
+  /**
+   * <p>
+   * Having subclause.
+   * </p>
+   * 
+   * @param what having subclause
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public SqlBuilder having(final String what) {
+    Assert.isTrue(null != groups && !groups.isEmpty());
+    if (Strings.isNotEmpty(what)) having = what;
+    return this;
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlQuery.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlQuery.java
new file mode 100755
index 0000000..bc632c3
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlQuery.java
@@ -0,0 +1,389 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+import com.ekingstar.hibernate.query.Query;
+
+/**
+ * sql查询
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class SqlQuery extends AbstractQuery<Object> {
+
+  /** Constant <code>INNER_JOIN=" left join "</code> */
+  public static final String INNER_JOIN = " left join ";
+
+  /** Constant <code>OUTER_JOIN=" outer join "</code> */
+  public static final String OUTER_JOIN = " outer join ";
+
+  /** Constant <code>LEFT_OUTER_JOIN=" left outer join "</code> */
+  public static final String LEFT_OUTER_JOIN = " left outer join ";
+
+  /** Constant <code>RIGHT_OUTER_JOIN=" right outer join "</code> */
+  public static final String RIGHT_OUTER_JOIN = " right outer join ";
+
+  protected String select;
+
+  protected String from;
+
+  protected List<Condition> conditions = CollectUtils.newArrayList();
+
+  protected List<Order> orders = CollectUtils.newArrayList();
+
+  protected List<String> groups = CollectUtils.newArrayList();
+
+  /**
+   * <p>
+   * Constructor for SqlQuery.
+   * </p>
+   */
+  public SqlQuery() {
+    super();
+  }
+
+  /**
+   * <p>
+   * Constructor for SqlQuery.
+   * </p>
+   * 
+   * @param queryStr a {@link java.lang.String} object.
+   */
+  public SqlQuery(final String queryStr) {
+    super();
+    this.queryStr = queryStr;
+  }
+
+  /**
+   * <p>
+   * add.
+   * </p>
+   * 
+   * @param condition a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery add(final Condition condition) {
+    conditions.add(condition);
+    return this;
+  }
+
+  /**
+   * 添加一组条件<br>
+   * query中不能添加条件集合作为一个条件,因此这里命名没有采用有区别性的addAll
+   * 
+   * @param cons a {@link java.util.Collection} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery add(final Collection<Condition> cons) {
+    conditions.addAll(cons);
+    return this;
+  }
+
+  /**
+   * <p>
+   * addOrder.
+   * </p>
+   * 
+   * @param order a {@link com.ekingstar.commons.collection.Order} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery addOrder(final Order order) {
+    if (null != order) {
+      this.orders.add(order);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * addOrder.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery addOrder(final List<Order> orders) {
+    if (null != orders) {
+      this.orders.addAll(orders);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>select</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getSelect() {
+    return select;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>select</code>.
+   * </p>
+   * 
+   * @param select a {@link java.lang.String} object.
+   */
+  public void setSelect(final String select) {
+    if (null == select) {
+      this.select = null;
+    } else {
+      if (Strings.contains(select.toLowerCase(), "select")) {
+        this.select = select;
+      } else {
+        this.select = "select " + select;
+      }
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>conditions</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<Condition> getConditions() {
+    return conditions;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>conditions</code>.
+   * </p>
+   * 
+   * @param conditions a {@link java.util.List} object.
+   */
+  public void setConditions(final List<Condition> conditions) {
+    this.conditions = conditions;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>from</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getFrom() {
+    return from;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>from</code>.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   */
+  public void setFrom(final String from) {
+    if (null == from) {
+      this.from = null;
+    } else {
+      if (Strings.contains(from.toLowerCase(), "from")) {
+        this.from = from;
+      } else {
+        this.from = " from " + from;
+      }
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>orders</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<Order> getOrders() {
+    return orders;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>orders</code>.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   */
+  public void setOrders(final List<Order> orders) {
+    this.orders = orders;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>groups</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<String> getGroups() {
+    return groups;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>groups</code>.
+   * </p>
+   * 
+   * @param groups a {@link java.util.List} object.
+   */
+  public void setGroups(final List<String> groups) {
+    this.groups = groups;
+  }
+
+  /**
+   * <p>
+   * groupBy.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery groupBy(final String what) {
+    if (Strings.isNotEmpty(what)) {
+      groups.add(what);
+    }
+    return this;
+  }
+
+  /**
+   * 生成查询语句（如果查询语句已经存在则不进行生成）
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String toQueryString() {
+    if (Strings.isNotEmpty(queryStr)) {
+      return queryStr;
+    } else {
+      return genQueryString(true);
+    }
+  }
+
+  /**
+   * <p>
+   * toCountString.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String toCountString() {
+    if (Strings.isNotEmpty(countStr)) {
+      return countStr;
+    } else {
+      return "select count(*) from (" + genQueryString(false) + ")";
+    }
+  }
+
+  /**
+   * <p>
+   * genQueryString.
+   * </p>
+   * 
+   * @param hasOrder a boolean.
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genQueryString(final boolean hasOrder) {
+    if (null == from) { return queryStr; }
+    final StringBuilder buf = new StringBuilder(50);
+    buf.append((select == null) ? "" : select).append(' ').append(from);
+    if (!conditions.isEmpty()) {
+      buf.append(" where ").append(Conditions.toQueryString(conditions));
+    }
+    if (!groups.isEmpty()) {
+      buf.append(" group by ");
+      for (final String groupBy : groups) {
+        buf.append(groupBy).append(',');
+      }
+      buf.deleteCharAt(buf.length() - 1);
+    }
+    if (hasOrder && !CollectUtils.isEmpty(orders)) {
+      buf.append(' ').append(Order.toSortString(orders));
+    }
+    return buf.toString();
+  }
+
+  /**
+   * <p>
+   * getParams.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> getParams() {
+    return (null == params) ? Conditions.getParamMap(conditions) : CollectUtils.newHashMap(params);
+  }
+
+  /**
+   * <p>
+   * build.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  public Query<Object> build() {
+    QueryBean<Object> queryBean = new QueryBean<Object>();
+    queryBean.setStatement(toQueryString());
+    queryBean.setParams(CollectUtils.newHashMap(getParams()));
+    if (null != limit) {
+      queryBean.setLimit(new PageLimit(limit.getPageNo(), limit.getPageSize()));
+    }
+    queryBean.setCountStatement(toCountString());
+    queryBean.setCacheable(cacheable);
+    queryBean.setLang(getLang());
+    return queryBean;
+  }
+
+  /**
+   * <p>
+   * getLang.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  protected Lang getLang() {
+    return Lang.SQL;
+  }
+
+  /** {@inheritDoc} */
+  public SqlQuery limit(PageLimit limit) {
+    this.limit = limit;
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public SqlQuery params(Map<String, Object> newParams) {
+    this.params = CollectUtils.newHashMap(newParams);
+    return this;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/limit/AbstractQueryPage.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/limit/AbstractQueryPage.java
new file mode 100755
index 0000000..cea01b4
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/limit/AbstractQueryPage.java
@@ -0,0 +1,249 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.limit;
+
+import java.util.Iterator;
+
+import com.ekingstar.commons.page.Page;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.commons.page.PageWapper;
+import com.ekingstar.commons.page.SinglePage;
+import com.ekingstar.hibernate.query.LimitQuery;
+
+/**
+ * 基于查询的分页。<br>
+ * 当使用或导出大批量数据时，使用者仍以List的方式进行迭代。<br>
+ * 该实现则是内部采用分页方式。
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public abstract class AbstractQueryPage<T> extends PageWapper<T> {
+
+  protected int pageNo = 0;
+
+  protected int maxPageNo = 0;
+
+  protected LimitQuery<T> query;
+
+  /** {@inheritDoc} */
+  abstract public Page<T> moveTo(int pageNo);
+
+  /**
+   * <p>
+   * Constructor for AbstractQueryPage.
+   * </p>
+   */
+  public AbstractQueryPage() {
+    super();
+  }
+
+  /**
+   * <p>
+   * Constructor for AbstractQueryPage.
+   * </p>
+   * 
+   * @param query a {@link com.ekingstar.hibernate.query.LimitQuery} object.
+   */
+  public AbstractQueryPage(LimitQuery<T> query) {
+    this.query = query;
+    if (null != query) {
+      if (null == query.getLimit()) {
+        query.limit(new PageLimit(pageNo, Page.DEFAULT_PAGE_SIZE));
+      } else {
+        pageNo = query.getLimit().getPageNo() - 1;
+      }
+    }
+  }
+
+  /**
+   * 按照单个分页数据设置.
+   * 
+   * @param page a {@link com.ekingstar.commons.collection.page.SinglePage} object.
+   */
+  protected void setPageData(SinglePage<T> page) {
+    setPage(page);
+    this.pageNo = page.getPageNo();
+    this.maxPageNo = page.getMaxPageNo();
+  }
+
+  /**
+   * <p>
+   * next.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<T> next() {
+    return moveTo(pageNo + 1);
+  }
+
+  /**
+   * <p>
+   * previous.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<T> previous() {
+    return moveTo(pageNo - 1);
+  }
+
+  /**
+   * <p>
+   * hasNext.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasNext() {
+    return maxPageNo > pageNo;
+  }
+
+  /**
+   * <p>
+   * hasPrevious.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasPrevious() {
+    return pageNo > 1;
+  }
+
+  /**
+   * <p>
+   * getFirstPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getFirstPageNo() {
+    return 1;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>maxPageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getMaxPageNo() {
+    return maxPageNo;
+  }
+
+  /**
+   * <p>
+   * getNextPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getNextPageNo() {
+    return getPage().getNextPageNo();
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageNo() {
+    return pageNo;
+  }
+
+  /**
+   * <p>
+   * getPageSize.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageSize() {
+    return query.getLimit().getPageSize();
+  }
+
+  /**
+   * <p>
+   * getPreviousPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPreviousPageNo() {
+    return getPage().getPreviousPageNo();
+  }
+
+  /**
+   * <p>
+   * getTotal.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getTotal() {
+    return getPage().getTotal();
+  }
+
+  /**
+   * <p>
+   * iterator.
+   * </p>
+   * 
+   * @return a {@link java.util.Iterator} object.
+   */
+  public Iterator<T> iterator() {
+    return new PageIterator<T>(this);
+  }
+
+}
+
+class PageIterator<T> implements Iterator<T> {
+
+  private final AbstractQueryPage<T> queryPage;
+
+  private int dataIndex;
+
+  public PageIterator(AbstractQueryPage<T> queryPage) {
+    this.queryPage = queryPage;
+    this.dataIndex = 0;
+  }
+
+  public boolean hasNext() {
+    return (dataIndex < queryPage.getPage().getItems().size()) || (queryPage.hasNext());
+  }
+
+  public T next() {
+    if (dataIndex < queryPage.getPage().size()) {
+      return queryPage.getPage().getItems().get(dataIndex++);
+    } else {
+      queryPage.next();
+      dataIndex = 0;
+      return queryPage.getPage().getItems().get(dataIndex++);
+    }
+  }
+
+  public void remove() {
+
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/TestModel.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/TestModel.java
new file mode 100755
index 0000000..e583d2f
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/TestModel.java
@@ -0,0 +1,33 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate;
+
+public class TestModel {
+
+  private String name;
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionTest.java
new file mode 100755
index 0000000..d7e34db
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionTest.java
@@ -0,0 +1,51 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.builder;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.hibernate.query.builder.Condition;
+import com.ekingstar.hibernate.query.builder.Conditions;
+
+@Test
+public class ConditionTest {
+
+  public void testGetNamedParams() {
+    Condition condition = new Condition("std.id =:stAd_id1 and std.name like :name");
+    List<String> names = condition.getParamNames();
+    assertEquals(names.size(), 2);
+    assertEquals(names.get(0), "stAd_id1");
+    assertEquals(names.get(1), "name");
+  }
+
+  public void testVarArgs() {
+    Condition c = new Condition("entity.code =:code  entity.id in (:ids)", "aa", new Long[] { 1L });
+    assertEquals(2, Conditions.getParamMap(c).size());
+
+    Condition c1 = new Condition("entity.id in (:ids)", new Long[] { 1L, 2L });
+    assertEquals(1, Conditions.getParamMap(c1).size());
+    assertTrue((Conditions.getParamMap(c1).get("ids").getClass().isArray()));
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionsTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionsTest.java
new file mode 100755
index 0000000..8b9ca02
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionsTest.java
@@ -0,0 +1,64 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.builder;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.hibernate.query.builder.Condition;
+import com.ekingstar.hibernate.query.builder.Conditions;
+
+@Test
+public class ConditionsTest {
+
+  @BeforeClass
+  protected void setUp() throws Exception {
+
+  }
+
+  public void testGetParamMap() throws Exception {
+    List<Condition> conditions = CollectUtils.newArrayList();
+    conditions.add(new Condition("std.id=:std_id", 1L));
+    Map<String, Object> params = Conditions.getParamMap(conditions);
+    assertEquals(params.size(), 1);
+    assertEquals(params.get("std_id"), 1L);
+  }
+
+  public void testToQueryString() {
+    List<Condition> conditions = CollectUtils.newArrayList();
+    conditions.add(new Condition("user.id=:user_id", 1L));
+    conditions.add(new Condition("user.name=:std_name", "name"));
+    assertEquals(Conditions.toQueryString(conditions), "(user.id=:user_id) and (user.name=:std_name)");
+  }
+
+  public void testConcat() {
+    List<Condition> conditions = CollectUtils.newArrayList();
+    conditions.add(new Condition("user.id=:user_id", 1L));
+    conditions.add(new Condition("user.name=:std_name", "name"));
+    Condition rs = Conditions.or(conditions);
+    assertEquals(rs.getContent(), "((user.id=:user_id) or (user.name=:std_name))");
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/OqlBuilderTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/OqlBuilderTest.java
new file mode 100755
index 0000000..f5f75d2
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/OqlBuilderTest.java
@@ -0,0 +1,88 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.builder;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ekingstar.hibernate.TestModel;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.builder.Condition;
+import com.ekingstar.hibernate.query.builder.OqlBuilder;
+
+@Test
+public class OqlBuilderTest {
+
+  public void testToCountString1() throws Exception {
+    OqlBuilder<TestModel> queryBuilder = OqlBuilder.from(TestModel.class, "model");
+    LimitQuery<?> query = (LimitQuery<?>) queryBuilder.build();
+    assertEquals("select count(*) from com.ekingstar.hibernate.TestModel model", query.getCountQuery()
+        .getStatement());
+    queryBuilder.where(new Condition("name like :name", "testName"));
+    query = (LimitQuery<?>) queryBuilder.build();
+    assertTrue(query.getCountQuery().getStatement().endsWith("(name like :name)"));
+  }
+
+  public void testToCountString2() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder
+        .hql("from Ware where price is not null order by releaseDate desc "
+            + " union all from Ware where price is null order by releaseDate desc");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertNull(query.getCountQuery());
+  }
+
+  public void testToCountString3() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder.from("Ware", "w");
+    queryBuilder.select("(select count(*) from Product p where p.ware=w) pcount,w.id");
+    queryBuilder.where("w.price is not null and exists (select * from Orders o where o.product=p)").orderBy(
+        "w.releaseDate desc");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertEquals(
+        query.getStatement(),
+        "select (select count(*) from Product p where p.ware=w) pcount,w.id from Ware w "
+            + "where (w.price is not null and exists (select * from Orders o where o.product=p)) order by w.releaseDate desc");
+    assertEquals(
+        query.getCountQuery().getStatement(),
+        "select count(*) from Ware w where (w.price is not null and exists (select * from Orders o where o.product=p))");
+  }
+
+  public void testToCountString4() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder
+        .hql("from Ware where price is not null order by releaseDate desc ");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertEquals("select count(*) from Ware where price is not null", query.getCountQuery().getStatement());
+  }
+
+  public void testToCountString5() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder.hql("from Ware where price is not null");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertEquals("select count(*) from Ware where price is not null", query.getCountQuery().getStatement());
+  }
+
+  public void testHaving() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder.from("SomeClass a ").groupBy("a.name").having("sum(a.id)>0");
+    Assert.assertEquals(queryBuilder.build().getStatement(),
+        "from SomeClass a  group by a.name having sum(a.id)>0");
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/MockQueryPage.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/MockQueryPage.java
new file mode 100755
index 0000000..88ef7ff
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/MockQueryPage.java
@@ -0,0 +1,54 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.limit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.ekingstar.commons.page.Page;
+import com.ekingstar.commons.page.SinglePage;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.limit.AbstractQueryPage;
+
+public class MockQueryPage extends AbstractQueryPage<String> {
+
+  public MockQueryPage() {
+
+  }
+
+  public MockQueryPage(LimitQuery<String> query) {
+    super(query);
+    next();
+  }
+
+  public Page<String> moveTo(int pageNo) {
+    SinglePage<String> page = new SinglePage<String>();
+    page.setPageNo(pageNo);
+    page.setPageSize(super.getPageSize());
+    List<String> datas = new ArrayList<String>(getPageSize());
+    for (int i = 0; i < getPageSize(); i++) {
+      datas.add(String.valueOf(i) + " of " + pageNo);
+    }
+    page.setItems(datas);
+    page.setTotal(100);
+    setPageData(page);
+    return this;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/QueryPageTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/QueryPageTest.java
new file mode 100755
index 0000000..ea3672a
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/QueryPageTest.java
@@ -0,0 +1,43 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.limit;
+
+import static org.testng.Assert.assertNotNull;
+
+import java.util.Iterator;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.builder.OqlBuilder;
+
+@Test
+public class QueryPageTest {
+
+  public void testMove() throws Exception {
+    OqlBuilder<String> query = OqlBuilder.from(String.class, "dd");
+    query.limit(new PageLimit(1, 2));
+    MockQueryPage page = new MockQueryPage((LimitQuery<String>) query.build());
+    for (Iterator<String> iterator = page.iterator(); iterator.hasNext();) {
+      String data = iterator.next();
+      assertNotNull(data);
+    }
+  }
+}
