/*++

Copyright (C) 2024 3MF Consortium (Original Author)

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This file has been generated by the Automatic Component Toolkit (ACT) version 1.8.1-develop.

Abstract: This is an autogenerated Java file in order to allow an easy
 use of the 3MF Library

Interface version: 2.5.0

*/

package lib3mf;

import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;


import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

public class ImplicitFunction extends Function {

	public ImplicitFunction(Lib3MFWrapper wrapper, Pointer handle) {
		super(wrapper, handle);
	}

	/**
	 * Retrieves the identifier of the function
	 *
	 * @return the identifier
	 * @throws Lib3MFException
	 */
	public String getIdentifier() throws Lib3MFException {
		Pointer bytesNeededIdentifier = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_getidentifier.invokeInt(new java.lang.Object[]{mHandle, 0, bytesNeededIdentifier, null}));
		int sizeIdentifier = bytesNeededIdentifier.getInt(0);
		Pointer bufferIdentifier = new Memory(sizeIdentifier);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_getidentifier.invokeInt(new java.lang.Object[]{mHandle, sizeIdentifier, bytesNeededIdentifier, bufferIdentifier}));
		return new String(bufferIdentifier.getByteArray(0, sizeIdentifier - 1), StandardCharsets.UTF_8);
	}

	/**
	 * Sets the identifier of the function
	 *
	 * @param identifier the identifier
	 * @throws Lib3MFException
	 */
	public void setIdentifier(String identifier) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_setidentifier.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier}));
	}

	/**
	 * Add a node
	 *
	 * @param nodeType the type of the node
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ImplicitNode addNode(Lib3MFWrapper.ImplicitNodeType nodeType, String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addnode.invokeInt(new java.lang.Object[]{mHandle, Lib3MFWrapper.EnumConversion.convertImplicitNodeTypeToConst(nodeType), bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ImplicitNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ImplicitNode.class);
		return node;
	}

	/**
	 * Add a SinNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public SinNode addSinNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addsinnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		SinNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, SinNode.class);
		return node;
	}

	/**
	 * Add a CosNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public CosNode addCosNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addcosnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		CosNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, CosNode.class);
		return node;
	}

	/**
	 * Add a TanNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public TanNode addTanNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addtannode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		TanNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, TanNode.class);
		return node;
	}

	/**
	 * Add a ArcSinNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ArcSinNode addArcSinNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addarcsinnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ArcSinNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ArcSinNode.class);
		return node;
	}

	/**
	 * Add a ArcCosNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ArcCosNode addArcCosNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addarccosnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ArcCosNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ArcCosNode.class);
		return node;
	}

	/**
	 * Add a ArcTan2Node
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ArcTan2Node addArcTan2Node(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addarctan2node.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ArcTan2Node node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ArcTan2Node.class);
		return node;
	}

	/**
	 * Add a SinhNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public SinhNode addSinhNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addsinhnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		SinhNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, SinhNode.class);
		return node;
	}

	/**
	 * Add a CoshNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public CoshNode addCoshNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addcoshnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		CoshNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, CoshNode.class);
		return node;
	}

	/**
	 * Add a TanhNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public TanhNode addTanhNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addtanhnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		TanhNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, TanhNode.class);
		return node;
	}

	/**
	 * Add a RoundNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public RoundNode addRoundNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addroundnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		RoundNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, RoundNode.class);
		return node;
	}

	/**
	 * Add a CeilNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public CeilNode addCeilNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addceilnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		CeilNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, CeilNode.class);
		return node;
	}

	/**
	 * Add a FloorNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public FloorNode addFloorNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addfloornode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		FloorNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, FloorNode.class);
		return node;
	}

	/**
	 * Add a SignNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public SignNode addSignNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addsignnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		SignNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, SignNode.class);
		return node;
	}

	/**
	 * Add a FractNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public FractNode addFractNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addfractnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		FractNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, FractNode.class);
		return node;
	}

	/**
	 * Add a AbsNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public AbsNode addAbsNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addabsnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		AbsNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, AbsNode.class);
		return node;
	}

	/**
	 * Add a ExpNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ExpNode addExpNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addexpnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ExpNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ExpNode.class);
		return node;
	}

	/**
	 * Add a LogNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public LogNode addLogNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addlognode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		LogNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, LogNode.class);
		return node;
	}

	/**
	 * Add a Log2Node
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public Log2Node addLog2Node(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addlog2node.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		Log2Node node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, Log2Node.class);
		return node;
	}

	/**
	 * Add a Log10Node
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public Log10Node addLog10Node(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addlog10node.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		Log10Node node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, Log10Node.class);
		return node;
	}

	/**
	 * Add a LengthNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public LengthNode addLengthNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addlengthnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		LengthNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, LengthNode.class);
		return node;
	}

	/**
	 * Add a TransposeNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public TransposeNode addTransposeNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addtransposenode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		TransposeNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, TransposeNode.class);
		return node;
	}

	/**
	 * Add a InverseNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public InverseNode addInverseNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addinversenode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		InverseNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, InverseNode.class);
		return node;
	}

	/**
	 * Add a SqrtNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public SqrtNode addSqrtNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addsqrtnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		SqrtNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, SqrtNode.class);
		return node;
	}

	/**
	 * Add a ResourceIdNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ResourceIdNode addResourceIdNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addresourceidnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ResourceIdNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ResourceIdNode.class);
		return node;
	}

	/**
	 * Add an AdditionNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public AdditionNode addAdditionNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addadditionnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		AdditionNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, AdditionNode.class);
		return node;
	}

	/**
	 * Add a SubtractionNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public SubtractionNode addSubtractionNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addsubtractionnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		SubtractionNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, SubtractionNode.class);
		return node;
	}

	/**
	 * Add a MultiplicationNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public MultiplicationNode addMultiplicationNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addmultiplicationnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		MultiplicationNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, MultiplicationNode.class);
		return node;
	}

	/**
	 * Add a DivisionNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public DivisionNode addDivisionNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_adddivisionnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		DivisionNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, DivisionNode.class);
		return node;
	}

	/**
	 * Add a DotNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public DotNode addDotNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_adddotnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		DotNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, DotNode.class);
		return node;
	}

	/**
	 * Add a CrossNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public CrossNode addCrossNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addcrossnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		CrossNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, CrossNode.class);
		return node;
	}

	/**
	 * Add a MatVecMultiplicationNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public MatVecMultiplicationNode addMatVecMultiplicationNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addmatvecmultiplicationnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		MatVecMultiplicationNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, MatVecMultiplicationNode.class);
		return node;
	}

	/**
	 * Add a MinNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public MinNode addMinNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addminnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		MinNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, MinNode.class);
		return node;
	}

	/**
	 * Add a MaxNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public MaxNode addMaxNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addmaxnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		MaxNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, MaxNode.class);
		return node;
	}

	/**
	 * Add a FmodNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public FmodNode addFmodNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addfmodnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		FmodNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, FmodNode.class);
		return node;
	}

	/**
	 * Add a PowNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public PowNode addPowNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addpownode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		PowNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, PowNode.class);
		return node;
	}

	/**
	 * Add a SelectNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public SelectNode addSelectNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addselectnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		SelectNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, SelectNode.class);
		return node;
	}

	/**
	 * Add a ClampNode
	 *
	 * @param identifier the identifier of the node
	 * @param configuration the configuration of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ClampNode addClampNode(String identifier, Lib3MFWrapper.ImplicitNodeConfiguration configuration, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addclampnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, Lib3MFWrapper.EnumConversion.convertImplicitNodeConfigurationToConst(configuration), bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ClampNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ClampNode.class);
		return node;
	}

	/**
	 * Add a ComposeVectorNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ComposeVectorNode addComposeVectorNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addcomposevectornode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ComposeVectorNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ComposeVectorNode.class);
		return node;
	}

	/**
	 * Add a VectorFromScalar
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public VectorFromScalarNode addVectorFromScalarNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addvectorfromscalarnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		VectorFromScalarNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, VectorFromScalarNode.class);
		return node;
	}

	/**
	 * Add a DecomposeVectorNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public DecomposeVectorNode addDecomposeVectorNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_adddecomposevectornode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		DecomposeVectorNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, DecomposeVectorNode.class);
		return node;
	}

	/**
	 * Add a ComposeMatrixNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ComposeMatrixNode addComposeMatrixNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addcomposematrixnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ComposeMatrixNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ComposeMatrixNode.class);
		return node;
	}

	/**
	 * Add a MatrixFromRowsNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public MatrixFromRowsNode addMatrixFromRowsNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addmatrixfromrowsnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		MatrixFromRowsNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, MatrixFromRowsNode.class);
		return node;
	}

	/**
	 * Add a MatrixFromColumnsNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public MatrixFromColumnsNode addMatrixFromColumnsNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addmatrixfromcolumnsnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		MatrixFromColumnsNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, MatrixFromColumnsNode.class);
		return node;
	}

	/**
	 * Add a ConstantNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ConstantNode addConstantNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addconstantnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ConstantNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ConstantNode.class);
		return node;
	}

	/**
	 * Add a ConstVecNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ConstVecNode addConstVecNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addconstvecnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ConstVecNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ConstVecNode.class);
		return node;
	}

	/**
	 * Add a ConstMatNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public ConstMatNode addConstMatNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addconstmatnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		ConstMatNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, ConstMatNode.class);
		return node;
	}

	/**
	 * Add a MeshNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public MeshNode addMeshNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addmeshnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		MeshNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, MeshNode.class);
		return node;
	}

	/**
	 * Add a UnsignedMeshNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public UnsignedMeshNode addUnsignedMeshNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addunsignedmeshnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		UnsignedMeshNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, UnsignedMeshNode.class);
		return node;
	}

	/**
	 * Add a BeamLatticeNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public BeamLatticeNode addBeamLatticeNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addbeamlatticenode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		BeamLatticeNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, BeamLatticeNode.class);
		return node;
	}

	/**
	 * Add a FunctionGradientNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public FunctionGradientNode addFunctionGradientNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addfunctiongradientnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		FunctionGradientNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, FunctionGradientNode.class);
		return node;
	}

	/**
	 * Add a NormalizeDistanceNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public NormalizeDistanceNode addNormalizeDistanceNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addnormalizedistancenode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		NormalizeDistanceNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, NormalizeDistanceNode.class);
		return node;
	}

	/**
	 * Add a FunctionCallNode
	 *
	 * @param identifier the identifier of the node
	 * @param displayName the display name of the node
	 * @param tag the tag of the node
	 * @return the added node
	 * @throws Lib3MFException
	 */
	public FunctionCallNode addFunctionCallNode(String identifier, String displayName, String tag) throws Lib3MFException {
		byte[] bytesIdentifier = identifier.getBytes(StandardCharsets.UTF_8);
		Memory bufferIdentifier = new Memory(bytesIdentifier.length + 1);
		bufferIdentifier.write(0, bytesIdentifier, 0, bytesIdentifier.length);
		bufferIdentifier.setByte(bytesIdentifier.length, (byte)0);
		byte[] bytesDisplayName = displayName.getBytes(StandardCharsets.UTF_8);
		Memory bufferDisplayName = new Memory(bytesDisplayName.length + 1);
		bufferDisplayName.write(0, bytesDisplayName, 0, bytesDisplayName.length);
		bufferDisplayName.setByte(bytesDisplayName.length, (byte)0);
		byte[] bytesTag = tag.getBytes(StandardCharsets.UTF_8);
		Memory bufferTag = new Memory(bytesTag.length + 1);
		bufferTag.write(0, bytesTag, 0, bytesTag.length);
		bufferTag.setByte(bytesTag.length, (byte)0);
		Pointer bufferNode = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addfunctioncallnode.invokeInt(new java.lang.Object[]{mHandle, bufferIdentifier, bufferDisplayName, bufferTag, bufferNode}));
		Pointer valueNode = bufferNode.getPointer(0);
		FunctionCallNode node = null;
		if (valueNode == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node was a null pointer");
		}
		node = mWrapper.PolymorphicFactory(valueNode, FunctionCallNode.class);
		return node;
	}

	/**
	 * Retrieves the nodes
	 *
	 * @return iterator for the list of nodes
	 * @throws Lib3MFException
	 */
	public NodeIterator getNodes() throws Lib3MFException {
		Pointer bufferIterator = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_getnodes.invokeInt(new java.lang.Object[]{mHandle, bufferIterator}));
		Pointer valueIterator = bufferIterator.getPointer(0);
		NodeIterator iterator = null;
		if (valueIterator == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Iterator was a null pointer");
		}
		iterator = mWrapper.PolymorphicFactory(valueIterator, NodeIterator.class);
		return iterator;
	}

	/**
	 * Removes a node
	 *
	 * @param node The node to be removed
	 * @throws Lib3MFException
	 */
	public void removeNode(ImplicitNode node) throws Lib3MFException {
		Pointer nodeHandle = null;
		if (node != null) {
			nodeHandle = node.getHandle();
		} else {
			throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Node is a null value.");
		}
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_removenode.invokeInt(new java.lang.Object[]{mHandle, nodeHandle}));
	}

	/**
	 * Add a link
	 *
	 * @param source the source port
	 * @param target the target port
	 * @throws Lib3MFException
	 */
	public void addLink(ImplicitPort source, ImplicitPort target) throws Lib3MFException {
		Pointer sourceHandle = null;
		if (source != null) {
			sourceHandle = source.getHandle();
		} else {
			throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Source is a null value.");
		}
		Pointer targetHandle = null;
		if (target != null) {
			targetHandle = target.getHandle();
		} else {
			throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "Target is a null value.");
		}
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addlink.invokeInt(new java.lang.Object[]{mHandle, sourceHandle, targetHandle}));
	}

	/**
	 * Add a link
	 *
	 * @param source name of the source port in the format nodename.portname
	 * @param target name of the target port in the format nodename.portname
	 * @throws Lib3MFException
	 */
	public void addLinkByNames(String source, String target) throws Lib3MFException {
		byte[] bytesSource = source.getBytes(StandardCharsets.UTF_8);
		Memory bufferSource = new Memory(bytesSource.length + 1);
		bufferSource.write(0, bytesSource, 0, bytesSource.length);
		bufferSource.setByte(bytesSource.length, (byte)0);
		byte[] bytesTarget = target.getBytes(StandardCharsets.UTF_8);
		Memory bufferTarget = new Memory(bytesTarget.length + 1);
		bufferTarget.write(0, bytesTarget, 0, bytesTarget.length);
		bufferTarget.setByte(bytesTarget.length, (byte)0);
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_addlinkbynames.invokeInt(new java.lang.Object[]{mHandle, bufferSource, bufferTarget}));
	}

	/**
	 * Clears the function
	 *
	 * @throws Lib3MFException
	 */
	public void clear() throws Lib3MFException {
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_clear.invokeInt(new java.lang.Object[]{mHandle}));
	}

	/**
	 * Sorts the nodes topologically
	 *
	 * @throws Lib3MFException
	 */
	public void sortNodesTopologically() throws Lib3MFException {
		mWrapper.checkError(this, mWrapper.lib3mf_implicitfunction_sortnodestopologically.invokeInt(new java.lang.Object[]{mHandle}));
	}


}

