public static AnnotationValue[] toArray(List<AnnotationValue> list) {
   AnnotationValue[] values = EMPTY_ANNOTATION_VALUE_ARRAY;
   if (CollectionHelper.isNotEmpty(list)) {
     values = list.toArray(new AnnotationValue[list.size()]);
   }
   return values;
 }
  private Collection<MethodDescriptor> extractMethods(
      Class clazz, JavaTypeDescriptor declaringType, JandexPivot jandexPivot) {
    final Method[] declaredMethods = clazz.getDeclaredMethods();
    final Method[] methods = clazz.getMethods();

    if (declaredMethods.length <= 0 && methods.length <= 0) {
      return Collections.emptyList();
    }

    final List<MethodDescriptor> methodDescriptors = CollectionHelper.arrayList(methods.length);

    for (Method method : declaredMethods) {
      methodDescriptors.add(fromMethod(method, declaringType, jandexPivot));
    }

    for (Method method : methods) {
      if (clazz.equals(method.getDeclaringClass())) {
        continue;
      }

      final JavaTypeDescriptor methodDeclarer =
          getType(buildName(method.getDeclaringClass().getName()));
      methodDescriptors.add(fromMethod(method, methodDeclarer, jandexPivot));
    }

    return methodDescriptors;
  }
 /**
  * util method for String Array attribute Annotation
  *
  * @param name
  * @param values
  * @param annotationValueList
  */
 static void stringArrayValue(
     String name, List<String> values, List<AnnotationValue> annotationValueList) {
   if (CollectionHelper.isNotEmpty(values)) {
     AnnotationValue[] annotationValues = new AnnotationValue[values.size()];
     for (int j = 0; j < values.size(); j++) {
       annotationValues[j] = stringValue("", values.get(j));
     }
     annotationValueList.add(AnnotationValue.createArrayValue(name, annotationValues));
   }
 }
  static void enumArrayValue(
      String name, DotName typeName, List<Enum> valueList, List<AnnotationValue> list) {
    if (CollectionHelper.isNotEmpty(valueList)) {

      List<AnnotationValue> enumValueList = new ArrayList<AnnotationValue>(valueList.size());
      for (Enum e : valueList) {
        addToCollectionIfNotNull(enumValueList, enumValue("", typeName, e));
      }
      list.add(AnnotationValue.createArrayValue(name, toArray(enumValueList)));
    }
  }
  public Map<Class<?>, MappedSuperclassType<?>> getMappedSuperclassTypeMap() {
    // we need to actually build this map...
    final Map<Class<?>, MappedSuperclassType<?>> mappedSuperClassTypeMap =
        CollectionHelper.mapOfSize(mappedSuperclassByMappedSuperclassMapping.size());

    for (MappedSuperclassTypeImpl mappedSuperclassType :
        mappedSuperclassByMappedSuperclassMapping.values()) {
      mappedSuperClassTypeMap.put(mappedSuperclassType.getJavaType(), mappedSuperclassType);
    }

    return mappedSuperClassTypeMap;
  }
  private List<JavaTypeDescriptor> extractTypeParameters(ResolvedType resolvedType) {
    if (resolvedType.getTypeParameters().isEmpty()) {
      return Collections.emptyList();
    }

    final List<JavaTypeDescriptor> result =
        CollectionHelper.arrayList(resolvedType.getTypeParameters().size());
    for (ResolvedType typeParameter : resolvedType.getTypeParameters()) {
      result.add(getType(buildName(typeParameter.getErasedSignature())));
    }
    return result;
  }
  private Collection<InterfaceDescriptor> extractInterfaces(Class clazz) {
    final Class[] interfaces = clazz.getInterfaces();
    if (interfaces == null || interfaces.length <= 0) {
      return Collections.emptyList();
    }

    final Collection<InterfaceDescriptor> interfaceTypes =
        CollectionHelper.arrayList(interfaces.length);
    for (Class anInterface : interfaces) {
      interfaceTypes.add((InterfaceDescriptor) getType(buildName(anInterface.getName())));
    }
    return interfaceTypes;
  }
  private static Map<String, GraphNode<?>> makeSafeGraphNodeMapCopy(
      Map<String, GraphNode<?>> graphNodeMap) {
    if (graphNodeMap == null) {
      return null;
    }

    final HashMap<String, GraphNode<?>> copy =
        new HashMap<String, GraphNode<?>>(CollectionHelper.determineProperSizing(graphNodeMap));
    for (Map.Entry<String, GraphNode<?>> attributeNodeEntry : graphNodeMap.entrySet()) {
      copy.put(attributeNodeEntry.getKey(), attributeNodeEntry.getValue().makeImmutableCopy());
    }
    return copy;
  }
 protected void sortMethods(List<FrameworkMethod> computedTestMethods) {
   if (CollectionHelper.isEmpty(computedTestMethods)) {
     return;
   }
   Collections.sort(
       computedTestMethods,
       new Comparator<FrameworkMethod>() {
         @Override
         public int compare(FrameworkMethod o1, FrameworkMethod o2) {
           return o1.getName().compareTo(o2.getName());
         }
       });
 }
  static void classArrayValue(
      String name,
      List<String> classNameList,
      List<AnnotationValue> list,
      ServiceRegistry serviceRegistry) {
    if (CollectionHelper.isNotEmpty(classNameList)) {

      List<AnnotationValue> clazzValueList = new ArrayList<AnnotationValue>(classNameList.size());
      for (String clazz : classNameList) {
        addToCollectionIfNotNull(clazzValueList, classValue("", clazz, serviceRegistry));
      }

      list.add(AnnotationValue.createArrayValue(name, toArray(clazzValueList)));
    }
  }
  private MethodDescriptor fromMethod(
      Method method, JavaTypeDescriptor declaringType, JandexPivot jandexPivot) {
    final Class[] parameterTypes = method.getParameterTypes();
    final Collection<JavaTypeDescriptor> argumentTypes;
    if (parameterTypes.length == 0) {
      argumentTypes = Collections.emptyList();
    } else {
      argumentTypes = CollectionHelper.arrayList(parameterTypes.length);
      for (Class parameterType : parameterTypes) {
        argumentTypes.add(toTypeDescriptor(parameterType));
      }
    }

    return new MethodDescriptorImpl(
        method.getName(),
        declaringType,
        method.getModifiers(),
        toTypeDescriptor(method.getReturnType()),
        argumentTypes,
        jandexPivot.methodAnnotations.get(buildMethodAnnotationsKey(method)));
  }
  private Collection<FieldDescriptor> extractFields(
      Class clazz, JavaTypeDescriptor declaringType, JandexPivot jandexPivot) {
    final Field[] declaredFields = clazz.getDeclaredFields();
    final Field[] fields = clazz.getFields();

    if (declaredFields.length <= 0 && fields.length <= 0) {
      return Collections.emptyList();
    }

    final List<FieldDescriptor> fieldDescriptors = CollectionHelper.arrayList(fields.length);

    for (Field field : declaredFields) {
      fieldDescriptors.add(
          new FieldDescriptorImpl(
              field.getName(),
              toTypeDescriptor(field.getType()),
              field.getModifiers(),
              declaringType,
              jandexPivot.fieldAnnotations.get(field.getName())));
    }

    for (Field field : fields) {
      if (clazz.equals(field.getDeclaringClass())) {
        continue;
      }

      final JavaTypeDescriptor fieldDeclarer =
          getType(buildName(field.getDeclaringClass().getName()));
      fieldDescriptors.add(
          new FieldDescriptorImpl(
              field.getName(),
              toTypeDescriptor(field.getType()),
              field.getModifiers(),
              fieldDeclarer,
              jandexPivot.fieldAnnotations.get(field.getName())));
    }
    return fieldDescriptors;
  }
 private LocalBindingContextImpl(MetadataImplementor metadata) {
   this.metadata = metadata;
   this.localMappingDefaults =
       new OverriddenMappingDefaults(
           metadata.getMappingDefaults(),
           hbmBindResult.getRoot().getPackage(),
           hbmBindResult.getRoot().getSchema(),
           hbmBindResult.getRoot().getCatalog(),
           null,
           null,
           null,
           hbmBindResult.getRoot().getDefaultCascade(),
           hbmBindResult.getRoot().getDefaultAccess(),
           hbmBindResult.getRoot().isDefaultLazy());
   if (CollectionHelper.isEmpty(hbmBindResult.getRoot().getMeta())) {
     this.metaAttributeContext =
         new MetaAttributeContext(metadata.getGlobalMetaAttributeContext());
   } else {
     this.metaAttributeContext =
         Helper.extractMetaAttributeContext(
             hbmBindResult.getRoot().getMeta(), true, metadata.getGlobalMetaAttributeContext());
   }
 }
    private ArrayList<MetadataSourceType> resolveInitialSourceProcessOrdering(
        ConfigurationService configService) {
      final ArrayList<MetadataSourceType> initialSelections = new ArrayList<MetadataSourceType>();

      final String sourceProcessOrderingSetting =
          configService.getSetting(
              AvailableSettings.ARTIFACT_PROCESSING_ORDER, StandardConverters.STRING);
      if (sourceProcessOrderingSetting != null) {
        final String[] orderChoices =
            StringHelper.split(",; ", sourceProcessOrderingSetting, false);
        initialSelections.addAll(
            CollectionHelper.<MetadataSourceType>arrayList(orderChoices.length));
        for (String orderChoice : orderChoices) {
          initialSelections.add(MetadataSourceType.parsePrecedence(orderChoice));
        }
      }
      if (initialSelections.isEmpty()) {
        initialSelections.add(MetadataSourceType.HBM);
        initialSelections.add(MetadataSourceType.CLASS);
      }

      return initialSelections;
    }
  /**
   * Package-protected method to centralize checking of criteria query multi-selects as defined by
   * the {@link CriteriaQuery#multiselect(List)} method.
   *
   * @param selections The selection varargs to check
   * @throws IllegalArgumentException If the selection items are not valid per {@link
   *     CriteriaQuery#multiselect} documentation. <i>&quot;An argument to the multiselect method
   *     must not be a tuple- or array-valued compound selection item.&quot;</i>
   */
  void checkMultiselect(List<Selection<?>> selections) {
    final HashSet<String> aliases =
        new HashSet<String>(CollectionHelper.determineProperSizing(selections.size()));

    for (Selection<?> selection : selections) {
      if (selection.isCompoundSelection()) {
        if (selection.getJavaType().isArray()) {
          throw new IllegalArgumentException(
              "Selection items in a multi-select cannot contain compound array-valued elements");
        }
        if (Tuple.class.isAssignableFrom(selection.getJavaType())) {
          throw new IllegalArgumentException(
              "Selection items in a multi-select cannot contain compound tuple-valued elements");
        }
      }
      if (StringHelper.isNotEmpty(selection.getAlias())) {
        boolean added = aliases.add(selection.getAlias());
        if (!added) {
          throw new IllegalArgumentException(
              "Multi-select expressions defined duplicate alias : " + selection.getAlias());
        }
      }
    }
  }
 private void prepare() {
   // assume 20 services for initial sizing
   this.serviceBindingMap = CollectionHelper.concurrentMap(20);
   this.serviceList = CollectionHelper.arrayList(20);
 }
/** @author Steve Ebersole */
public abstract class AbstractServiceRegistryImpl
    implements ServiceRegistryImplementor, ServiceBinding.ServiceLifecycleOwner {

  private static final CoreMessageLogger LOG =
      Logger.getMessageLogger(CoreMessageLogger.class, AbstractServiceRegistryImpl.class.getName());

  private final ServiceRegistryImplementor parent;

  private final ConcurrentHashMap<Class, ServiceBinding> serviceBindingMap =
      CollectionHelper.concurrentMap(20);

  // IMPL NOTE : the list used for ordered destruction.  Cannot used map above because we need to
  // iterate it in reverse order which is only available through ListIterator
  // assume 20 services for initial sizing
  private final List<ServiceBinding> serviceBindingList = CollectionHelper.arrayList(20);

  @SuppressWarnings({"UnusedDeclaration"})
  protected AbstractServiceRegistryImpl() {
    this((ServiceRegistryImplementor) null);
  }

  protected AbstractServiceRegistryImpl(ServiceRegistryImplementor parent) {
    this.parent = parent;
  }

  public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
    if (!ServiceRegistryImplementor.class.isInstance(bootstrapServiceRegistry)) {
      throw new IllegalArgumentException("Boot-strap registry was not ");
    }
    this.parent = (ServiceRegistryImplementor) bootstrapServiceRegistry;
  }

  @SuppressWarnings({"unchecked"})
  protected <R extends Service> void createServiceBinding(ServiceInitiator<R> initiator) {
    serviceBindingMap.put(initiator.getServiceInitiated(), new ServiceBinding(this, initiator));
  }

  protected <R extends Service> void createServiceBinding(ProvidedService<R> providedService) {
    ServiceBinding<R> binding = locateServiceBinding(providedService.getServiceRole(), false);
    if (binding == null) {
      binding =
          new ServiceBinding<R>(
              this, providedService.getServiceRole(), providedService.getService());
      serviceBindingMap.put(providedService.getServiceRole(), binding);
    }
    registerService(binding, providedService.getService());
  }

  @Override
  @SuppressWarnings({"unchecked"})
  public ServiceRegistry getParentServiceRegistry() {
    return parent;
  }

  @Override
  @SuppressWarnings({"unchecked"})
  public <R extends Service> ServiceBinding<R> locateServiceBinding(Class<R> serviceRole) {
    return locateServiceBinding(serviceRole, true);
  }

  @SuppressWarnings({"unchecked"})
  protected <R extends Service> ServiceBinding<R> locateServiceBinding(
      Class<R> serviceRole, boolean checkParent) {
    ServiceBinding<R> serviceBinding = serviceBindingMap.get(serviceRole);
    if (serviceBinding == null && checkParent && parent != null) {
      // look in parent
      serviceBinding = parent.locateServiceBinding(serviceRole);
    }
    return serviceBinding;
  }

  @Override
  public <R extends Service> R getService(Class<R> serviceRole) {
    final ServiceBinding<R> serviceBinding = locateServiceBinding(serviceRole);
    if (serviceBinding == null) {
      throw new UnknownServiceException(serviceRole);
    }

    R service = serviceBinding.getService();
    if (service == null) {
      service = initializeService(serviceBinding);
    }

    return service;
  }

  protected <R extends Service> void registerService(ServiceBinding<R> serviceBinding, R service) {
    serviceBinding.setService(service);
    synchronized (serviceBindingList) {
      serviceBindingList.add(serviceBinding);
    }
  }

  private <R extends Service> R initializeService(ServiceBinding<R> serviceBinding) {
    if (LOG.isTraceEnabled()) {
      LOG.tracev("Initializing service [role={0}]", serviceBinding.getServiceRole().getName());
    }

    // PHASE 1 : create service
    R service = createService(serviceBinding);
    if (service == null) {
      return null;
    }

    // PHASE 2 : inject service (***potentially recursive***)
    serviceBinding.getLifecycleOwner().injectDependencies(serviceBinding);

    // PHASE 3 : configure service
    serviceBinding.getLifecycleOwner().configureService(serviceBinding);

    // PHASE 4 : Start service
    serviceBinding.getLifecycleOwner().startService(serviceBinding);
    startService(serviceBinding);

    return service;
  }

  @SuppressWarnings({"unchecked"})
  protected <R extends Service> R createService(ServiceBinding<R> serviceBinding) {
    final ServiceInitiator<R> serviceInitiator = serviceBinding.getServiceInitiator();
    if (serviceInitiator == null) {
      // this condition should never ever occur
      throw new UnknownServiceException(serviceBinding.getServiceRole());
    }

    try {
      R service = serviceBinding.getLifecycleOwner().initiateService(serviceInitiator);
      // IMPL NOTE : the register call here is important to avoid potential stack overflow issues
      //		from recursive calls through #configureService
      registerService(serviceBinding, service);
      return service;
    } catch (ServiceException e) {
      throw e;
    } catch (Exception e) {
      throw new ServiceException(
          "Unable to create requested service [" + serviceBinding.getServiceRole().getName() + "]",
          e);
    }
  }

  @Override
  public <R extends Service> void injectDependencies(ServiceBinding<R> serviceBinding) {
    final R service = serviceBinding.getService();

    applyInjections(service);

    if (ServiceRegistryAwareService.class.isInstance(service)) {
      ((ServiceRegistryAwareService) service).injectServices(this);
    }
  }

  private <R extends Service> void applyInjections(R service) {
    try {
      for (Method method : service.getClass().getMethods()) {
        InjectService injectService = method.getAnnotation(InjectService.class);
        if (injectService == null) {
          continue;
        }

        processInjection(service, method, injectService);
      }
    } catch (NullPointerException e) {
      LOG.error("NPE injecting service deps : " + service.getClass().getName());
    }
  }

  @SuppressWarnings({"unchecked"})
  private <T extends Service> void processInjection(
      T service, Method injectionMethod, InjectService injectService) {
    if (injectionMethod.getParameterTypes() == null
        || injectionMethod.getParameterTypes().length != 1) {
      throw new ServiceDependencyException(
          "Encountered @InjectService on method with unexpected number of parameters");
    }

    Class dependentServiceRole = injectService.serviceRole();
    if (dependentServiceRole == null || dependentServiceRole.equals(Void.class)) {
      dependentServiceRole = injectionMethod.getParameterTypes()[0];
    }

    // todo : because of the use of proxies, this is no longer returning null here...

    final Service dependantService = getService(dependentServiceRole);
    if (dependantService == null) {
      if (injectService.required()) {
        throw new ServiceDependencyException(
            "Dependency ["
                + dependentServiceRole
                + "] declared by service ["
                + service
                + "] not found");
      }
    } else {
      try {
        injectionMethod.invoke(service, dependantService);
      } catch (Exception e) {
        throw new ServiceDependencyException("Cannot inject dependency service", e);
      }
    }
  }

  @Override
  @SuppressWarnings({"unchecked"})
  public <R extends Service> void startService(ServiceBinding<R> serviceBinding) {
    if (Startable.class.isInstance(serviceBinding.getService())) {
      ((Startable) serviceBinding.getService()).start();
    }

    if (Manageable.class.isInstance(serviceBinding.getService())) {
      getService(JmxService.class)
          .registerService(
              (Manageable) serviceBinding.getService(), serviceBinding.getServiceRole());
    }
  }

  @Override
  @SuppressWarnings({"unchecked"})
  public void destroy() {
    synchronized (serviceBindingList) {
      ListIterator<ServiceBinding> serviceBindingsIterator =
          serviceBindingList.listIterator(serviceBindingList.size());
      while (serviceBindingsIterator.hasPrevious()) {
        final ServiceBinding serviceBinding = serviceBindingsIterator.previous();
        serviceBinding.getLifecycleOwner().stopService(serviceBinding);
      }
      serviceBindingList.clear();
    }
    serviceBindingMap.clear();
  }

  @Override
  public <R extends Service> void stopService(ServiceBinding<R> binding) {
    final Service service = binding.getService();
    if (Stoppable.class.isInstance(service)) {
      try {
        ((Stoppable) service).stop();
      } catch (Exception e) {
        LOG.unableToStopService(service.getClass(), e.toString());
      }
    }
  }
}