Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: CPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Common Public License Version 1.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.eclipse.org/legal/cpl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyright (C) 2006 Ola Bini <ola@ologix.com> Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the CPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the CPL, the GPL or the LGPL. END LICENSE BLOCK ***
  
  package org.jruby;
  
  import static org.jruby.RubyEnumerator.enumeratorize;
  
  import java.util.Arrays;
  import java.util.List;
  
  
  import static org.jruby.javasupport.util.RuntimeHelpers.invokedynamic;
  import static org.jruby.runtime.invokedynamic.MethodNames.OP_CMP;

The implementation of Ruby's Enumerable module.
  
  
  @JRubyModule(name="Enumerable")
  public class RubyEnumerable {
  
      public static RubyModule createEnumerableModule(Ruby runtime) {
          RubyModule enumModule = runtime.defineModule("Enumerable");
          runtime.setEnumerable(enumModule);
          
          enumModule.defineAnnotatedMethods(RubyEnumerable.class);
  
          return enumModule;
      }
  
      public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject self,
              BlockCallback callback) {
          return RuntimeHelpers.invoke(contextself"each", CallBlock.newCallClosure(selfruntime.getEnumerable(),
                  .callbackcontext));
      }
  
      public static IRubyObject callEach19(Ruby runtimeThreadContext contextIRubyObject self,
              BlockCallback callback) {
          return RuntimeHelpers.invoke(contextself"each", CallBlock19.newCallClosure(selfruntime.getEnumerable(),
                  .callbackcontext));
      }
  
      @Deprecated
      public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject selfIRubyObject[] args,
              BlockCallback callback) {
          return RuntimeHelpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(), .callbackcontext));
      }
  
      public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject self,
              Arity arityBlockCallback callback) {
          return RuntimeHelpers.invoke(contextself"each", CallBlock.newCallClosure(selfruntime.getEnumerable(),
                  aritycallbackcontext));
      }
  
     public static IRubyObject callEach19(Ruby runtimeThreadContext contextIRubyObject self,
             Arity arityBlockCallback callback) {
         return RuntimeHelpers.invoke(contextself"each", CallBlock19.newCallClosure(selfruntime.getEnumerable(),
                 aritycallbackcontext));
     }
     
     public static IRubyObject each(ThreadContext contextIRubyObject selfBlockBody body) {
         Block block = new Block(bodycontext.currentBinding(self.));
         return RuntimeHelpers.invoke(contextself"each"block);
     }
 
     @Deprecated
     public static IRubyObject callEach(Ruby runtimeThreadContext contextIRubyObject selfIRubyObject[] args,
             Arity arityBlockCallback callback) {
         return RuntimeHelpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(), aritycallbackcontext));
     }
 
     private static void checkContext(ThreadContext firstContextThreadContext secondContextString name) {
         if (firstContext != secondContext) {
             throw secondContext.runtime.newThreadError("Enumerable#" + name + " cannot be parallelized");
         }
     }
 
     public static IRubyObject checkArgs(Ruby runtimeIRubyObject[] largs) {
         return largs.length == 0 ? runtime.getNil() : largs[0];
     }
 
     @JRubyMethod
     public static IRubyObject count(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final int result[] = new int[] { 0 };
         
         if (block.isGiven()) {
             each(contextselfnew JavaInternalBlockBody(context"Enumerable#count"block.arity()) {
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     if (block.yield(contextarg).isTrue()) result[0]++; 
                     return runtime.getNil();
                 }
             });
         } else {
             if (self.respondsTo("size")) return self.callMethod(context"size");
             
             each(contextselfnew JavaInternalBlockBody(context"Enumerable#count".) {
                 public IRubyObject yield(ThreadContext contextIRubyObject unusedValue) {
                     result[0]++;
                     return runtime.getNil();
                 }
             });
         }
         return RubyFixnum.newFixnum(runtimeresult[0]);
     }
     
     @JRubyMethod
     public static IRubyObject count(ThreadContext contextIRubyObject selffinal IRubyObject methodArgfinal Block block) {
         final Ruby runtime = context.runtime;
         final int result[] = new int[] { 0 };
         
         if (block.isGiven()) runtime.getWarnings().warn(. , "given block not used");
         
         each(contextselfnew JavaInternalBlockBody(context"Enumerable#count".) {
             public IRubyObject yield(ThreadContext contextIRubyObject blockArg) {
                 if (blockArg.equals(methodArg)) result[0]++;
                 
                 return runtime.getNil();
             }
         });
 
         return RubyFixnum.newFixnum(runtimeresult[0]);
     }
     
     @JRubyMethod
     public static IRubyObject cycle(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"cycle");
         }
         
         return cycleCommon(contextself, -1, block);
     }
 
     @JRubyMethod
     public static IRubyObject cycle(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
         if (arg.isNil()) return cycle(contextselfblock);
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"cycle"arg);
         }
 
         long times = RubyNumeric.num2long(arg);
         if (times <= 0) {
             return context.runtime.getNil();
         }
 
         return cycleCommon(contextselftimesblock);
     }
 
     /*
      * @param nv number of times to cycle or -1 to cycle indefinitely
      */
     private static IRubyObject cycleCommon(ThreadContext contextIRubyObject selflong nvfinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         each(contextselfnew JavaInternalBlockBody(block.arity()) {
             public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                 synchronized (result) { result.append(arg); }
                 block.yield(contextarg);
                 return runtime.getNil();            
             }
         });
 
         int length = result.size();
         if (length == 0) return runtime.getNil();
 
         while (nv < 0 || 0 < --nv) {
             for (int i=0; i < lengthi++) {
                 block.yield(contextresult.eltInternal(i));
             }
         }
 
         return runtime.getNil();
     }
 
     @JRubyMethod(name = "take")
     public static IRubyObject take(ThreadContext contextIRubyObject selfIRubyObject nBlock block) {
         final Ruby runtime = context.runtime;
         final long len = RubyNumeric.num2long(n);
         
         if (len < 0) throw runtime.newArgumentError("attempt to take negative size");
         if (len == 0) return runtime.newEmptyArray();
 
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(.) {
                 long i = len// Atomic ?
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     synchronized (result) {
                         result.append(arg);
                         if (-- == 0) throw .
                     }
                     
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump e) {}
         
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject take_while(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"take_while");
         }
 
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(block.arity()) {
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     if (!block.yield(contextarg).isTrue()) throw .;
                     synchronized (result) { result.append(arg); }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
         return result;
     }    
 
     @JRubyMethod(name = "drop")
     public static IRubyObject drop(ThreadContext contextIRubyObject selfIRubyObject nfinal Block block) {
         final Ruby runtime = context.runtime;
         final long len = RubyNumeric.num2long(n);
         
         if (len < 0) throw runtime.newArgumentError("attempt to drop negative size");
 
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(.) {
                 long i = len// Atomic ?
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     synchronized (result) {
                         if ( == 0) {
                             // While iterating over an RubyEnumerator, "arg"
                             // gets overwritten by the new value, leading to JRUBY-6892.
                             // So call .dup() whenever appropriate.
                             result.append(arg.isImmediate() ? arg : arg.dup());
                         } else {
                             --;
                         }
                     }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump e) {}
         
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject drop_while(ThreadContext contextIRubyObject selffinal Block block) {
         if (!block.isGiven()) {
             return enumeratorize(context.runtimeself"drop_while");
         }
 
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         try {
             each(contextselfnew JavaInternalBlockBody(context"Enumerable#drop_while"block.arity()) {
                 boolean memo = false;
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     if (! && !block.yield(contextarg).isTrue())  = true;
                     if (synchronized (result) { result.append(arg); }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
         
         return result;
     }    
 
     @JRubyMethod(name = "first")
     public static IRubyObject first(ThreadContext contextIRubyObject self) {
         final IRubyObject[] holder = new IRubyObject[]{ context.runtime.getNil() };
 
         try {
             each(contextselfnew JavaInternalBlockBody(contextnull.) {
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     holder[0] = arg;
                     throw .;
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
 
         return holder[0];
     }
 
     @JRubyMethod(name = "first")
     public static IRubyObject first(ThreadContext contextIRubyObject selffinal IRubyObject num) {
         int firstCount = RubyNumeric.fix2int(num);
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         if (firstCount < 0) throw runtime.newArgumentError("negative index");
         if (firstCount == 0) return result;
 
         try {
             each(contextselfnew JavaInternalBlockBody(contextnull.) {
                 private int iter = RubyNumeric.fix2int(num);                
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     result.append(arg);
                     if (-- == 1) throw .;
                     return runtime.getNil();                
                 }
             });
         } catch (JumpException.SpecialJump sj) {}
 
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, compat = .)
     public static IRubyObject to_a(ThreadContext contextIRubyObject self) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, rest = true, compat = .)
     public static IRubyObject to_a(ThreadContext contextIRubyObject selfIRubyObject[] args) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         RuntimeHelpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(), 
                 .new AppendBlockCallback(runtimeresult), context));
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, compat = .)
     public static IRubyObject to_a19(ThreadContext contextIRubyObject self) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         result.infectBy(self);
         return result;
     }
 
     @JRubyMethod(name = {"to_a""entries"}, rest = true, compat = .)
     public static IRubyObject to_a19(ThreadContext contextIRubyObject selfIRubyObject[] args) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
         RuntimeHelpers.invoke(contextself"each"args, CallBlock.newCallClosure(selfruntime.getEnumerable(), 
                 .new AppendBlockCallback(runtimeresult), context));
         result.infectBy(self);
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject sort(ThreadContext contextIRubyObject selffinal Block block) {
         Ruby runtime = context.runtime;
         RubyArray result = runtime.newArray();
 
         callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         result.sort_bang(contextblock);
         
         return result;
     }
 
     public static IRubyObject sort_byCommon(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final ThreadContext localContext = context// MUST NOT be used across threads
 
         if (self instanceof RubyArray) {
             RubyArray selfArray = (RubyArrayself;
             final IRubyObject[][] valuesAndCriteria = new IRubyObject[selfArray.size()][2];
 
             each(contextselfnew JavaInternalBlockBody(.) {
                 AtomicInteger i = new AtomicInteger(0);
                 public IRubyObject yield(ThreadContext contextIRubyObject arg) {
                     IRubyObject[] myVandC = valuesAndCriteria[.getAndIncrement()];
                     myVandC[0] = arg;
                     myVandC[1] = block.yield(contextarg);
                     return runtime.getNil();
                 }
             });
             
             Arrays.sort(valuesAndCriterianew Comparator<IRubyObject[]>() {
                 public int compare(IRubyObject[] o1IRubyObject[] o2) {
                     return RubyFixnum.fix2int(invokedynamic(localContexto1[1], o2[1]));
                 }
             });
             
             IRubyObject dstArray[] = new IRubyObject[selfArray.size()];
             for (int i = 0; i < dstArray.lengthi++) {
                 dstArray[i] = valuesAndCriteria[i][0];
             }
 
             return runtime.newArrayNoCopy(dstArray);
         } else {
             final List<IRubyObject[]> valuesAndCriteria = new ArrayList<IRubyObject[]>();
 
             callEach(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     IRubyObject[] myVandC = new IRubyObject[2];
                     myVandC[0] = larg;
                     myVandC[1] = block.yield(ctxlarg);
                     valuesAndCriteria.add(myVandC);
                     return runtime.getNil();
                 }
             });
             
             Collections.sort(valuesAndCriterianew Comparator<IRubyObject[]>() {
                 public int compare(IRubyObject[] o1IRubyObject[] o2) {
                     return RubyFixnum.fix2int(invokedynamic(localContexto1[1], o2[1]));
                 }
             });
 
             IRubyObject dstArray[] = new IRubyObject[valuesAndCriteria.size()];
             for (int i = 0; i < dstArray.lengthi++) {
                 dstArray[i] = valuesAndCriteria.get(i)[0];
             }
 
             return runtime.newArrayNoCopy(dstArray);
         }
     }
 
     @JRubyMethod
     public static IRubyObject sort_by(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? sort_byCommon(contextselfblock) : enumeratorize(context.runtimeself"sort_by");
     }
 
     @JRubyMethod
     public static IRubyObject grep(ThreadContext contextIRubyObject selffinal IRubyObject patternfinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         if (block.isGiven()) {
             callEach(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     ctx.setRubyFrameDelta(ctx.getRubyFrameDelta()+2);
                     if (pattern.callMethod(ctx"==="larg).isTrue()) {
                         IRubyObject value = block.yield(ctxlarg);
                         synchronized (result) {
                             result.append(value);
                         }
                     }
                     ctx.setRubyFrameDelta(ctx.getRubyFrameDelta()-2);
                     return runtime.getNil();
                 }
             });
         } else {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     if (pattern.callMethod(ctx"==="larg).isTrue()) {
                         synchronized (result) {
                             result.append(larg);
                         }
                     }
                     return runtime.getNil();
                 }
             });
         }
         
         return result;
     }
 
     public static IRubyObject detectCommon(ThreadContext contextIRubyObject selffinal Block block) {
         return detectCommon(contextselfnullblock);
     }
 
     public static IRubyObject detectCommon(ThreadContext contextIRubyObject selfIRubyObject ifnonefinal Block block) {
         final Ruby runtime = context.runtime;
         final IRubyObject result[] = new IRubyObject[] { null };
         final ThreadContext localContext = context;
 
         try {
             callEach(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     checkContext(localContextctx"detect/find");
                     if (block.yield(ctxlarg).isTrue()) {
                         result[0] = larg;
                         throw .;
                     }
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {
             return result[0];
         }
 
         return ifnone != null ? ifnone.callMethod(context"call") : runtime.getNil();
     }
 
     @JRubyMethod
     public static IRubyObject detect(ThreadContext contextIRubyObject selffinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextnullblock);
 
         return block.isGiven() ? detectCommon(contextselfblock) : enumeratorize(context.runtimeself"detect");
     }
 
     @JRubyMethod
     public static IRubyObject detect(ThreadContext contextIRubyObject selfIRubyObject ifnonefinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextifnoneblock);
 
         return block.isGiven() ? detectCommon(contextselfifnoneblock) : enumeratorize(context.runtimeself"detect"ifnone);
     }
 
     // FIXME: Custom Array enumeratorize should be made for all of these methods which skip Array without a supplied block.
     @JRubyMethod
     public static IRubyObject find(ThreadContext contextIRubyObject selffinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextnullblock);
 
         return blockGiven ? detectCommon(contextselfblock) : enumeratorize(context.runtimeself"find");
     }
 
     @JRubyMethod
     public static IRubyObject find(ThreadContext contextIRubyObject selfIRubyObject ifnonefinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find(contextifnoneblock);
 
         return blockGiven ? detectCommon(contextselfifnoneblock) :
             enumeratorize(context.runtimeself"find"ifnone);
     }
 
     @JRubyMethod
     public static IRubyObject find_index(ThreadContext contextIRubyObject selffinal Block block) {
         boolean blockGiven = block.isGiven();
 
         if (self instanceof RubyArray && blockGivenreturn ((RubyArrayself).find_index(contextblock);
 
         return blockGiven ? find_indexCommon(contextselfblock) :
             enumeratorize(context.runtimeself"find_index");
     }
 
     @JRubyMethod
     public static IRubyObject find_index(ThreadContext contextIRubyObject selffinal IRubyObject condfinal Block block) {
         final Ruby runtime = context.runtime;
 
         if (block.isGiven()) runtime.getWarnings().warn(. , "given block not used");
         if (self instanceof RubyArrayreturn ((RubyArrayself).find_index(contextcond);
 
         return find_indexCommon(contextselfcond);
     }
 
     public static IRubyObject find_indexCommon(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final long result[] = new long[] {0};
 
         try {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     if (block.yield(ctxlarg).isTrue()) throw .;
                     result[0]++;
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {
             return RubyFixnum.newFixnum(runtimeresult[0]);
         }
         
         return runtime.getNil();
     }
 
     public static IRubyObject find_indexCommon(ThreadContext contextIRubyObject selffinal IRubyObject cond) {
         final Ruby runtime = context.runtime;
         final long result[] = new long[] {0};
 
         try {
             callEach(runtimecontextself.new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     if (larg.equals(cond)) throw .;
                     result[0]++;
                     return runtime.getNil();
                 }
             });
         } catch (JumpException.SpecialJump sj) {
             return RubyFixnum.newFixnum(runtimeresult[0]);
         }
 
         return runtime.getNil();
     }
 
     public static IRubyObject selectCommon(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         callEach(runtimecontextselfblock.arity(), new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = checkArgs(runtimelargs);
                 if (block.yield(ctxlarg).isTrue()) {
                     synchronized (result) {
                         result.append(larg);
                     }
                 }
                 return runtime.getNil();
             }
         });
 
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject select(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? selectCommon(contextselfblock) : enumeratorize(context.runtimeself"select");
     }
 
     @JRubyMethod
     public static IRubyObject find_all(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? selectCommon(contextselfblock) : enumeratorize(context.runtimeself"find_all");
     }
 
     public static IRubyObject rejectCommon(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         callEach(runtimecontextselfblock.arity(), new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = checkArgs(runtimelargs);
                 if (!block.yield(ctxlarg).isTrue()) {
                     synchronized (result) {
                         result.append(larg);
                     }
                 }
                 return runtime.getNil();
             }
         });
 
         return result;
     }
 
     @JRubyMethod
     public static IRubyObject reject(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? rejectCommon(contextselfblock) : enumeratorize(context.runtimeself"reject");
     }
 
     @JRubyMethod(name = {"collect""map"}, compat = .)
     public static IRubyObject collect(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray result = runtime.newArray();
 
         if (block.isGiven()) {
             callEach(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     IRubyObject value = block.yield(ctxlarg);
                     synchronized (result) {
                         result.append(value);
                     }
                     return runtime.getNil();
                 }
             });
         } else {
             callEach(runtimecontextself.new AppendBlockCallback(runtimeresult));
         }
         return result;
     }
 
     @JRubyMethod(name = {"collect"}, compat = .)
     public static IRubyObject collect19(ThreadContext contextIRubyObject selffinal Block block) {
         return collectCommon19(contextselfblock"collect");
     }
 
     @JRubyMethod(name = {"map"}, compat = .)
     public static IRubyObject map19(ThreadContext contextIRubyObject selffinal Block block) {
         return collectCommon19(contextselfblock"map");
     }
 
     private static IRubyObject collectCommon19(ThreadContext contextIRubyObject selffinal Block blockString methodName) {
         final Ruby runtime = context.runtime;
         if (block.isGiven()) {
             final RubyArray result = runtime.newArray();
 
             callEach19(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg;
                     boolean newAry = false;
                     if (largs.length == 0) {
                         larg = ctx.nil;
                     } else if (largs.length == 1) {
                         larg = largs[0];
                     } else {
                         newAry = true;
                         larg = RubyArray.newArrayNoCopy(ctx.runtimelargs);
                     }
                     
                     IRubyObject value = newAry ? block.yieldArray(ctxlargnullnull) : block.yield(ctxlarg);
                     synchronized (result) {
                         result.append(value);
                     }
                     return runtime.getNil();
                 }
             });
             return result;
         } else {
             return enumeratorize(runtimeselfmethodName);
         }
     }
 
     public static IRubyObject collectCommon(ThreadContext contextRuby runtimeIRubyObject self,
             RubyArray resultfinal Block blockBlockCallback blockCallback) {
         callEach(runtimecontextself.blockCallback);
         return result;
     }
 
     @JRubyMethod(name = {"flat_map"}, compat = .)
     public static IRubyObject flat_map19(ThreadContext contextIRubyObject selffinal Block block) {
         return flatMapCommon19(contextselfblock"flat_map");
     }
 
     @JRubyMethod(name = {"collect_concat"}, compat = .)
     public static IRubyObject collect_concat19(ThreadContext contextIRubyObject selffinal Block block) {
         return flatMapCommon19(contextselfblock"collect_concat");
     }
 
     private static IRubyObject flatMapCommon19(ThreadContext contextIRubyObject selffinal Block blockString methodName) {
         final Ruby runtime = context.runtime;
         if(block.isGiven()) {
             final RubyArray ary = runtime.newArray();
 
             callEach(runtimecontextselfblock.arity(), new BlockCallback() {
                 public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                     IRubyObject larg = checkArgs(runtimelargs);
                     IRubyObject i = block.yield(ctxlarg);
                     IRubyObject tmp = i.checkArrayType();
                     synchronized(ary) {
                         if(tmp.isNil()) {
                             ary.append(i);
                         } else {
                             ary.concat(tmp);
                         }
                     }
                     return runtime.getNil();
                 }
             });
             return ary;
         } else {
             return enumeratorize(runtimeselfmethodName);
         }
     }
 
     public static IRubyObject injectCommon(ThreadContext contextIRubyObject selfIRubyObject initfinal Block block) {
         final Ruby runtime = context.runtime;
         final IRubyObject result[] = new IRubyObject[] { init };
         final ThreadContext localContext = context;
 
         callEach(runtimecontextselfblock.arity(), new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = checkArgs(runtimelargs);
                 checkContext(localContextctx"inject");
                 result[0] = result[0] == null ? 
                         larg : block.yieldArray(ctxruntime.newArray(result[0], larg), nullnull);
 
                 return runtime.getNil();
             }
         });
 
         return result[0] == null ? runtime.getNil() : result[0];
     }
 
     @JRubyMethod(name = {"inject""reduce"})
     public static IRubyObject inject(ThreadContext contextIRubyObject selffinal Block block) {
         return injectCommon(contextselfnullblock);
     }
     
     @JRubyMethod(name = {"inject""reduce"})
     public static IRubyObject inject(ThreadContext contextIRubyObject selfIRubyObject argfinal Block block) {
         return block.isGiven() ? injectCommon(contextselfargblock) : inject(contextselfnullargblock);
     }
 
     @JRubyMethod(name = {"inject""reduce"})
     public static IRubyObject inject(ThreadContext contextIRubyObject selfIRubyObject initIRubyObject methodfinal Block block) {
         final Ruby runtime = context.runtime;
 
         if (block.isGiven()) runtime.getWarnings().warn(. , "given block not used");
 
         final String methodId = method.asJavaString();
         final IRubyObject result[] = new IRubyObject[] { init }; 
 
         callEach(runtimecontextself.new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = checkArgs(runtimelargs);
                 result[0] = result[0] == null ? larg : result[0].callMethod(ctxmethodIdlarg);
                 return runtime.getNil();
             }
         });
         return result[0] == null ? runtime.getNil() : result[0];
     }
 
     public static IRubyObject partitionCommon(ThreadContext contextIRubyObject selffinal Block block) {
         final Ruby runtime = context.runtime;
         final RubyArray arr_true = runtime.newArray();
         final RubyArray arr_false = runtime.newArray();
 
         callEach(runtimecontextselfblock.arity(), new BlockCallback() {
             public IRubyObject call(ThreadContext ctxIRubyObject[] largsBlock blk) {
                 IRubyObject larg = checkArgs(runtimelargs);
                 if (block.yield(ctxlarg).isTrue()) {
                     synchronized (arr_true) {
                         arr_true.append(larg);
                     }
                 } else {
                     synchronized (arr_false) {
                         arr_false.append(larg);
                     }
                 }
 
                 return runtime.getNil();
             }
         });
 
         return runtime.newArray(arr_truearr_false);
     }
 
     @JRubyMethod(name = "partition")
     public static IRubyObject partition(ThreadContext contextIRubyObject selffinal Block block) {
         return block.isGiven() ? partitionCommon(contextselfblock) : enumeratorize(context.runtimeself"partition");
     }
 
     private static class EachWithIndex implements BlockCallback {
         private int index = 0;
         private final Block block;
         private final Ruby runtime;
 
         public EachWithIndex(ThreadContext ctxBlock block) {
             this. = block;
             this. = ctx.runtime;
         }
 
         public IRubyObject call(ThreadContext contextIRubyObject[] iargsBlock block) {