Repository: decorators-squad/eo-yaml (java)

Issue:
Introduce Skip YamlLines
At the moment, there are a number of ``YamlLines`` implementations which are skipping over certain lines (start/end markers, comments etc).

Their implementations are more or less identical, so let's try to put everything into a generic ``Skip`` implementation that takes the lines to be skipped as argument.

Pull request:
Implemented Skip YamlLines
fixes #273 
This Skip aggregates all the conditions for which a given yaml line should be skipped from iteration. It is a big performance improvement since we reduce the number of line iterations quite a lot.

Patch:
diff --git a/src/main/java/com/amihaiemil/eoyaml/EvenlyIndentedLine.java b/src/main/java/com/amihaiemil/eoyaml/EvenlyIndentedLine.java
deleted file mode 100644
index fd02605..0000000
--- a/src/main/java/com/amihaiemil/eoyaml/EvenlyIndentedLine.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (c) 2016-2020, Mihai Emil Andronache
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- *  list of conditions and the following disclaimer.
- *  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.
- * Neither the name of the copyright holder nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- * 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.
- */
-package com.amihaiemil.eoyaml;
-
-/**
- * Any Yaml line should have an even indentation (multiple of 2).
- * @deprecated Usage of this class has been removed since the assumption
- *  that any YAML line should have an even indentation is incorrect. It
- *  will probably be removed later.
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 1.0.0
- *
- */
-@Deprecated
-final class EvenlyIndentedLine implements YamlLine {
-
-    /**
-     * Original line.
-     */
-    private YamlLine line;
-
-    /**
-     * Ctor.
-     * @param line Original YamlLine
-     */
-    EvenlyIndentedLine(final YamlLine line) {
-        this.line = line;
-    }
-
-    @Override
-    public String trimmed() {
-        return this.line.trimmed();
-    }
-
-    @Override
-    public int number() {
-        return this.line.number();
-    }
-
-    @Override
-    public int indentation() {
-        final int indentation = this.line.indentation();
-        if (indentation % 2 != 0) {
-            throw new IllegalStateException(
-                "Indentation of line " + this.line.number() + " is incorrect. "
-                + "It is " + indentation + " and it should be a multiple of 2!"
-            );
-        }
-        return indentation;
-    }
-
-    @Override
-    public String toString() {
-        return this.line.toString();
-    }
-
-    @Override
-    public int compareTo(final YamlLine other) {
-        return this.line.compareTo(other);
-    }
-
-    @Override
-    public boolean requireNestedIndentation() {
-        return this.line.requireNestedIndentation();
-    }
-}
diff --git a/src/main/java/com/amihaiemil/eoyaml/NoDirectives.java b/src/main/java/com/amihaiemil/eoyaml/NoDirectives.java
deleted file mode 100644
index def2e31..0000000
--- a/src/main/java/com/amihaiemil/eoyaml/NoDirectives.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Copyright (c) 2016-2020, Mihai Emil Andronache
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- *  list of conditions and the following disclaimer.
- *  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.
- * Neither the name of the copyright holder nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- * 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.
- */
-package com.amihaiemil.eoyaml;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * No directives. Decorates some YamlLines
- * and ignores YAML directives from the iteration.
- * This class can be used as follows:
- * <pre>
- *  YamlLines noDirs = new NoDirectives(
- *      new AllYamlLines(lines)
- * );//Ignores YAML Directives from iteration.
- * </pre>
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 3.1.4
- */
-final class NoDirectives implements YamlLines {
-    /**
-     * YamlLines.
-     */
-    private final YamlLines yamlLines;
-
-    /**
-     * Ctor.
-     * @param yamlLines The Yaml lines.
-     */
-    NoDirectives(final YamlLines yamlLines) {
-        this.yamlLines = yamlLines;
-    }
-
-    /**
-     * Returns an iterator over these Yaml lines.
-     * It ignores the lines containing YAML Directives.
-     * @return Iterator over these yaml lines.
-     */
-    @Override
-    public Iterator<YamlLine> iterator() {
-        Iterator<YamlLine> iterator = this.yamlLines.iterator();
-        if (iterator.hasNext()) {
-            final List<YamlLine> noDirectives = new ArrayList<>();
-            while (iterator.hasNext()) {
-                final YamlLine current = iterator.next();
-                final String currentLine = current.trimmed();
-                if (currentLine.startsWith("%")) {
-                    continue;
-                } else {
-                    noDirectives.add(current);
-                }
-            }
-            iterator = noDirectives.iterator();
-        }
-        return iterator;
-    }
-
-    @Override
-    public Collection<YamlLine> lines() {
-        return this.yamlLines.lines();
-    }
-
-    @Override
-    public AllYamlLines nested(final int after) {
-        return this.yamlLines.nested(after);
-    }
-
-    @Override
-    public YamlNode toYamlNode(final YamlLine prev) {
-        return this.yamlLines.toYamlNode(prev);
-    }
-}
diff --git a/src/main/java/com/amihaiemil/eoyaml/NoScalarMarkers.java b/src/main/java/com/amihaiemil/eoyaml/NoScalarMarkers.java
deleted file mode 100644
index 911e066..0000000
--- a/src/main/java/com/amihaiemil/eoyaml/NoScalarMarkers.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Copyright (c) 2016-2020, Mihai Emil Andronache
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- *  list of conditions and the following disclaimer.
- *  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.
- * Neither the name of the copyright holder nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- * 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.
- */
-package com.amihaiemil.eoyaml;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * When reading a single Scalar, the first of the given lines
- * dictates the type of the scalar: '>' is folded, '|' is literal etc.
- *
- * The lines will be passed altogether to the read scalar, so we have
- * to ignore these markers as they are not part of the scalar itself.
- * This class can be used as follows:
- * <pre>
- *   YamlLines noScalarMarkers = new NoScalarMarkers(
- *     new AllYamlLines(lines)
- *   );
- * </pre>
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 4.0.0
- */
-final class NoScalarMarkers implements YamlLines {
-
-    /**
-     * YamlLines.
-     */
-    private final YamlLines yamlLines;
-
-    /**
-     * Ctor.
-     * @param yamlLines The Yaml lines.
-     */
-    NoScalarMarkers(final YamlLines yamlLines) {
-        this.yamlLines = yamlLines;
-    }
-
-    /**
-     * Returns an iterator over these Yaml lines.
-     * It ignores the Scalar start markers ('>', '|' etc).
-     * @return Iterator over these yaml lines.
-     */
-    @Override
-    public Iterator<YamlLine> iterator() {
-        Iterator<YamlLine> iterator = this.yamlLines.iterator();
-        if (iterator.hasNext()) {
-            final List<YamlLine> noScalarMarkers = new ArrayList<>();
-            while (iterator.hasNext()) {
-                final YamlLine current = iterator.next();
-                final String line = current.trimmed();
-                if (line.endsWith(">") || line.endsWith("|")) {
-                    continue;
-                } else {
-                    noScalarMarkers.add(current);
-                }
-            }
-            iterator = noScalarMarkers.iterator();
-        }
-        return iterator;
-    }
-
-    @Override
-    public Collection<YamlLine> lines() {
-        return this.yamlLines.lines();
-    }
-
-    @Override
-    public AllYamlLines nested(final int after) {
-        return this.yamlLines.nested(after);
-    }
-
-    @Override
-    public YamlNode toYamlNode(final YamlLine prev) {
-        return this.yamlLines.toYamlNode(prev);
-    }
-}
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadFoldedBlockScalar.java b/src/main/java/com/amihaiemil/eoyaml/ReadFoldedBlockScalar.java
index 9335820..514f435 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadFoldedBlockScalar.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadFoldedBlockScalar.java
@@ -54,10 +54,14 @@ final class ReadFoldedBlockScalar extends BaseScalar {
      * @param lines Given lines to represent.
      */
     ReadFoldedBlockScalar(final YamlLines lines) {
-        this.lines = new NoScalarMarkers(
-            new NoDirectivesOrMarkers(
-                lines
-            )
+        this.lines = new Skip(
+            lines,
+            line -> line.trimmed().endsWith(">"),
+            line -> line.trimmed().endsWith("|"),
+            line -> line.trimmed().startsWith("---"),
+            line -> line.trimmed().startsWith("..."),
+            line -> line.trimmed().startsWith("%"),
+            line -> line.trimmed().startsWith("!!")
         );
     }
 
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadLiteralBlockScalar.java b/src/main/java/com/amihaiemil/eoyaml/ReadLiteralBlockScalar.java
index 75600a1..911f2a5 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadLiteralBlockScalar.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadLiteralBlockScalar.java
@@ -54,10 +54,14 @@ final class ReadLiteralBlockScalar extends BaseScalar {
      * @param lines Given lines to represent.
      */
     ReadLiteralBlockScalar(final YamlLines lines) {
-        this.lines = new NoScalarMarkers(
-            new NoDirectivesOrMarkers(
-                lines
-            )
+        this.lines = new Skip(
+            lines,
+            line -> line.trimmed().endsWith(">"),
+            line -> line.trimmed().endsWith("|"),
+            line -> line.trimmed().startsWith("---"),
+            line -> line.trimmed().startsWith("..."),
+            line -> line.trimmed().startsWith("%"),
+            line -> line.trimmed().startsWith("!!")
         );
     }
 
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
index 040457a..1dab4cf 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlMapping.java
@@ -53,8 +53,12 @@ final class ReadYamlMapping extends BaseYamlMapping {
     ReadYamlMapping(final AllYamlLines lines) {
         this.lines = new SameIndentationLevel(
             new WellIndented(
-                new NoDirectivesOrMarkers(
-                    lines
+                new Skip(
+                    lines,
+                    line -> line.trimmed().startsWith("---"),
+                    line -> line.trimmed().startsWith("..."),
+                    line -> line.trimmed().startsWith("%"),
+                    line -> line.trimmed().startsWith("!!")
                 )
             )
         );
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
index ca03b57..feaab19 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlSequence.java
@@ -49,8 +49,12 @@ final class ReadYamlSequence extends BaseYamlSequence {
     ReadYamlSequence(final AllYamlLines lines) {
         this.lines = new SameIndentationLevel(
             new WellIndented(
-                new NoDirectivesOrMarkers(
-                    lines
+                new Skip(
+                    lines,
+                    line -> line.trimmed().startsWith("---"),
+                    line -> line.trimmed().startsWith("..."),
+                    line -> line.trimmed().startsWith("%"),
+                    line -> line.trimmed().startsWith("!!")
                 )
             )
         );
diff --git a/src/main/java/com/amihaiemil/eoyaml/ReadYamlStream.java b/src/main/java/com/amihaiemil/eoyaml/ReadYamlStream.java
index 6f4c958..a010ce6 100644
--- a/src/main/java/com/amihaiemil/eoyaml/ReadYamlStream.java
+++ b/src/main/java/com/amihaiemil/eoyaml/ReadYamlStream.java
@@ -51,7 +51,10 @@ final class ReadYamlStream extends BaseYamlStream {
     ReadYamlStream(final AllYamlLines lines) {
         this.lines = new WellIndented(
             new StartMarkers(
-                new NoDirectives(lines)
+                new Skip(
+                    lines,
+                    line -> line.trimmed().startsWith("%")
+                )
             )
         );
     }
diff --git a/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java b/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java
index f767c80..9964928 100644
--- a/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java
+++ b/src/main/java/com/amihaiemil/eoyaml/RtYamlInput.java
@@ -74,8 +74,12 @@ final class RtYamlInput implements YamlInput {
     @Override
     public Scalar readPlainScalar() throws IOException {
         final ReadPlainScalar read;
-        final Iterator<YamlLine> iterator = new NoDirectivesOrMarkers(
-            this.readInput()
+        final Iterator<YamlLine> iterator = new Skip(
+            this.readInput(),
+            line -> line.trimmed().startsWith("---"),
+            line -> line.trimmed().startsWith("..."),
+            line -> line.trimmed().startsWith("%"),
+            line -> line.trimmed().startsWith("!!")
         ).iterator();
         if(!iterator.hasNext()) {
             read = new ReadPlainScalar(new YamlLine.NullYamlLine());
diff --git a/src/main/java/com/amihaiemil/eoyaml/NoDirectivesOrMarkers.java b/src/main/java/com/amihaiemil/eoyaml/Skip.java
similarity index 66%
rename from src/main/java/com/amihaiemil/eoyaml/NoDirectivesOrMarkers.java
rename to src/main/java/com/amihaiemil/eoyaml/Skip.java
index 9a26847..0193ba4 100644
--- a/src/main/java/com/amihaiemil/eoyaml/NoDirectivesOrMarkers.java
+++ b/src/main/java/com/amihaiemil/eoyaml/Skip.java
@@ -33,58 +33,54 @@ import java.util.Iterator;
 import java.util.List;
 
 /**
- * No directives or markers. Decorates some YamlLines
- * and ignores YAML directives and markers from iteration.
- * Use this class as follows:
- * <pre>
- *  YamlLines noDirs = new NoDirectivesOrMarkers(
- *      new AllYamlLines(lines)
- * );//Ignores YAML Directives and Start/End markers from iteration.
- * </pre>
+ * Decorator over some YamlLines which makes sure that lines
+ * which satisfy one of the given conditions are ignored from
+ * iteration.
  * @author Mihai Andronache (amihaiemil@gmail.com)
  * @version $Id$
- * @since 3.1.2
+ * @since 4.2.0
  */
-final class NoDirectivesOrMarkers implements YamlLines {
+final class Skip implements YamlLines {
 
     /**
      * YamlLines.
      */
     private final YamlLines yamlLines;
 
+    /**
+     * If a YamlLine meets any of these conditions, it is skipped.
+     */
+    private final Condition[] conditions;
+
     /**
      * Ctor.
      * @param yamlLines The Yaml lines.
+     * @param conditions Conditions.
      */
-    NoDirectivesOrMarkers(final YamlLines yamlLines) {
+    Skip(final YamlLines yamlLines, final Condition... conditions) {
         this.yamlLines = yamlLines;
+        this.conditions = conditions;
     }
 
-    /**
-     * Returns an iterator over these Yaml lines.
-     * It ignores the YAML Directives and Marker lines.
-     * @return Iterator over these yaml lines.
-     */
     @Override
     public Iterator<YamlLine> iterator() {
         Iterator<YamlLine> iterator = this.yamlLines.iterator();
         if (iterator.hasNext()) {
-            final List<YamlLine> noDirsOrMarks = new ArrayList<>();
+            final List<YamlLine> notSkipped = new ArrayList<>();
             while (iterator.hasNext()) {
+                boolean skip = false;
                 final YamlLine current = iterator.next();
-                final String currentLine = current.trimmed();
-                if (
-                    "---".equals(currentLine)
-                        || "...".equals(currentLine)
-                        || currentLine.startsWith("%")
-                        || currentLine.startsWith("!!")
-                ) {
-                    continue;
-                } else {
-                    noDirsOrMarks.add(current);
+                for(int idx = 0; idx < this.conditions.length; idx++) {
+                    if(this.conditions[idx].isMet(current)) {
+                        skip = true;
+                        break;
+                    }
+                }
+                if(!skip) {
+                    notSkipped.add(current);
                 }
             }
-            iterator = noDirsOrMarks.iterator();
+            iterator = notSkipped.iterator();
         }
         return iterator;
     }
@@ -103,4 +99,22 @@ final class NoDirectivesOrMarkers implements YamlLines {
     public YamlNode toYamlNode(final YamlLine prev) {
         return this.yamlLines.toYamlNode(prev);
     }
+
+    /**
+     * Condition that a YamlLine has to satisfy in order to be
+     * skipped/ignored from iteration.
+     * @author Mihai Andronache (amihaiemil@gmail.com)
+     * @version $Id$
+     * @since 4.2.0
+     */
+    interface Condition {
+
+        /**
+         * Is this condition met or not?
+         * @param line YamlLine.
+         * @return True or false.
+         */
+        boolean isMet(final YamlLine line);
+
+    }
 }
diff --git a/src/main/java/com/amihaiemil/eoyaml/StartMarkers.java b/src/main/java/com/amihaiemil/eoyaml/StartMarkers.java
index b43dae8..0e019c2 100644
--- a/src/main/java/com/amihaiemil/eoyaml/StartMarkers.java
+++ b/src/main/java/com/amihaiemil/eoyaml/StartMarkers.java
@@ -48,21 +48,10 @@ final class StartMarkers implements YamlLines {
     private YamlLines yamlLines;
 
     /**
-     * Constructor. Pay attention, directives will be
-     * omitted from the given lines.
+     * Constructor.
      * @param yamlLines The YAML Lines.
      */
     StartMarkers(final YamlLines yamlLines){
-        this(new NoDirectives(yamlLines));
-    }
-
-    /**
-     * Constructor.
-     * @param yamlLines The YAML Lines. YAML Directives
-     *  should always be omitted, we only iterate over
-     *  the Start markers.
-     */
-    StartMarkers(final NoDirectives yamlLines){
         this.yamlLines = yamlLines;
     }
 


Test patch:
diff --git a/src/test/java/com/amihaiemil/eoyaml/EvenlyIndentedLineTest.java b/src/test/java/com/amihaiemil/eoyaml/EvenlyIndentedLineTest.java
deleted file mode 100644
index 5a03a8b..0000000
--- a/src/test/java/com/amihaiemil/eoyaml/EvenlyIndentedLineTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Copyright (c) 2016-2020, Mihai Emil Andronache
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- *  list of conditions and the following disclaimer.
- *  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.
- * Neither the name of the copyright holder nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- * 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.
- */
-package com.amihaiemil.eoyaml;
-
-import org.hamcrest.MatcherAssert;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link EvenlyIndentedLine}.
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 1.0.0
- *
- */
-public final class EvenlyIndentedLineTest {
-
-    /**
-     * EvenlyIndentedLine knows its number.
-     */
-    @Test
-    public void knowsNumber() {
-        YamlLine line = new EvenlyIndentedLine(
-            new RtYamlLine("this line", 12)
-        );
-        MatcherAssert.assertThat(line.number(), Matchers.is(12));
-    }
-
-    /**
-     * EvenlyIndentedLine can trim itself.
-     */
-    @Test
-    public void trimmsItself() {
-        YamlLine line = new EvenlyIndentedLine(
-            new RtYamlLine("   this: line   ", 10)
-        );
-        MatcherAssert.assertThat(
-            line.trimmed(), Matchers.equalTo("this: line")
-        );
-    }
-
-    /**
-     * EvenlyIndentedLine returns its, indentation if it's right.
-     */
-    @Test
-    public void isWellIndented() {
-        YamlLine byZero = new EvenlyIndentedLine(
-            new RtYamlLine("this: line", 5)
-        );
-        MatcherAssert.assertThat(
-            byZero.indentation(), Matchers.is(0)
-        );
-        YamlLine byFour = new EvenlyIndentedLine(
-                new RtYamlLine("    this: line", 10)
-        );
-        MatcherAssert.assertThat(
-            byFour.indentation(), Matchers.is(4)
-        );
-    }
-
-    /**
-     * EvenlyIndentedLine throws an exception when the line
-     * has an odd indentation.
-     */
-    @Test (expected = IllegalStateException.class)
-    public void isBadlyIndented() {
-        YamlLine line = new EvenlyIndentedLine(
-            new RtYamlLine("   odd: indent", 8)
-        );
-        line.indentation();
-    }
-
-}
diff --git a/src/test/java/com/amihaiemil/eoyaml/NoDirectivesOrMarkersTest.java b/src/test/java/com/amihaiemil/eoyaml/NoDirectivesOrMarkersTest.java
deleted file mode 100644
index e07183f..0000000
--- a/src/test/java/com/amihaiemil/eoyaml/NoDirectivesOrMarkersTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * Copyright (c) 2016-2020, Mihai Emil Andronache
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- *  list of conditions and the following disclaimer.
- *  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.
- * Neither the name of the copyright holder nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- * 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.
- */
-package com.amihaiemil.eoyaml;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hamcrest.MatcherAssert;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Unit tests for {@link NoDirectivesOrMarkers}.
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 3.1.2
- */
-public final class NoDirectivesOrMarkersTest {
-
-    /**
-     * NoDirectivesOrMarkers can return the encapsulated lines.
-     */
-    @Test
-    @SuppressWarnings("unchecked")
-    public void returnsLines() {
-        final YamlLines lines = Mockito.mock(YamlLines.class);
-        final Collection<YamlLine> collection = Mockito.mock(Collection.class);
-        Mockito.when(lines.lines()).thenReturn(collection);
-        MatcherAssert.assertThat(
-            new NoDirectivesOrMarkers(lines).lines(),
-            Matchers.is(collection)
-        );
-    }
-    
-    /**
-     * NoDirectivesOrMarkers can turn itself into YamlNode.
-     */
-    @Test
-    public void turnsIntoYamlNode() {
-        final YamlLines lines = Mockito.mock(YamlLines.class);
-        final YamlLine prev = Mockito.mock(YamlLine.class);
-        final YamlNode result = Mockito.mock(YamlNode.class);
-        Mockito.when(lines.toYamlNode(prev)).thenReturn(result);
-        MatcherAssert.assertThat(
-            new NoDirectivesOrMarkers(lines).toYamlNode(prev),
-            Matchers.is(result)
-        );
-    }
-    
-    /**
-     * NoDirectivesOrMarkers should ignore YAML directives
-     * and markers from iteration.
-     */
-    @Test
-    public void ignoresDirectivesAndMarkers() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine("%YAML 1.2", 0));
-        lines.add(new RtYamlLine("---", 1));
-        lines.add(new RtYamlLine("first: something", 2));
-        lines.add(new RtYamlLine("second: ", 3));
-        lines.add(new RtYamlLine("  fourth: some", 4));
-        lines.add(new RtYamlLine("  fifth: values", 5));
-        lines.add(new RtYamlLine("third:", 6));
-        lines.add(new RtYamlLine("  - seq", 7));
-        lines.add(new RtYamlLine("...", 8));
-        final YamlLines ndmLines = new NoDirectivesOrMarkers(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(6)
-        );
-        final Iterator<YamlLine> iterator = ndmLines.iterator();
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("first: something")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("second:")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fourth: some")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fifth: values")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("third:")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("- seq")
-        );
-    }
-    
-    /**
-     * NoDirectivesOrMarkers iterates over all the lines, since
-     * there are actually no directives or markers to ignore.
-     */
-    @Test
-    public void noDirectivesAndMarkersToIgnore() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine("first: something", 0));
-        lines.add(new RtYamlLine("second: ", 1));
-        lines.add(new RtYamlLine("  fourth: some", 2));
-        lines.add(new RtYamlLine("  fifth: values", 3));
-        final YamlLines ndmLines = new NoDirectivesOrMarkers(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(4)
-        );
-        final Iterator<YamlLine> iterator = ndmLines.iterator();
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("first: something")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("second:")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fourth: some")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fifth: values")
-        );
-    }
-    
-    /**
-     * NoDirectivesOrMarkers works with no lines.
-     */
-    @Test
-    public void iteratesEmptyLines() {
-        final YamlLines ndmLines = new NoDirectivesOrMarkers(
-            new AllYamlLines(new ArrayList<YamlLine>())
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(0)
-        );
-    }
-}
diff --git a/src/test/java/com/amihaiemil/eoyaml/NoDirectivesTest.java b/src/test/java/com/amihaiemil/eoyaml/NoDirectivesTest.java
deleted file mode 100644
index 91732dd..0000000
--- a/src/test/java/com/amihaiemil/eoyaml/NoDirectivesTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package com.amihaiemil.eoyaml;
-
-import org.hamcrest.MatcherAssert;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Unit tests for {@link NoDirectives}.
- * @checkstyle ExecutableStatementCount (200 lines)
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 3.1.4
- */
-public final class NoDirectivesTest {
-
-    /**
-     * NoDirectives can return the encapsulated lines.
-     */
-    @Test
-    @SuppressWarnings("unchecked")
-    public void returnsLines() {
-        final YamlLines lines = Mockito.mock(YamlLines.class);
-        final Collection<YamlLine> collection = Mockito.mock(Collection.class);
-        Mockito.when(lines.lines()).thenReturn(collection);
-        MatcherAssert.assertThat(
-            new NoDirectives(lines).lines(),
-            Matchers.is(collection)
-        );
-    }
-
-    /**
-     * NoDirectives can turn itself into YamlNode.
-     */
-    @Test
-    public void turnsIntoYamlNode() {
-        final YamlLines lines = Mockito.mock(YamlLines.class);
-        final YamlLine prev = Mockito.mock(YamlLine.class);
-        final YamlNode result = Mockito.mock(YamlNode.class);
-        Mockito.when(lines.toYamlNode(prev)).thenReturn(result);
-        MatcherAssert.assertThat(
-            new NoDirectives(lines).toYamlNode(prev),
-            Matchers.is(result)
-        );
-    }
-
-    /**
-     * NoDirectives should ignore YAML directives
-     * and markers from iteration.
-     */
-    @Test
-    public void ignoresDirectives() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine("%YAML 1.2", 0));
-        lines.add(new RtYamlLine("---", 1));
-        lines.add(new RtYamlLine("first: something", 2));
-        lines.add(new RtYamlLine("second: ", 3));
-        lines.add(new RtYamlLine("  fourth: some", 4));
-        lines.add(new RtYamlLine("  fifth: values", 5));
-        lines.add(new RtYamlLine("third:", 6));
-        lines.add(new RtYamlLine("  - seq", 7));
-        lines.add(new RtYamlLine("...", 8));
-        lines.add(new RtYamlLine("%YAML 1.2", 9));
-        lines.add(new RtYamlLine("---", 10));
-        lines.add(new RtYamlLine("...", 11));
-
-        final YamlLines ndmLines = new NoDirectives(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(10)
-        );
-        final Iterator<YamlLine> iterator = ndmLines.iterator();
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("---")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("first: something")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("second:")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fourth: some")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fifth: values")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("third:")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("- seq")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("...")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("---")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("...")
-        );
-    }
-
-    /**
-     * NoDirectives iterates over all the lines, since
-     * there are actually no directives to ignore.
-     */
-    @Test
-    public void noDirectivesAndMarkersToIgnore() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine("first: something", 0));
-        lines.add(new RtYamlLine("second: ", 1));
-        lines.add(new RtYamlLine("  fourth: some", 2));
-        lines.add(new RtYamlLine("  fifth: values", 3));
-        final YamlLines ndmLines = new NoDirectives(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(4)
-        );
-        final Iterator<YamlLine> iterator = ndmLines.iterator();
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("first: something")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("second:")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fourth: some")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("fifth: values")
-        );
-    }
-
-    /**
-     * NoDirectivesOrMarkers works with no lines.
-     */
-    @Test
-    public void iteratesEmptyLines() {
-        final YamlLines ndmLines = new NoDirectives(
-            new AllYamlLines(new ArrayList<YamlLine>())
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(0)
-        );
-    }
-}
diff --git a/src/test/java/com/amihaiemil/eoyaml/NoScalarMarkersTest.java b/src/test/java/com/amihaiemil/eoyaml/NoScalarMarkersTest.java
deleted file mode 100644
index 732af88..0000000
--- a/src/test/java/com/amihaiemil/eoyaml/NoScalarMarkersTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * Copyright (c) 2016-2020, Mihai Emil Andronache
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- *  list of conditions and the following disclaimer.
- *  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.
- * Neither the name of the copyright holder nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- * 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.
- */
-package com.amihaiemil.eoyaml;
-
-import org.hamcrest.MatcherAssert;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Unit tests for {@link NoScalarMarkers}.
- * @author Mihai Andronache (amihaiemil@gmail.com)
- * @version $Id$
- * @since 4.0.0
- */
-public final class NoScalarMarkersTest {
-    /**
-     * {@link NoScalarMarkers} can return the encapsulated lines.
-     */
-    @Test
-    @SuppressWarnings("unchecked")
-    public void returnsLines() {
-        final YamlLines lines = Mockito.mock(YamlLines.class);
-        final Collection<YamlLine> collection = Mockito.mock(Collection.class);
-        Mockito.when(lines.lines()).thenReturn(collection);
-        MatcherAssert.assertThat(
-            new NoScalarMarkers(lines).lines(),
-            Matchers.is(collection)
-        );
-    }
-
-    /**
-     * {@link NoScalarMarkers} can turn itself into YamlNode.
-     */
-    @Test
-    public void turnsIntoYamlNode() {
-        final YamlLines lines = Mockito.mock(YamlLines.class);
-        final YamlLine prev = Mockito.mock(YamlLine.class);
-        final YamlNode result = Mockito.mock(YamlNode.class);
-        Mockito.when(lines.toYamlNode(prev)).thenReturn(result);
-        MatcherAssert.assertThat(
-            new NoScalarMarkers(lines).toYamlNode(prev),
-            Matchers.is(result)
-        );
-    }
-
-    /**
-     * {@link NoScalarMarkers} should ignore the '|' marker.
-     */
-    @Test
-    public void ignoresLiteralScalarMarker() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine("|", 0));
-        lines.add(new RtYamlLine("first", 1));
-        lines.add(new RtYamlLine("second", 2));
-
-        final YamlLines ndmLines = new NoScalarMarkers(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(2)
-        );
-        final Iterator<YamlLine> iterator = ndmLines.iterator();
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("first")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("second")
-        );
-    }
-
-
-    /**
-     * {@link NoScalarMarkers} should ignore the '>' marker.
-     */
-    @Test
-    public void ignoresFoldedScalarMarker() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine(">", 0));
-        lines.add(new RtYamlLine("first", 1));
-        lines.add(new RtYamlLine("second", 2));
-
-        final YamlLines ndmLines = new NoScalarMarkers(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(2)
-        );
-        final Iterator<YamlLine> iterator = ndmLines.iterator();
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("first")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("second")
-        );
-    }
-
-    /**
-     * {@link NoScalarMarkers} iterates over all the lines, since
-     * there are actually no directives to ignore.
-     */
-    @Test
-    public void noDirectivesAndMarkersToIgnore() {
-        final List<YamlLine> lines = new ArrayList<>();
-        lines.add(new RtYamlLine("first", 0));
-        lines.add(new RtYamlLine("second", 1));
-        lines.add(new RtYamlLine("third", 2));
-        final YamlLines ndmLines = new NoScalarMarkers(
-            new AllYamlLines(lines)
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(3)
-        );
-        final Iterator<YamlLine> iterator = ndmLines.iterator();
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("first")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("second")
-        );
-        MatcherAssert.assertThat(
-            iterator.next().trimmed(),
-            Matchers.equalTo("third")
-        );
-    }
-
-    /**
-     * {@link NoScalarMarkers} works with no lines.
-     */
-    @Test
-    public void iteratesEmptyLines() {
-        final YamlLines ndmLines = new NoScalarMarkers(
-            new AllYamlLines(new ArrayList<>())
-        );
-        MatcherAssert.assertThat(
-            ndmLines,
-            Matchers.iterableWithSize(0)
-        );
-    }
-}
diff --git a/src/test/java/com/amihaiemil/eoyaml/SkipTest.java b/src/test/java/com/amihaiemil/eoyaml/SkipTest.java
new file mode 100644
index 0000000..91cb0e6
--- /dev/null
+++ b/src/test/java/com/amihaiemil/eoyaml/SkipTest.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2016-2020, Mihai Emil Andronache
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ *  list of conditions and the following disclaimer.
+ *  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.
+ * Neither the name of the copyright holder nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ * 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.
+ */
+package com.amihaiemil.eoyaml;
+
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Unit tests for {@link Skip}.
+ * @author Mihai Andronache (amihaiemil@gmail.com)
+ * @version $Id$
+ * @since 4.0.2
+ */
+public final class SkipTest {
+
+    /**
+     * No line is skipped when there are no conditions.
+     */
+    @Test
+    public void noConditionsSkipsNone() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("first: somethingElse", 0));
+        lines.add(new RtYamlLine("second: ", 1));
+        lines.add(new RtYamlLine("  fourth: some", 2));
+        lines.add(new RtYamlLine("  fifth: values", 3));
+        lines.add(new RtYamlLine("third: something", 4));
+        final YamlLines all = new AllYamlLines(lines);
+        MatcherAssert.assertThat(all, Matchers.iterableWithSize(lines.size()));
+        MatcherAssert.assertThat(
+            new Skip(all), Matchers.iterableWithSize(lines.size())
+        );
+    }
+
+    /**
+     * It works when there are no lines given.
+     */
+    @Test
+    public void worksWithNoLines() {
+        final List<YamlLine> lines = new ArrayList<>();
+        final YamlLines all = new AllYamlLines(lines);
+        MatcherAssert.assertThat(all, Matchers.iterableWithSize(lines.size()));
+        MatcherAssert.assertThat(
+            new Skip(all), Matchers.iterableWithSize(lines.size())
+        );
+        MatcherAssert.assertThat(
+            new Skip(
+                all,
+                line -> {
+                    throw new IllegalStateException(
+                        "Condition should not be checked, there are no lines."
+                    );
+                }
+            ),
+            Matchers.iterableWithSize(lines.size())
+        );
+    }
+    /**
+     * Lines which are satisfying one of the conditions are skipped.
+     */
+    @Test
+    public void skipsLines() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("---", 0));
+        lines.add(new RtYamlLine("temp: 10C", 1));
+        lines.add(new RtYamlLine("...", 2));
+        lines.add(new RtYamlLine("---", 3));
+        lines.add(new RtYamlLine("temp: 15C", 4));
+        lines.add(new RtYamlLine("...", 5));
+        final YamlLines all = new AllYamlLines(lines);
+        MatcherAssert.assertThat(all, Matchers.iterableWithSize(lines.size()));
+        final YamlLines skip = new Skip(
+            all,
+            line -> line.trimmed().startsWith("---"),
+            line -> line.trimmed().startsWith("...")
+        );
+        MatcherAssert.assertThat(skip, Matchers.iterableWithSize(2));
+        final Iterator<YamlLine> notSkipped = skip.iterator();
+        MatcherAssert.assertThat(
+            notSkipped.next().trimmed(),
+            Matchers.equalTo("temp: 10C")
+        );
+        MatcherAssert.assertThat(
+            notSkipped.next().trimmed(),
+            Matchers.equalTo("temp: 15C")
+        );
+    }
+
+    /**
+     * No line is skipped because none of them are satisfying any
+     * conditions.
+     */
+    @Test
+    public void skipsNoLines() {
+        final List<YamlLine> lines = new ArrayList<>();
+        lines.add(new RtYamlLine("temp: 10C", 1));
+        lines.add(new RtYamlLine("nextTemp: 15C", 4));
+        final YamlLines all = new AllYamlLines(lines);
+        MatcherAssert.assertThat(all, Matchers.iterableWithSize(lines.size()));
+        final YamlLines skip = new Skip(
+            all,
+            line -> line.trimmed().startsWith("---"),
+            line -> line.trimmed().startsWith("...")
+        );
+        MatcherAssert.assertThat(skip, Matchers.iterableWithSize(lines.size()));
+        final Iterator<YamlLine> notSkipped = skip.iterator();
+        MatcherAssert.assertThat(
+            notSkipped.next().trimmed(),
+            Matchers.equalTo("temp: 10C")
+        );
+        MatcherAssert.assertThat(
+            notSkipped.next().trimmed(),
+            Matchers.equalTo("nextTemp: 15C")
+        );
+    }
+}