@Override
 public BlockFamily getBlockFamily(BlockUri uri) {
   BlockFamily family = registeredBlockInfo.get().registeredFamilyByUri.get(uri);
   if (family == null && generateNewIds) {
     if (isFreeformFamily(uri.getRootFamilyUri())) {
       family = blockLoader.loadWithShape(uri);
     } else {
       family = getAvailableBlockFamily(uri);
     }
     if (family != null) {
       lock.lock();
       try {
         for (Block block : family.getBlocks()) {
           block.setId(getNextId());
         }
         registerFamily(family);
       } finally {
         lock.unlock();
       }
     } else {
       logger.warn("Unable to resolve block family {}", uri);
     }
   }
   return family;
 }
  public BlockManagerImpl(
      WorldAtlas atlas,
      List<String> registeredBlockFamilies,
      Map<String, Short> knownBlockMappings,
      boolean generateNewIds,
      BlockFamilyFactoryRegistry blockFamilyFactoryRegistry) {
    this.generateNewIds = generateNewIds;
    this.moduleManager = CoreRegistry.get(ModuleManager.class);
    blockLoader =
        new BlockLoader(CoreRegistry.get(AssetManager.class), blockFamilyFactoryRegistry, atlas);
    BlockLoader.LoadBlockDefinitionResults blockDefinitions = blockLoader.loadBlockDefinitions();
    addBlockFamily(getAirFamily(), true);
    for (BlockFamily family : blockDefinitions.families) {
      addBlockFamily(family, false);
    }
    for (FreeformFamily freeformFamily : blockDefinitions.shapelessDefinitions) {
      addFreeformBlockFamily(freeformFamily.uri, freeformFamily.categories);
    }
    if (knownBlockMappings.size() >= MAX_ID) {
      nextId = UNKNOWN_ID;
    } else if (knownBlockMappings.size() > 0) {
      nextId = (short) knownBlockMappings.size();
    }

    for (String rawFamilyUri : registeredBlockFamilies) {
      BlockUri familyUri = new BlockUri(rawFamilyUri);
      BlockFamily family;
      if (isFreeformFamily(familyUri)) {
        family = blockLoader.loadWithShape(familyUri);
      } else {
        family = getAvailableBlockFamily(familyUri);
      }
      if (family != null) {
        for (Block block : family.getBlocks()) {
          Short id = knownBlockMappings.get(block.getURI().toString());
          if (id != null) {
            block.setId(id);
          } else {
            logger.error(
                "Missing id for block {} in provided family {}", block.getURI(), family.getURI());
            if (generateNewIds) {
              block.setId(getNextId());
            } else {
              block.setId(UNKNOWN_ID);
            }
          }
        }
        registerFamily(family);
      } else {
        logger.error("Family not available: {}", rawFamilyUri);
      }
    }
  }
 @VisibleForTesting
 protected void registerFamily(BlockFamily family) {
   logger.info("Registered {}", family);
   lock.lock();
   try {
     RegisteredState newState = new RegisteredState(registeredBlockInfo.get());
     newState.registeredFamilyByUri.put(family.getURI(), family);
     for (Block block : family.getBlocks()) {
       registerBlock(block, newState);
     }
     registeredBlockInfo.set(newState);
   } finally {
     lock.unlock();
   }
   for (BlockRegistrationListener listener : listeners) {
     listener.onBlockFamilyRegistered(family);
   }
 }
 public void receiveFamilyRegistration(BlockUri familyUri, Map<String, Integer> registration) {
   BlockFamily family;
   if (isFreeformFamily(familyUri)) {
     family = blockLoader.loadWithShape(familyUri);
   } else {
     family = getAvailableBlockFamily(familyUri);
   }
   if (family != null) {
     for (Block block : family.getBlocks()) {
       Integer id = registration.get(block.getURI().toString());
       if (id != null) {
         block.setId((short) id.intValue());
       } else {
         logger.error(
             "Missing id for block {} in registered family {}", block.getURI(), familyUri);
         block.setId(UNKNOWN_ID);
       }
       registerFamily(family);
     }
   } else {
     logger.error("Block family not available: {}", familyUri);
   }
 }