@Override
  public AbstractArrayDefinition createDefinition(
      @Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input)
      throws CTFException {
    IDefinition lenDef = null;

    if (definitionScope != null) {
      lenDef = definitionScope.lookupDefinition(getLengthName());
    }

    if (lenDef == null) {
      throw new CTFException("Sequence length field not found"); // $NON-NLS-1$
    }

    if (!(lenDef instanceof IntegerDefinition)) {
      throw new CTFException("Sequence length field not integer"); // $NON-NLS-1$
    }

    IntegerDefinition lengthDefinition = (IntegerDefinition) lenDef;

    if (lengthDefinition.getDeclaration().isSigned()) {
      throw new CTFException("Sequence length must not be signed"); // $NON-NLS-1$
    }

    long length = lengthDefinition.getValue();
    if ((length > Integer.MAX_VALUE)
        || (!input.canRead((int) length * fElemType.getMaximumSize()))) {
      throw new CTFException("Sequence length too long " + length); // $NON-NLS-1$
    }

    if (isAlignedBytes()) {
      // Don't create "useless" definitions
      byte[] data = new byte[(int) length];
      input.get(data);
      return new ByteArrayDefinition(this, definitionScope, fieldName, data);
    }
    Collection<String> collection = fPaths.get(fieldName);
    while (collection.size() < length) {
      fPaths.put(fieldName, fieldName + '[' + collection.size() + ']');
    }
    List<String> paths = (List<String>) fPaths.get(fieldName);
    Builder<Definition> definitions = new ImmutableList.Builder<>();
    for (int i = 0; i < length; i++) {
      /* We should not have inserted any null values */
      String elemName = checkNotNull(paths.get(i));
      definitions.add(fElemType.createDefinition(definitionScope, elemName, input));
    }
    List<Definition> list = checkNotNull(definitions.build());
    return new ArrayDefinition(this, definitionScope, fieldName, list);
  }