public AbstractProductIon(PrecursorIon precursorIon, ProductIonType type, int position, Peptide peptide, int charge) {
        //based on DefaultPeptideIon create ProductIon.
        super(peptide, charge);

        if (precursorIon == null) {
            throw new NullPointerException("Precursor ion can not set null!");
        }

        if (type == null) {
            throw new NullPointerException("Product ion type can not set null!");
        }

        // absolute the charges of precursor ion and product ion.
        int precursorZ = precursorIon.getCharge() > 0 ? precursorIon.getCharge() : precursorIon.getCharge() * -1;
        int productZ = charge > 0 ? charge : charge * -1;

        if (precursorZ <= 0) {
            throw new IllegalArgumentException("precursor ion charge should not less than zero! " + precursorIon);
        }

        if (productZ > 3) {
            throw new IllegalArgumentException("product ion change (" + productZ + ") should not great than 3!");
        }

        if (productZ > precursorZ) {
            throw new IllegalArgumentException("product ion change (" + productZ + ") should not great than precursor ion (" + precursorZ + ")");
        }


        this.precursorIon = precursorIon;
        this.type = type;
        this.position = position;
    }