public WeightedRandomModel(ModelResourceLocation parent, Variants variants) {
      this.variants = variants.getVariants();
      ImmutableList.Builder<Pair<IModel, IModelState>> builder = ImmutableList.builder();
      for (Variant v : (List<Variant>) variants.getVariants()) {
        ResourceLocation loc = v.getModelLocation();
        locations.add(loc);

        IModel model = null;
        try {
          model = getModel(loc);
        } catch (Exception e) {
          /*
           * Vanilla eats this, which makes it only show variants that have models.
           * But that doesn't help debugging, so we maintain the missing model
           * so that resource pack makers have a hint that their states are broken.
           */
          FMLLog.warning(
              "Unable to load block model: \'"
                  + loc
                  + "\' for variant: \'"
                  + parent
                  + "\': "
                  + e.toString());
          model = getMissingModel();
        }

        if (v instanceof ISmartVariant) {
          model = ((ISmartVariant) v).process(model, ModelLoader.this);
          try {
            resolveDependencies(model);
          } catch (IOException e) {
            FMLLog.getLogger()
                .error("Exception resolving indirect dependencies for model" + loc, e);
          }
          textures.addAll(model.getTextures()); // Kick this, just in case.
        }

        models.add(model);
        builder.add(Pair.of(model, v.getState()));
      }

      if (models.size()
          == 0) // If all variants are missing, add one with the missing model and default rotation.
      {
        IModel missing = getMissingModel();
        models.add(missing);
        builder.add(Pair.<IModel, IModelState>of(missing, TRSRTransformation.identity()));
      }

      defaultState = new MultiModelState(builder.build());
    }
 @Override
 protected void registerVariant(ModelBlockDefinition definition, ModelResourceLocation location) {
   if (!loadingBlockModels.isEmpty() && loadingBlockModels.peekFirst() == location) {
     blockBar.step(location.toString());
     loadingBlockModels.removeFirst();
   }
   Variants variants = null;
   try {
     variants = definition.getVariants(location.getVariant());
   } catch (MissingVariantException e) {
     missingVariants.add(location);
   }
   if (variants != null && !variants.getVariants().isEmpty()) {
     try {
       stateModels.put(location, new WeightedRandomModel(location, variants));
     } catch (Throwable e) {
       throw new RuntimeException(e);
     }
   }
 }