void processParameterPerAnnot(AnnotatedPcodeUseropDefinition<?> opdef, Type declClsOpType,
				int i, Parameter p) {
			if (getPos(opdef) != -1) {
				throw new IllegalArgumentException(
					"Can only have one parameter with @" + annotCls.getSimpleName());
			}
			Type pType = p.getParameterizedType();
			Map<TypeVariable<?>, Type> typeArgs = TypeUtils.getTypeArguments(pType, paramCls);
			if (typeArgs == null) {
				throw new IllegalArgumentException("Parameter " + p.getName() + " with @" +
					annotCls.getSimpleName() + " must acccept " + getArgumentType(declClsOpType));
			}
			if (typeArgs.isEmpty()) {
				// Nothing
			}
			else if (typeArgs.size() == 1) {
				Type declMthOpType = typeArgs.get(paramCls.getTypeParameters()[0]);
				if (!Objects.equals(declClsOpType, declMthOpType)) {
					throw new IllegalArgumentException("Parameter " + p.getName() + " with @" +
						annotCls.getSimpleName() + " must acccept " +
						getArgumentType(declClsOpType));
				}
			}
			else {
				throw new AssertionError("Internal: paramCls for @" + annotCls.getSimpleName() +
					"should only have one type parameter <T>");
			}
			setPos(opdef, i);
		}
A userop library wherein Java methods are exported via a special annotation

<p>
See {@code StandAloneEmuExampleScript} for an example of implementing a userop library.

@param <T> the type of data processed by the library
Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/AnnotatedPcodeUseropLibrary.java