开发用的工具
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);
+    }
+  }
+}