/** @return any Criteria. If no Criteria has been established we establish one and return it. */
 private Criteria getOrEstablishSomeCriteria() {
   Criteria criteria = getSomeCriteria();
   if (criteria == null) {
     final Shard shard = shards.get(0);
     criteria = shard.establishCriteria(this);
   }
   return criteria;
 }
 /** @return any Criteria, or null if we don't have one */
 private /*@Nullable*/ Criteria getSomeCriteria() {
   for (final Shard shard : shards) {
     final Criteria criteria = shard.getCriteriaById(criteriaId);
     if (criteria != null) {
       return criteria;
     }
   }
   return null;
 }
 /**
  * @return Returns an actual Criteria object. If no actual Criteria object has been allocated,
  *     allocate one and return it.
  */
 private Criteria getOrEstablishSomeSubcriteria() {
   Criteria crit = getSomeSubcriteria();
   if (crit == null) {
     Shard shard = shards.get(0);
     // this should trigger the creation of all subcriteria for the parent
     shard.establishCriteria(parent);
   }
   return getSomeSubcriteria();
 }
 private ShardedCriteriaImpl setCriteriaEvent(final CriteriaEvent event) {
   for (final Shard shard : shards) {
     if (shard.getCriteriaById(criteriaId) != null) {
       event.onEvent(shard.getCriteriaById(criteriaId));
     } else {
       shard.addCriteriaEvent(criteriaId, event);
     }
   }
   return this;
 }
 @Override
 public boolean isReadOnlyInitialized() {
   for (final Shard shard : shards) {
     if (shard.getCriteriaById(criteriaId) != null) {
       if (!shard.getCriteriaById(criteriaId).isReadOnlyInitialized()) {
         // any one shard is not read only, we return false as a whole
         return false;
       }
     }
   }
   return true;
 }
 public ShardedSessionStatistics(ShardedSessionImplementor session) {
   sessionStatistics = Sets.newHashSet();
   for (Shard s : session.getShards()) {
     if (s.getSession() != null) {
       sessionStatistics.add(s.getSession().getStatistics());
     } else {
       OpenSessionEvent ose =
           new OpenSessionEvent() {
             public void onOpenSession(Session session) {
               sessionStatistics.add(session.getStatistics());
             }
           };
       s.addOpenSessionEvent(ose);
     }
   }
 }
  /**
   * Creating sharded subcriteria is tricky. We need to give the client a reference to a
   * ShardedSubcriteriaImpl (which to the client just looks like a Criteria object). Then, for each
   * shard where the Criteria has already been established we need to create the actual subcriteria,
   * and for each shard where the Criteria has not yet been established we need to register an event
   * that will create the Subcriteria when the Criteria is established.
   *
   * @param factory the factory to use to create the subcriteria
   * @param associationPath the association path to the property on which we're creating a
   *     subcriteria
   * @return a new ShardedSubcriteriaImpl
   */
  private ShardedSubcriteriaImpl createSubcriteria(
      final SubcriteriaFactory factory, final String associationPath) {

    final ShardedSubcriteriaImpl subcriteria =
        new ShardedSubcriteriaImpl(shards, this, criteriaCollector, associationPath);

    for (final Shard shard : shards) {
      final Criteria criteria = shard.getCriteriaById(criteriaId);
      if (criteria != null) {
        factory.createSubcriteria(criteria, NO_CRITERIA_EVENTS);
      } else {
        final CreateSubcriteriaEvent event =
            new CreateSubcriteriaEvent(factory, subcriteria.getSubcriteriaRegistrar(shard));
        shard.addCriteriaEvent(criteriaId, event);
      }
    }
    return subcriteria;
  }