class DeriveExtendedPublicKey extends NativeMethod {

    @Override
    public Object execute(Object[] arguments) {
        if (arguments == null) {
            throw new NativeContractIllegalArgumentException("Must provide xpub and path arguments. None was provided");
        }
        String xpub = (String) arguments[0];
        String path = (String) arguments[1];

        NetworkParameters params = helper.validateAndExtractNetworkFromExtendedPublicKey(xpub);
        DeterministicKey key;
        try {
            key = DeterministicKey.deserializeB58(xpub, params);
        } catch (IllegalArgumentException e) {
            throw new NativeContractIllegalArgumentException("Invalid extended public key", e);
        }

        // Path must be of the form S, with S ::= n || n/S with n an unsigned integer

        // Covering special case: upon splitting a string, if the string ends with the delimiter, then
        // there is no empty string as a last element. Make sure that the whole path starts and ends with a digit
        // just in case.
        if (path == null || path.length() == 0 || !isDecimal(path.substring(0,1)) || !isDecimal(path.substring(path.length()-1, path.length()))) {
            throwInvalidPath(path);
        }

        String[] pathChunks = path.split("/");

        if (pathChunks.length > 10) {
            throw new NativeContractIllegalArgumentException("Path should contain 10 levels at most");
        }

        if (Arrays.stream(pathChunks).anyMatch(s -> !isDecimal(s))) {
            throwInvalidPath(path);
        }

        List<ChildNumber> pathList;
        try {
            pathList = HDUtils.parsePath(path);
        } catch (NumberFormatException ex) {
            throw new NativeContractIllegalArgumentException(getInvalidPathErrorMessage(path), ex);
        }

        DeterministicKey derived = key;
        for (ChildNumber pathItem : pathList) {
            derived = HDKeyDerivation.deriveChildKey(derived, pathItem.getI());
        }

        return derived.serializePubB58(params);
    }

    public  DeriveExtendedPublicKey(ExecutionEnvironment executionEnvironment, HDWalletUtilsHelper helper);

}