public Gate newInstance() throws InstantiationException {
        BuiltInGate result;

        Node[] inputNodes = new Node[inputPinsInfo.length];
        Node[] outputNodes = new Node[outputPinsInfo.length];

        for (int i = 0; i < inputNodes.length; i++)
            inputNodes[i] = new Node();

        for (int i = 0; i < outputNodes.length; i++)
            outputNodes[i] = new Node();

        try {
            result = (BuiltInGate)javaGateClass.newInstance();
        } catch (IllegalAccessException iae) {
            throw new InstantiationException(iae.getMessage());
        }

        result.init(inputNodes, outputNodes, this);

        // if the gate has a gui component, add the gate to the gate manager
        // and set it to be its own parent for eval notifications
        if (result instanceof BuiltInGateWithGUI)
            GatesManager.getInstance().addChip((BuiltInGateWithGUI)result);

        // Add a DirtyGateAdapter as a listener to all the non-clocked inputs,
        // so the gate will become dirty when one of its non-clocked input changes.
        Node adapter = new DirtyGateAdapter(result);
        for (int i = 0; i < isInputClocked.length; i++)
            if (!isInputClocked[i])
                inputNodes[i].addListener(adapter);

        return result;
    }