/*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,  
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jboss.weld.bean.proxy;

import static org.jboss.weld.logging.messages.BeanMessage.UNEXPECTED_UNWRAPPED_CUSTOM_DECORATOR;
import static org.jboss.weld.util.reflection.Reflections.ensureAccessible;

import java.lang.reflect.Method;
import java.util.List;

import javax.enterprise.inject.spi.Decorator;

import org.jboss.interceptor.util.proxy.TargetInstanceProxyMethodHandler;
import org.jboss.weld.ForbiddenStateException;
import org.jboss.weld.bean.AnnotatedItemProvidingDecoratorWrapper;
import org.jboss.weld.bean.DecoratorImpl;
import org.jboss.weld.introspector.MethodSignature;
import org.jboss.weld.introspector.WeldMethod;
import org.jboss.weld.introspector.jlr.MethodSignatureImpl;
import org.jboss.weld.serialization.spi.helpers.SerializableContextualInstance;

/**
 * Method handler for decorated beans
 * 
 * @author Pete Muir
 * 
 */
public class DecoratorProxyMethodHandler extends TargetInstanceProxyMethodHandler
{
   private static final long serialVersionUID = 4577632640130385060L;

   private final List<SerializableContextualInstance<Decorator<Object>, Object>> decoratorInstances;

   /**
    * Constructor
    * 
    * @param removeMethods
    * 
    * @param proxy The generic proxy
    */
   public DecoratorProxyMethodHandler(List<SerializableContextualInstance<Decorator<Object>, Object>> decoratorInstances, Object instance)
   {
      super (instance, instance.getClass());
      this.decoratorInstances = decoratorInstances;
   }
   
   /**
    * 
    * 
    * @param self the proxy instance.
    * @param method the overridden method declared in the super class or
    *           interface.
    * @param proceed the forwarder method for invoking the overridden method. It
    *           is null if the overridden method is abstract or declared in the
    *           interface.
    * @param args an array of objects containing the values of the arguments
    *           passed in the method invocation on the proxy instance. If a
    *           parameter type is a primitive type, the type of the array
    *           element is a wrapper class.
    * @return the resulting value of the method invocation.
    * 
    * @throws Throwable if the method invocation fails.
    */
   @Override
   protected Object doInvoke(Object self, Method method, Method proceed, Object[] args) throws Throwable
   {
      MethodSignature methodSignature = new MethodSignatureImpl(method);
      for (SerializableContextualInstance<Decorator<Object>, Object> beanInstance : decoratorInstances)
      {
         WeldMethod<?, ?> decoratorMethod;
         if (beanInstance.getContextual().get() instanceof DecoratorImpl<?>)
         {
            decoratorMethod = ((DecoratorImpl<?>)beanInstance.getContextual().get()).getAnnotatedItem().getWeldMethod(methodSignature);
         }
         else if (beanInstance.getContextual().get() instanceof AnnotatedItemProvidingDecoratorWrapper)
         {
            decoratorMethod = ((AnnotatedItemProvidingDecoratorWrapper)beanInstance.getContextual().get()).getAnnotatedItem().getWeldMethod(methodSignature);
         }
         else
         {
            throw new ForbiddenStateException(UNEXPECTED_UNWRAPPED_CUSTOM_DECORATOR, beanInstance.getContextual().get());
         }
         if (decoratorMethod != null)
         {
            return decoratorMethod.invokeOnInstance(beanInstance.getInstance(), args);
         }
      }
      
      return ensureAccessible(method).invoke(getTargetInstance(), args);
   }
}

@@ -916,83 +916,8 @@
 TOR;
-%0Aimport static org.jboss.weld.util.reflection.Reflections.ensureAccessible;
 %0A%0Aim
@@ -1486,16 +1486,67 @@
 nstance;
+%0Aimport org.jboss.weld.util.reflection.Reflections;
 %0A%0A/**%0A *
@@ -3330,16 +3330,17 @@
 Method;%0A
+%0A
         
@@ -4187,40 +4187,27 @@
 urn 
-ensureAccessible(method)
+Reflections
 .invoke(
 getT
@@ -4202,16 +4202,23 @@
 .invoke(
+method,
 getTarge

Use Reflections.invoke