// Path: core/src/main/java/org/wandledi/AbstractSpell.java
// public abstract class AbstractSpell implements Spell {
// 
//     protected Spell parent;
//     protected LinkedList<SpellLine> lines = new LinkedList<SpellLine>();
//     private boolean ignoreBounds = false;
// 
//     @Override
//     public abstract Spell clone();
// 
//     public boolean hierarchyContains(Spell spell) {
//         return this == spell || parent.hierarchyContains(spell);
//     }
// 
//     public Resources getResources() {
//         return parent.getResources();
//     }
// 
//     public Wandler getWandler() {
//         return parent.getWandler();
//     }
// 
//     protected void reset() {
//         clearLines();
//     }
// 
//     protected void pushLine(SpellLine line) {
//         lines.add(line);
//     }
// 
//     protected SpellLine popLine() {
//         return lines.removeLast();
//     }
// 
//     protected SpellLine pullLine() {
//         return lines.removeFirst();
//     }
// 
//     protected void clearLines() {
//         lines.clear();
//     }
// 
//     public void setParent(Spell parent) {
//         this.parent = parent;
//     }
// 
//     public Spell getParent() {
//         return this.parent;
//     }
// 
//     public void startTransformedElement(String name, Attributes attributes) {
//         if (Wandler.dlogLevel >= Wandler.DLOG_LEVEL_2) {
//             System.out.println("[info] Casting " + toString());
//         }
//         if (ignoreBounds()) {
//             startElement(name, attributes);
//         } else {
//             parent.startTransformedElement(name, attributes);
//         }
//     }
// 
//     public void endTransformedElement(String name) {
//         if (ignoreBounds()) {
//             endElement(name);
//         } else {
//             parent.endTransformedElement(name);
//         }
//     }
// 
//     public void startElement(String name, Attributes attributes) {
//         parent.startElement(name, attributes);
//     }
// 
//     public void endElement(String name) {
//         parent.endElement(name);
//     }
// 
//     public void writeCharacters(char[] characters, int offset, int length, boolean safe) {
//         parent.writeCharacters(characters, offset, length, safe);
//     }
// 
//     public void writeString(String string, boolean safe) {
//         char[] characters = string.toCharArray();
//         writeCharacters(characters, 0, characters.length, safe);
//     }
// 
//     public void ignoreBounds(boolean ignoreBounds) {
//         this.ignoreBounds = ignoreBounds;
//     }
// 
//     public boolean ignoreBounds() {
//         return ignoreBounds;
//     }
// }
// 
// Path: core/src/main/java/org/wandledi/Spell.java
// public interface Spell {
// 
//     public void setParent(Spell spell);
//     public Spell getParent();
//     public void startElement(String name, Attributes attributes);
//     public void endElement(String name);
// 
//     /**
//      * Write the given characters to the output.
//      *
//      * @param characters Character array from which to read.
//      * @param offset Start reading here.
//      * @param length Stop there.
//      * @param safe Is this data safe or does it have to be checked for invalid (reserved) characters (<, >, &, ...)?
//      */
//     public void writeCharacters(char[] characters, int offset, int length, boolean safe);
// 
//     /**This shall only be a convenience method that makes a call to #writeCharacters.
//      */
//     public void writeString(String string, boolean safe);
//     
//     public void startTransformedElement(String name, Attributes attributes);
//     public void endTransformedElement(String name);
// 
//     /**Each Spell must implement this method and above all mind it
//      * within its implementation of #startTransformedElement and
//      * #endTransformedElement, which mark the bounds of a transformation.
//      * 
//      * If this method is called with true as an argument,
//      * a Spell must not execute its actual implementation of
//      * the respective method, but instead the normal #startElement and
//      * #endElement respectively.
//      *
//      * Hence, a typical implementation of #startTransformedElement would like
//      * this:
//      * <pre>
//      * public void startTransformedElement(String name, Attributes attributes) {
//      *
//      *     if (ignoreBounds()) {
//      *         startElement(name, attributes);
//      *     } else {
//      *         // actual logic ...
//      *         super.startTransformedElement(possiblyTransformedName,
//      *                 possiblyTransformedAttributes);
//      *     }
//      * }
//      * </pre>
//      *
//      * This is highly uncomfortable, but I just don't know how to
//      * enforce this implicitly at the moment.
//      *
//      * @param ignoreBounds Flag indicating whether or not the bounds shall be ignored.
//      */
//     public void ignoreBounds(boolean ignoreBounds);
// 
//     /**Indicates whether or not this Spell ignores transformation bounds events.
//      *
//      * @return True if this Spell ignores transformation bounds.
//      */
//     public boolean ignoreBounds();
// 
//     public Spell clone();
// 
//     /**Checks whether the given spell is contained within this spell's hierarchy.
//      * For this each respective parent is compared.
//      *
//      * @param spell
//      * @return
//      */
//     public boolean hierarchyContains(Spell spell);
// 
//     /**Simply implement as parent.getResources().
//      *
//      * @return The parent's Resources.
//      */
//     public Resources getResources();
// 
//     /**
//      * Implement as parent.getWandler().
//      *
//      * @return The Wandler this Spell is used in.
//      */
//     public Wandler getWandler();
// }


import org.wandledi.AbstractSpell;
import org.wandledi.Spell;
import org.xml.sax.Attributes;
package org.wandledi.spells;


/**
 * Truncates a node, meaning that it drops outer nodes and only leaves the inner ones.
 * For instance if you truncate a list (ul) by 1 you will cut off the &lt;ul&gt; only
 * leaving the contained list items.
 *
 * @author Markus Kahl
 */
public class Truncate extends AbstractSpell{

    protected int depth;
    protected int level;

    public Truncate(int depth) {
        this.depth = depth;
        if (depth < 0) throw new IllegalArgumentException("Truncation depth must be at least 0");
    }

    protected Truncate() { }

// Path: core/src/main/java/org/wandledi/AbstractSpell.java
// public abstract class AbstractSpell implements Spell {
// 
//     protected Spell parent;
//     protected LinkedList<SpellLine> lines = new LinkedList<SpellLine>();
//     private boolean ignoreBounds = false;
// 
//     @Override
//     public abstract Spell clone();
// 
//     public boolean hierarchyContains(Spell spell) {
//         return this == spell || parent.hierarchyContains(spell);
//     }
// 
//     public Resources getResources() {
//         return parent.getResources();
//     }
// 
//     public Wandler getWandler() {
//         return parent.getWandler();
//     }
// 
//     protected void reset() {
//         clearLines();
//     }
// 
//     protected void pushLine(SpellLine line) {
//         lines.add(line);
//     }
// 
//     protected SpellLine popLine() {
//         return lines.removeLast();
//     }
// 
//     protected SpellLine pullLine() {
//         return lines.removeFirst();
//     }
// 
//     protected void clearLines() {
//         lines.clear();
//     }
// 
//     public void setParent(Spell parent) {
//         this.parent = parent;
//     }
// 
//     public Spell getParent() {
//         return this.parent;
//     }
// 
//     public void startTransformedElement(String name, Attributes attributes) {
//         if (Wandler.dlogLevel >= Wandler.DLOG_LEVEL_2) {
//             System.out.println("[info] Casting " + toString());
//         }
//         if (ignoreBounds()) {
//             startElement(name, attributes);
//         } else {
//             parent.startTransformedElement(name, attributes);
//         }
//     }
// 
//     public void endTransformedElement(String name) {
//         if (ignoreBounds()) {
//             endElement(name);
//         } else {
//             parent.endTransformedElement(name);
//         }
//     }
// 
//     public void startElement(String name, Attributes attributes) {
//         parent.startElement(name, attributes);
//     }
// 
//     public void endElement(String name) {
//         parent.endElement(name);
//     }
// 
//     public void writeCharacters(char[] characters, int offset, int length, boolean safe) {
//         parent.writeCharacters(characters, offset, length, safe);
//     }
// 
//     public void writeString(String string, boolean safe) {
//         char[] characters = string.toCharArray();
//         writeCharacters(characters, 0, characters.length, safe);
//     }
// 
//     public void ignoreBounds(boolean ignoreBounds) {
//         this.ignoreBounds = ignoreBounds;
//     }
// 
//     public boolean ignoreBounds() {
//         return ignoreBounds;
//     }
// }
// 
// Path: core/src/main/java/org/wandledi/Spell.java
// public interface Spell {
// 
//     public void setParent(Spell spell);
//     public Spell getParent();
//     public void startElement(String name, Attributes attributes);
//     public void endElement(String name);
// 
//     /**
//      * Write the given characters to the output.
//      *
//      * @param characters Character array from which to read.
//      * @param offset Start reading here.
//      * @param length Stop there.
//      * @param safe Is this data safe or does it have to be checked for invalid (reserved) characters (<, >, &, ...)?
//      */
//     public void writeCharacters(char[] characters, int offset, int length, boolean safe);
// 
//     /**This shall only be a convenience method that makes a call to #writeCharacters.
//      */
//     public void writeString(String string, boolean safe);
//     
//     public void startTransformedElement(String name, Attributes attributes);
//     public void endTransformedElement(String name);
// 
//     /**Each Spell must implement this method and above all mind it
//      * within its implementation of #startTransformedElement and
//      * #endTransformedElement, which mark the bounds of a transformation.
//      * 
//      * If this method is called with true as an argument,
//      * a Spell must not execute its actual implementation of
//      * the respective method, but instead the normal #startElement and
//      * #endElement respectively.
//      *
//      * Hence, a typical implementation of #startTransformedElement would like
//      * this:
//      * <pre>
//      * public void startTransformedElement(String name, Attributes attributes) {
//      *
//      *     if (ignoreBounds()) {
//      *         startElement(name, attributes);
//      *     } else {
//      *         // actual logic ...
//      *         super.startTransformedElement(possiblyTransformedName,
//      *                 possiblyTransformedAttributes);
//      *     }
//      * }
//      * </pre>
//      *
//      * This is highly uncomfortable, but I just don't know how to
//      * enforce this implicitly at the moment.
//      *
//      * @param ignoreBounds Flag indicating whether or not the bounds shall be ignored.
//      */
//     public void ignoreBounds(boolean ignoreBounds);
// 
//     /**Indicates whether or not this Spell ignores transformation bounds events.
//      *
//      * @return True if this Spell ignores transformation bounds.
//      */
//     public boolean ignoreBounds();
// 
//     public Spell clone();
// 
//     /**Checks whether the given spell is contained within this spell's hierarchy.
//      * For this each respective parent is compared.
//      *
//      * @param spell
//      * @return
//      */
//     public boolean hierarchyContains(Spell spell);
// 
//     /**Simply implement as parent.getResources().
//      *
//      * @return The parent's Resources.
//      */
//     public Resources getResources();
// 
//     /**
//      * Implement as parent.getWandler().
//      *
//      * @return The Wandler this Spell is used in.
//      */
//     public Wandler getWandler();
// }


// Path: core/src/main/java/org/wandledi/spells/Truncate.java
import org.wandledi.AbstractSpell;
import org.wandledi.Spell;
import org.xml.sax.Attributes;

package org.wandledi.spells;


/**
 * Truncates a node, meaning that it drops outer nodes and only leaves the inner ones.
 * For instance if you truncate a list (ul) by 1 you will cut off the &lt;ul&gt; only
 * leaving the contained list items.
 *
 * @author Markus Kahl
 */
public class Truncate extends AbstractSpell{

    protected int depth;
    protected int level;

    public Truncate(int depth) {
        this.depth = depth;
        if (depth < 0) throw new IllegalArgumentException("Truncation depth must be at least 0");
    }

    protected Truncate() { }

    @Override