You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2018/08/20 12:36:51 UTC

groovy git commit: refactor: split out (de)capitalize methods to a util class - helps limit exposure to jdk9 java.desktop module

Repository: groovy
Updated Branches:
  refs/heads/master 40fbe3d40 -> 82bf5683b


refactor: split out (de)capitalize methods to a util class - helps limit exposure to jdk9 java.desktop module


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/82bf5683
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/82bf5683
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/82bf5683

Branch: refs/heads/master
Commit: 82bf5683b78618819484ff1472755bb65298706c
Parents: 40fbe3d
Author: Paul King <pa...@asert.com.au>
Authored: Mon Aug 20 22:30:27 2018 +1000
Committer: Paul King <pa...@asert.com.au>
Committed: Mon Aug 20 22:30:27 2018 +1000

----------------------------------------------------------------------
 .../groovy/beans/BindableASTTransformation.java |  8 +--
 .../groovy/beans/VetoableASTTransformation.java |  8 +--
 src/main/groovy/groovy/lang/MetaClassImpl.java  |  3 +-
 src/main/groovy/groovy/lang/MetaProperty.java   |  8 +--
 .../groovy/util/FactoryBuilderSupport.java      |  5 +-
 .../java/org/apache/groovy/util/BeanUtils.java  | 66 ++++++++++++++++++++
 .../codehaus/groovy/ast/tools/BeanUtils.java    |  3 +-
 .../codehaus/groovy/ast/tools/GeneralUtils.java |  6 +-
 .../groovy/classgen/AsmClassGenerator.java      |  9 +--
 .../classgen/ClassCompletionVerifier.java       |  6 +-
 .../groovy/classgen/VariableScopeVisitor.java   |  3 +-
 .../org/codehaus/groovy/classgen/Verifier.java  |  4 +-
 ...ypesBinaryExpressionMultiTypeDispatcher.java |  4 +-
 .../asm/sc/StaticTypesCallSiteWriter.java       | 14 ++---
 .../groovy/control/StaticImportVisitor.java     |  2 +-
 .../groovy/runtime/MetaClassHelper.java         | 21 ++-----
 .../transform/FieldASTTransformation.java       |  4 +-
 .../IndexedPropertyASTTransformation.java       |  4 +-
 .../groovy/transform/LazyASTTransformation.java |  6 +-
 .../stc/StaticTypeCheckingVisitor.java          | 13 ++--
 .../groovy/groovy/cli/commons/CliBuilder.groovy |  8 ++-
 21 files changed, 134 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/groovy/groovy/beans/BindableASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/beans/BindableASTTransformation.java b/src/main/groovy/groovy/beans/BindableASTTransformation.java
index e1bf2e5..98ce518 100644
--- a/src/main/groovy/groovy/beans/BindableASTTransformation.java
+++ b/src/main/groovy/groovy/beans/BindableASTTransformation.java
@@ -35,7 +35,6 @@ import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.control.messages.SimpleMessage;
 import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.transform.ASTTransformation;
 import org.codehaus.groovy.transform.GroovyASTTransformation;
@@ -44,6 +43,7 @@ import org.objectweb.asm.Opcodes;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
@@ -184,8 +184,8 @@ public class BindableASTTransformation implements ASTTransformation, Opcodes {
      * Wrap an existing setter.
      */
     private static void wrapSetterMethod(ClassNode classNode, String propertyName) {
-        String getterName = "get" + MetaClassHelper.capitalize(propertyName);
-        MethodNode setter = classNode.getSetterMethod("set" + MetaClassHelper.capitalize(propertyName));
+        String getterName = "get" + capitalize(propertyName);
+        MethodNode setter = classNode.getSetterMethod("set" + capitalize(propertyName));
 
         if (setter != null) {
             // Get the existing code block
@@ -213,7 +213,7 @@ public class BindableASTTransformation implements ASTTransformation, Opcodes {
     }
 
     private void createListenerSetter(ClassNode classNode, PropertyNode propertyNode) {
-        String setterName = "set" + MetaClassHelper.capitalize(propertyNode.getName());
+        String setterName = "set" + capitalize(propertyNode.getName());
         if (classNode.getMethods(setterName).isEmpty()) {
             Statement setterBlock = createBindableStatement(propertyNode, fieldX(propertyNode.getField()));
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/groovy/groovy/beans/VetoableASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/beans/VetoableASTTransformation.java b/src/main/groovy/groovy/beans/VetoableASTTransformation.java
index 983e8da..d3bffc9 100644
--- a/src/main/groovy/groovy/beans/VetoableASTTransformation.java
+++ b/src/main/groovy/groovy/beans/VetoableASTTransformation.java
@@ -35,7 +35,6 @@ import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.control.messages.SimpleMessage;
 import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.transform.GroovyASTTransformation;
 import org.objectweb.asm.Opcodes;
@@ -44,6 +43,7 @@ import java.beans.PropertyVetoException;
 import java.beans.VetoableChangeListener;
 import java.beans.VetoableChangeSupport;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
@@ -168,8 +168,8 @@ public class VetoableASTTransformation extends BindableASTTransformation {
      * Wrap an existing setter.
      */
     private static void wrapSetterMethod(ClassNode classNode, boolean bindable, String propertyName) {
-        String getterName = "get" + MetaClassHelper.capitalize(propertyName);
-        MethodNode setter = classNode.getSetterMethod("set" + MetaClassHelper.capitalize(propertyName));
+        String getterName = "get" + capitalize(propertyName);
+        MethodNode setter = classNode.getSetterMethod("set" + capitalize(propertyName));
 
         if (setter != null) {
             // Get the existing code block
@@ -210,7 +210,7 @@ public class VetoableASTTransformation extends BindableASTTransformation {
         if (needsVetoableChangeSupport(declaringClass, source)) {
             addVetoableChangeSupport(declaringClass);
         }
-        String setterName = "set" + MetaClassHelper.capitalize(propertyNode.getName());
+        String setterName = "set" + capitalize(propertyNode.getName());
         if (declaringClass.getMethods(setterName).isEmpty()) {
             Expression fieldExpression = fieldX(propertyNode.getField());
             BlockStatement setterBlock = new BlockStatement();

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/groovy/groovy/lang/MetaClassImpl.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaClassImpl.java b/src/main/groovy/groovy/lang/MetaClassImpl.java
index 66abb2d..d2c6b9d 100644
--- a/src/main/groovy/groovy/lang/MetaClassImpl.java
+++ b/src/main/groovy/groovy/lang/MetaClassImpl.java
@@ -19,6 +19,7 @@
 package groovy.lang;
 
 import org.apache.groovy.internal.util.UncheckedThrow;
+import org.apache.groovy.util.BeanUtils;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.classgen.asm.BytecodeHelper;
@@ -2543,7 +2544,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         if (name == null) {
             // assume "is" or "[gs]et"
             String stripped = methodName.startsWith("is") ? methodName.substring(2) : methodName.substring(3);
-            String propName = Introspector.decapitalize(stripped);
+            String propName = BeanUtils.decapitalize(stripped);
             PROP_NAMES.putIfAbsent(methodName, propName);
             name = PROP_NAMES.get(methodName);
         }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/groovy/groovy/lang/MetaProperty.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaProperty.java b/src/main/groovy/groovy/lang/MetaProperty.java
index d3c9633..ca5bdf6 100644
--- a/src/main/groovy/groovy/lang/MetaProperty.java
+++ b/src/main/groovy/groovy/lang/MetaProperty.java
@@ -18,10 +18,10 @@
  */
 package groovy.lang;
 
-import org.codehaus.groovy.runtime.MetaClassHelper;
-
 import java.lang.reflect.Modifier;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
+
 /**
  * Represents a property on a bean which may have a getter and/or a setter
  * 
@@ -88,7 +88,7 @@ public abstract class MetaProperty {
      */
     public static String getGetterName(String propertyName, Class type) {
         String prefix = type == boolean.class || type == Boolean.class ? "is" : "get";
-        return prefix + MetaClassHelper.capitalize(propertyName);
+        return prefix + capitalize(propertyName);
     }
 
     /**
@@ -97,6 +97,6 @@ public abstract class MetaProperty {
      * @return The name of the property. The name is "set"+ the capitalized propertyName.
      */
     public static String getSetterName(String propertyName) {
-        return PROPERTY_SET_PREFIX + MetaClassHelper.capitalize(propertyName);
+        return PROPERTY_SET_PREFIX + capitalize(propertyName);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/groovy/groovy/util/FactoryBuilderSupport.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/FactoryBuilderSupport.java b/src/main/groovy/groovy/util/FactoryBuilderSupport.java
index 1074e53..a718dc9 100644
--- a/src/main/groovy/groovy/util/FactoryBuilderSupport.java
+++ b/src/main/groovy/groovy/util/FactoryBuilderSupport.java
@@ -28,7 +28,6 @@ import groovy.lang.MissingPropertyException;
 import groovy.lang.Reference;
 import groovy.lang.Script;
 import org.codehaus.groovy.runtime.InvokerHelper;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack;
 
 import java.lang.reflect.InvocationTargetException;
@@ -48,6 +47,8 @@ import java.util.TreeSet;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
+
 /**
  * Mix of BuilderSupport and SwingBuilder's factory support.
  *
@@ -620,7 +621,7 @@ public abstract class FactoryBuilderSupport extends Binding {
         if (getter != null) getter.setDelegate(this);
         if (setter != null) setter.setDelegate(this);
         explicitProperties.put(name, new Closure[]{getter, setter});
-        String methodNameBase = MetaClassHelper.capitalize(name);
+        String methodNameBase = capitalize(name);
         if (getter != null) {
             getRegistrationGroup(groupName).add("get" + methodNameBase);
         }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/apache/groovy/util/BeanUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/groovy/util/BeanUtils.java b/src/main/java/org/apache/groovy/util/BeanUtils.java
new file mode 100644
index 0000000..5f3669b
--- /dev/null
+++ b/src/main/java/org/apache/groovy/util/BeanUtils.java
@@ -0,0 +1,66 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.util;
+
+import static java.lang.Character.isUpperCase;
+
+public class BeanUtils {
+    /**
+     * Returns a new String which is the same as the original except the first letter
+     * will be lowercase except for some special cases as per JavaBean handling.
+     * In particular, if the first two letters are both uppercase, e.g. URL,
+     * then no change of case occurs.
+     *
+     * Originally inspired by the method with the same name in java.lang.Introspector.
+     * See also:
+     * https://stackoverflow.com/questions/4052840/most-efficient-way-to-make-the-first-character-of-a-string-lower-case/4052914
+     *
+     * @param property a string representing the name of a JavaBean-like property
+     * @return the decapitalized string
+     */
+    public static String decapitalize(final String property) {
+        if (property == null || property.isEmpty()) return property;
+        if (property.length() > 2 && isUpperCase(property.charAt(1)) && isUpperCase(property.charAt(0))) return property;
+        final char c[] = property.toCharArray();
+        c[0] = Character.toLowerCase(c[0]);
+        return new String(c);
+    }
+
+    /**
+     * This is the complement the behavior of the decapitalize(string) method.
+     * We handle names that begin with an initial lowerCase followed by upperCase
+     * with special JavaBean behavior (which is to make no change). See GROOVY-3211.
+     *
+     * @param property the property name to capitalize
+     * @return the name capitalized, except when we don't
+     */
+    public static String capitalize(final String property) {
+        final String rest = property.substring(1);
+
+        // Funky rule so that names like 'pNAME' will still work.
+        if (Character.isLowerCase(property.charAt(0)) && (rest.length() > 0) && isUpperCase(rest.charAt(0))) {
+            return property;
+        }
+
+        return property.substring(0, 1).toUpperCase() + rest;
+    }
+
+    private BeanUtils() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java
index 28c2270..841e1a3 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java
@@ -30,7 +30,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import static java.beans.Introspector.decapitalize;
+import static org.apache.groovy.util.BeanUtils.decapitalize;
 
 public class BeanUtils {
     static final String GET_PREFIX = "get";
@@ -155,4 +155,5 @@ public class BeanUtils {
             names.add(propName);
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
index 0fa8063..d7a3f0c 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -60,7 +60,6 @@ import org.codehaus.groovy.ast.stmt.ThrowStatement;
 import org.codehaus.groovy.classgen.Verifier;
 import org.codehaus.groovy.control.io.ReaderSource;
 import org.codehaus.groovy.runtime.GeneratedClosure;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.Token;
 import org.codehaus.groovy.syntax.Types;
 import org.codehaus.groovy.transform.AbstractASTTransformation;
@@ -73,6 +72,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_IDENTICAL;
 
 /**
@@ -766,10 +766,10 @@ public class GeneralUtils {
     }
 
     private static String getterName(ClassNode annotatedNode, PropertyNode pNode) {
-        String getterName = "get" + MetaClassHelper.capitalize(pNode.getName());
+        String getterName = "get" + capitalize(pNode.getName());
         boolean existingExplicitGetter = annotatedNode.getMethod(getterName, Parameter.EMPTY_ARRAY) != null;
         if (ClassHelper.boolean_TYPE.equals(pNode.getOriginType()) && !existingExplicitGetter) {
-            getterName = "is" + MetaClassHelper.capitalize(pNode.getName());
+            getterName = "is" + capitalize(pNode.getName());
         }
         return getterName;
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index a49b160..35a05fe 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -102,7 +102,6 @@ import org.codehaus.groovy.classgen.asm.OptimizingStatementWriter;
 import org.codehaus.groovy.classgen.asm.WriterController;
 import org.codehaus.groovy.classgen.asm.WriterControllerFactory;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
 import org.codehaus.groovy.syntax.RuntimeParserException;
 import org.objectweb.asm.AnnotationVisitor;
@@ -124,6 +123,8 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
+
 /**
  * Generates Java class versions of Groovy classes using ASM.
  *
@@ -1031,7 +1032,7 @@ public class AsmClassGenerator extends ClassGenerator {
                     } else {
                         prefix = "get";
                     }
-                    String propName = prefix + MetaClassHelper.capitalize(name);
+                    String propName = prefix + capitalize(name);
                     visitMethodCallExpression(new MethodCallExpression(objectExpression, propName, MethodCallExpression.NO_ARGUMENTS));
                     return;
                 }
@@ -1140,13 +1141,13 @@ public class AsmClassGenerator extends ClassGenerator {
     }
 
     private MethodNode findSetterOfSuperClass(ClassNode classNode, FieldNode fieldNode) {
-        String setterMethodName = "set" + MetaClassHelper.capitalize(fieldNode.getName());
+        String setterMethodName = "set" + capitalize(fieldNode.getName());
 
         return classNode.getSuperClass().getSetterMethod(setterMethodName);
     }
 
     private MethodNode findGetterOfSuperClass(ClassNode classNode, FieldNode fieldNode) {
-        String getterMethodName = "get" + MetaClassHelper.capitalize(fieldNode.getName());
+        String getterMethodName = "get" + capitalize(fieldNode.getName());
 
         return classNode.getSuperClass().getGetterMethod(getterMethodName);
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index e2a848b..7f2d933 100644
--- a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -43,7 +43,6 @@ import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.CatchStatement;
 import org.codehaus.groovy.ast.tools.GeneralUtils;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.Types;
 import org.codehaus.groovy.transform.trait.Traits;
 
@@ -62,6 +61,7 @@ import static java.lang.reflect.Modifier.isStrict;
 import static java.lang.reflect.Modifier.isSynchronized;
 import static java.lang.reflect.Modifier.isTransient;
 import static java.lang.reflect.Modifier.isVolatile;
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE;
 import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
 import static org.objectweb.asm.Opcodes.ACC_FINAL;
@@ -537,11 +537,11 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
     private void checkDuplicateProperties(PropertyNode node) {
         ClassNode cn = node.getDeclaringClass();
         String name = node.getName();
-        String getterName = "get" + MetaClassHelper.capitalize(name);
+        String getterName = "get" + capitalize(name);
         if (Character.isUpperCase(name.charAt(0))) {
             for (PropertyNode propNode : cn.getProperties()) {
                 String otherName = propNode.getField().getName();
-                String otherGetterName = "get" + MetaClassHelper.capitalize(otherName);
+                String otherGetterName = "get" + capitalize(otherName);
                 if (node != propNode && getterName.equals(otherGetterName)) {
                     String msg = "The field " + name + " and " + otherName + " on the class " +
                             cn.getName() + " will result in duplicate JavaBean properties, which is not allowed";

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index 1863c1f..6480dfe 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -58,6 +58,7 @@ import java.util.List;
 import java.util.Map;
 
 import static java.lang.reflect.Modifier.isFinal;
+import static org.apache.groovy.util.BeanUtils.decapitalize;
 
 /**
  * goes through an AST and initializes the scopes
@@ -205,7 +206,7 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
         if (!(name.startsWith("set") || name.startsWith("get"))) return null;
         String pname = name.substring(3);
         if (pname.length() == 0) return null;
-        pname = java.beans.Introspector.decapitalize(pname);
+        pname = decapitalize(pname);
 
         if (name.startsWith("get") && (m.getReturnType() == ClassHelper.VOID_TYPE || m.getParameters().length != 0)) {
             return null;

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/classgen/Verifier.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 5010807..cd234f0 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -23,6 +23,7 @@ import groovy.lang.GroovyObject;
 import groovy.lang.MetaClass;
 import groovy.transform.Generated;
 import org.apache.groovy.ast.tools.ClassNodeUtils;
+import org.apache.groovy.util.BeanUtils;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassHelper;
@@ -61,7 +62,6 @@ import org.codehaus.groovy.classgen.asm.MopWriter;
 import org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.ClassNodeSkip;
 import org.codehaus.groovy.classgen.asm.WriterController;
 import org.codehaus.groovy.reflection.ClassInfo;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.RuntimeParserException;
 import org.codehaus.groovy.syntax.Token;
 import org.codehaus.groovy.syntax.Types;
@@ -1151,7 +1151,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
      * Capitalizes the start of the given bean property name
      */
     public static String capitalize(String name) {
-        return MetaClassHelper.capitalize(name);
+        return BeanUtils.capitalize(name);
     }
 
     protected Statement createGetterBlock(PropertyNode propertyNode, final FieldNode field) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
index 81773c7..f865404 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
@@ -49,7 +49,6 @@ import org.codehaus.groovy.classgen.asm.OperandStack;
 import org.codehaus.groovy.classgen.asm.TypeChooser;
 import org.codehaus.groovy.classgen.asm.VariableSlotLoader;
 import org.codehaus.groovy.classgen.asm.WriterController;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.Token;
 import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
 import org.codehaus.groovy.transform.sc.StaticCompilationVisitor;
@@ -65,6 +64,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.ClassHelper.CLOSURE_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.char_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.double_TYPE;
@@ -276,7 +276,7 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher extends BinaryExpres
             }
         }
         if (!isAttribute) {
-            String setter = "set" + MetaClassHelper.capitalize(property);
+            String setter = "set" + capitalize(property);
             MethodNode setterMethod = receiverType.getSetterMethod(setter, false);
             ClassNode declaringClass = setterMethod!=null?setterMethod.getDeclaringClass():null;
             if (isThisExpression && declaringClass!=null && declaringClass.equals(controller.getClassNode())) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
index b717c42..c8cc0f6 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
@@ -45,7 +45,6 @@ import org.codehaus.groovy.classgen.asm.MethodCallerMultiAdapter;
 import org.codehaus.groovy.classgen.asm.OperandStack;
 import org.codehaus.groovy.classgen.asm.TypeChooser;
 import org.codehaus.groovy.runtime.InvokerHelper;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
 import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
@@ -61,6 +60,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.ClassHelper.BigDecimal_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.BigInteger_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Boolean_TYPE;
@@ -213,8 +213,8 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
         if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, methodName, safe, implicitThis)) return;
 
         // GROOVY-5580, it is still possible that we're calling a superinterface property
-        String getterName = "get" + MetaClassHelper.capitalize(methodName);
-        String altGetterName = "is" + MetaClassHelper.capitalize(methodName);
+        String getterName = "get" + capitalize(methodName);
+        String altGetterName = "is" + capitalize(methodName);
         if (receiverType.isInterface()) {
             Set<ClassNode> allInterfaces = receiverType.getAllInterfaces();
             MethodNode getterMethod = null;
@@ -506,10 +506,10 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
 
     private boolean makeGetPropertyWithGetter(final Expression receiver, final ClassNode receiverType, final String methodName, final boolean safe, final boolean implicitThis) {
         // does a getter exists ?
-        String getterName = "get" + MetaClassHelper.capitalize(methodName);
+        String getterName = "get" + capitalize(methodName);
         MethodNode getterNode = receiverType.getGetterMethod(getterName);
         if (getterNode==null) {
-            getterName = "is" + MetaClassHelper.capitalize(methodName);
+            getterName = "is" + capitalize(methodName);
             getterNode = receiverType.getGetterMethod(getterName);
         }
         if (getterNode!=null && receiver instanceof ClassExpression && !CLASS_Type.equals(receiverType) && !getterNode.isStatic()) {
@@ -526,7 +526,7 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
             if (boolean_TYPE.equals(propertyNode.getOriginType())) {
                 prefix = "is";
             }
-            getterName = prefix + MetaClassHelper.capitalize(methodName);
+            getterName = prefix + capitalize(methodName);
             getterNode = new MethodNode(
                     getterName,
                     ACC_PUBLIC,
@@ -875,7 +875,7 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
         controller.getOperandStack().doGroovyCast(Number_TYPE);
         int m2 = operandStack.getStackLength();
         MethodVisitor mv = controller.getMethodVisitor();
-        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/dgmimpl/NumberNumber" + MetaClassHelper.capitalize(message), message, "(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;", false);
+        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/dgmimpl/NumberNumber" + capitalize(message), message, "(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;", false);
         controller.getOperandStack().replace(Number_TYPE, m2 - m1);
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index 5bdeb9c..93f5929 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -60,7 +60,7 @@ import static org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticProper
 import static org.apache.groovy.ast.tools.ClassNodeUtils.hasStaticProperty;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.isInnerClass;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.isValidAccessorName;
-import static org.codehaus.groovy.runtime.MetaClassHelper.capitalize;
+import static org.apache.groovy.util.BeanUtils.capitalize;
 
 /**
  * Visitor to resolve constants and method calls from static Imports

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/runtime/MetaClassHelper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/runtime/MetaClassHelper.java b/src/main/java/org/codehaus/groovy/runtime/MetaClassHelper.java
index 7839a59..f2ae80a 100644
--- a/src/main/java/org/codehaus/groovy/runtime/MetaClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/runtime/MetaClassHelper.java
@@ -24,6 +24,7 @@ import groovy.lang.GroovyObject;
 import groovy.lang.GroovyRuntimeException;
 import groovy.lang.MetaClass;
 import groovy.lang.MetaMethod;
+import org.apache.groovy.util.BeanUtils;
 import org.codehaus.groovy.reflection.CachedClass;
 import org.codehaus.groovy.reflection.ParameterTypes;
 import org.codehaus.groovy.reflection.ReflectionCache;
@@ -476,23 +477,11 @@ public class MetaClassHelper {
     }
 
     /**
-     * This is the complement to the java.beans.Introspector.decapitalize(String) method.
-     * We handle names that begin with an initial lowerCase followed by upperCase specially
-     * (which is to make no change).
-     * See GROOVY-3211.
-     *
-     * @param property the property name to capitalize
-     * @return the name capitalized, except when we don't
+     * @deprecated Use BeanUtils.capitalize instead
      */
+    @Deprecated
     public static String capitalize(final String property) {
-        final String rest = property.substring(1);
-
-        // Funky rule so that names like 'pNAME' will still work.
-        if (Character.isLowerCase(property.charAt(0)) && (rest.length() > 0) && Character.isUpperCase(rest.charAt(0))) {
-            return property;
-        }
-
-        return property.substring(0, 1).toUpperCase() + rest;
+        return BeanUtils.capitalize(property);
     }
 
     /**
@@ -1029,6 +1018,6 @@ public class MetaClassHelper {
         if (Character.isDigit(prop.charAt(0))) {
             return prop;
         }
-        return java.beans.Introspector.decapitalize(prop);
+        return BeanUtils.decapitalize(prop);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
index bb52c6f..115a90d 100644
--- a/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
@@ -46,7 +46,6 @@ import org.codehaus.groovy.ast.stmt.ExpressionStatement;
 import org.codehaus.groovy.classgen.VariableScopeVisitor;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.objectweb.asm.Opcodes;
 
 import java.util.ArrayList;
@@ -54,6 +53,7 @@ import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.ClassHelper.make;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
@@ -118,7 +118,7 @@ public class FieldASTTransformation extends ClassCodeExpressionTransformer imple
                     addError("Can't have a final field also annotated with @" + OPTION_TYPE.getNameWithoutPackage(), de);
                 }
             } else {
-                String setterName = "set" + MetaClassHelper.capitalize(variableName);
+                String setterName = "set" + capitalize(variableName);
                 cNode.addMethod(setterName, ACC_PUBLIC | ACC_SYNTHETIC, ClassHelper.VOID_TYPE, params(param(ve.getType(), variableName)), ClassNode.EMPTY_ARRAY, block(
                         stmt(assignX(propX(varX("this"), variableName), varX(variableName)))
                 ));

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/transform/IndexedPropertyASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/IndexedPropertyASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/IndexedPropertyASTTransformation.java
index 6dd3ecf..7392f3c 100644
--- a/src/main/java/org/codehaus/groovy/transform/IndexedPropertyASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/IndexedPropertyASTTransformation.java
@@ -29,10 +29,10 @@ import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 
 import java.util.List;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.ClassHelper.make;
 import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
@@ -132,6 +132,6 @@ public class IndexedPropertyASTTransformation extends AbstractASTTransformation
     }
 
     private static String makeName(FieldNode fNode, String prefix) {
-        return prefix + MetaClassHelper.capitalize(fNode.getName());
+        return prefix + capitalize(fNode.getName());
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
index 37c0028..85c4f59 100644
--- a/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
@@ -37,10 +37,10 @@ import org.codehaus.groovy.ast.stmt.Statement;
 import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 
 import java.lang.ref.SoftReference;
 
+import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
@@ -163,7 +163,7 @@ public class LazyASTTransformation extends AbstractASTTransformation {
     private static void addMethod(FieldNode fieldNode, BlockStatement body, ClassNode type) {
         int visibility = ACC_PUBLIC;
         if (fieldNode.isStatic()) visibility |= ACC_STATIC;
-        String propName = MetaClassHelper.capitalize(fieldNode.getName().substring(1));
+        String propName = capitalize(fieldNode.getName().substring(1));
         fieldNode.getDeclaringClass().addMethod("get" + propName, visibility, type, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body);
         if (ClassHelper.boolean_TYPE.equals(type)) {
             fieldNode.getDeclaringClass().addMethod("is" + propName, visibility, type,
@@ -209,7 +209,7 @@ public class LazyASTTransformation extends AbstractASTTransformation {
     private static void createSoftSetter(FieldNode fieldNode, ClassNode type) {
         final BlockStatement body = new BlockStatement();
         final Expression fieldExpr = varX(fieldNode);
-        final String name = "set" + MetaClassHelper.capitalize(fieldNode.getName().substring(1));
+        final String name = "set" + capitalize(fieldNode.getName().substring(1));
         final Parameter parameter = param(type, "value");
         final Expression paramExpr = varX(parameter);
         body.addStatement(ifElseS(

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 12fe2f2..8b9ed1c 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -96,7 +96,6 @@ import org.codehaus.groovy.control.ErrorCollector;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
 import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.MetaClassHelper;
 import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.syntax.Token;
 import org.codehaus.groovy.syntax.TokenUtil;
@@ -126,6 +125,8 @@ import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
 import static org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName;
+import static org.apache.groovy.util.BeanUtils.capitalize;
+import static org.apache.groovy.util.BeanUtils.decapitalize;
 import static org.codehaus.groovy.ast.ClassHelper.BigDecimal_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.BigInteger_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Boolean_TYPE;
@@ -1284,7 +1285,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                             " for class: " + receiverType.getName(), receiver);
                 } else {
                     ClassNode valueType = getType(entryExpression.getValueExpression());
-                    MethodNode setter = receiverType.getSetterMethod("set" + MetaClassHelper.capitalize(pexp.getPropertyAsString()), false);
+                    MethodNode setter = receiverType.getSetterMethod("set" + capitalize(pexp.getPropertyAsString()), false);
                     ClassNode toBeAssignedTo = setter == null ? lookup.get() : setter.getParameters()[0].getType();
                     if (!isAssignableTo(valueType, toBeAssignedTo)
                             && !extension.handleIncompatibleAssignment(toBeAssignedTo, valueType, entryExpression)) {
@@ -1440,7 +1441,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         List<Receiver<String>> owners = makeOwnerList(objectExpression);
         addReceivers(receivers, owners, pexp.isImplicitThis());
 
-        String capName = MetaClassHelper.capitalize(propertyName);
+        String capName = capitalize(propertyName);
         boolean isAttributeExpression = pexp instanceof AttributeExpression;
         HashSet<ClassNode> handledNodes = new HashSet<ClassNode>();
         for (Receiver<String> receiver : receivers) {
@@ -1756,7 +1757,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         List<Receiver<String>> owners = makeOwnerList(objectExpression);
         addReceivers(receivers, owners, pexp.isImplicitThis());
 
-        String capName = MetaClassHelper.capitalize(propertyName);
+        String capName = capitalize(propertyName);
         boolean isAttributeExpression = pexp instanceof AttributeExpression;
 
         for (Receiver<String> receiver : receivers) {
@@ -4594,8 +4595,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         if (prefix == null || methodName == null) return null;
         if (methodName.startsWith(prefix) && prefix.length() < methodName.length()) {
             String result = methodName.substring(prefix.length());
-            String propertyName = java.beans.Introspector.decapitalize(result);
-            if (result.equals(MetaClassHelper.capitalize(propertyName))) return propertyName;
+            String propertyName = decapitalize(result);
+            if (result.equals(capitalize(propertyName))) return propertyName;
         }
         return null;
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/82bf5683/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy b/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy
index 88c64ae..218c9cb 100644
--- a/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy
+++ b/subprojects/groovy-cli-commons/src/main/groovy/groovy/cli/commons/CliBuilder.groovy
@@ -38,6 +38,8 @@ import java.lang.reflect.Array
 import java.lang.reflect.Field
 import java.lang.reflect.Method
 
+import static org.apache.groovy.util.BeanUtils.capitalize
+
 /**
  * Provides a builder to assist the processing of command line arguments.
  * Two styles are supported: dynamic api style (declarative method calls provide a mini DSL for describing options)
@@ -417,7 +419,7 @@ class CliBuilder {
         }
         optionFields.each { Field f ->
             Annotation annotation = f.getAnnotation(Option)
-            String setterName = "set" + MetaClassHelper.capitalize(f.getName());
+            String setterName = "set" + capitalize(f.getName());
             Method m = optionClass.getMethod(setterName, f.getType())
             def typedOption = processAddAnnotation(annotation, m, true)
             options.addOption(typedOption.cliOption)
@@ -513,7 +515,7 @@ class CliBuilder {
         }
         optionClass.declaredFields.findAll { it.getAnnotation(Option) }.each { Field f ->
             Annotation annotation = f.getAnnotation(Option)
-            String setterName = "set" + MetaClassHelper.capitalize(f.getName());
+            String setterName = "set" + capitalize(f.getName());
             Method m = optionClass.getMethod(setterName, f.getType())
             Map names = calculateNames(annotation.longName(), annotation.shortName(), m, true)
             processSetAnnotation(m, t, names.long ?: names.short, cli, true)
@@ -523,7 +525,7 @@ class CliBuilder {
             processSetRemaining(m, remaining, t, cli, namesAreSetters)
         }
         optionClass.declaredFields.findAll{ it.getAnnotation(Unparsed) }.each { Field f ->
-            String setterName = "set" + MetaClassHelper.capitalize(f.getName());
+            String setterName = "set" + capitalize(f.getName());
             Method m = optionClass.getMethod(setterName, f.getType())
             processSetRemaining(m, remaining, t, cli, namesAreSetters)
         }