001/*license*\
002   Codelet: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com)
003
004   This software is dual-licensed under the:
005   - Lesser General Public License (LGPL) version 3.0 or, at your option, any later version;
006   - Apache Software License (ASL) version 2.0.
007
008   Either license may be applied at your discretion. More information may be found at
009   - http://en.wikipedia.org/wiki/Multi-licensing.
010
011   The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at:
012   - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
013   - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
014\*license*/
015package  com.github.aliteralmind.codelet;
016   import  com.github.xbn.linefilter.entity.EntityRequired;
017   import  com.github.xbn.linefilter.entity.OutOfRangeResponseWhen;
018   import  com.github.xbn.linefilter.entity.OnOffAbort;
019   import  com.github.xbn.number.NewLengthInRangeFor;
020   import  com.github.xbn.linefilter.entity.PostFilterSelfActiveInOutRange;
021   import  com.github.aliteralmind.codelet.CodeletInstance;
022   import  com.github.xbn.analyze.validate.NewValidResultFilterFor;
023   import  com.github.xbn.analyze.validate.ValidResultFilter;
024   import  com.github.xbn.lang.IllegalArgumentStateException;
025   import  com.github.xbn.linefilter.FilteredLineIterator;
026   import  com.github.xbn.linefilter.KeepUnmatched;
027   import  com.github.xbn.linefilter.Returns;
028   import  com.github.xbn.linefilter.entity.BlockEntity;
029   import  com.github.xbn.util.IncludeJavaDoc;
030   import  com.github.xbn.linefilter.entity.KeepMatched;
031   import  com.github.xbn.linefilter.entity.NewBlockEntityFor;
032   import  com.github.xbn.linefilter.entity.NewSingleLineEntityFor;
033   import  com.github.xbn.linefilter.entity.SingleLineEntity;
034   import  com.github.xbn.linefilter.entity.TextChildEntity;
035   import  com.github.xbn.number.LengthInRange;
036   import  com.github.xbn.regexutil.NewPatternFor;
037   import  com.github.xbn.regexutil.ReplacedInEachInput;
038   import  com.github.xbn.text.CrashIfString;
039   import  com.github.xbn.util.JavaRegexes;
040   import  java.util.ArrayList;
041   import  java.util.List;
042   import  java.util.regex.Pattern;
043   import  java.util.regex.PatternSyntaxException;
044   import  static com.github.aliteralmind.codelet.CodeletBaseConfig.*;
045/**
046   <P>Convenience functions for creating line filters tailored for codelets.</P>
047
048   @see  com.github.xbn.linefilter.FilteredLineIterator
049   @since  0.1.0
050   @author  Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <A HREF="http://codelet.aliteralmind.com">{@code http://codelet.aliteralmind.com}</A>, <A HREF="https://github.com/aliteralmind/codelet">{@code https://github.com/aliteralmind/codelet}</A>
051 **/
052public class NewLineFilterFor  {
053   /**
054      <P>Eliminates all multi-line comments, including the license and JavaDoc blocks.</P>
055
056      @return  <CODE>{@link #eliminateAllCmtBlocksAndPackageLine(boolean, Appendable, Appendable, boolean, Appendable, Appendable) eliminateAllCmtBlocksAndPackageLine}(false, null, null, true, dbgJavaMlcs_ifNotNull, dbgAllLines_ifNonNull)</CODE>
057    **/
058   public static final FilteredLineIterator eliminateAllMultiLineComments(Appendable dbgJavaMlcs_ifNotNull, Appendable dbgAllLines_ifNonNull)  {
059      return  eliminateAllCmtBlocksAndPackageLine(false, null, null, true, dbgJavaMlcs_ifNotNull, dbgAllLines_ifNonNull);
060   }
061   /**
062      <P>Eliminates the package declaration line.</P>
063
064      @return  <CODE>{@link #eliminateAllCmtBlocksAndPackageLine(boolean, Appendable, Appendable, boolean, Appendable, Appendable) eliminateAllCmtBlocksAndPackageLine}(true, dbgPkgLnValidFilter_ifNonNull, dbgPkgLnVldtr_ifNonNull, false, null, dbgAllLines_ifNonNull)</CODE>
065    **/
066   public static final FilteredLineIterator eliminatePackageLine(Appendable dbgPkgLnValidFilter_ifNonNull, Appendable dbgPkgLnVldtr_ifNonNull, Appendable dbgAllLines_ifNonNull)  {
067      return  eliminateAllCmtBlocksAndPackageLine(true, dbgPkgLnValidFilter_ifNonNull, dbgPkgLnVldtr_ifNonNull, false, null, dbgAllLines_ifNonNull);
068   }
069
070   /**
071      <P>Eliminates the package declaration line and all multi-line comment blocks.</P>
072
073      @param  doDelete_pkgDecl  If {@code true}, the package declaration line is eliminated. If {@code false}, the alterer is not created ({@code line()} is not called, and both {@code dbgPkgLnValidFilter_ifNonNull} and {@code dbgPkgLnVldtr_ifNonNull} are ignored). At least one boolean parameter must be {@code true}.
074      @param  doElim_multiLineCmts  If {@code true}, all multi-line comments are deleted. If {@code false}, {@code allJavaMultiLineComments} is not called (and {@code dbgJavaMlcs_ifNotNull} is ignored). Warning: This eliminates <I>entire lines</I>, including any text that happens to be outside of the block:
075      <BR> &nbsp; &nbsp; <CODE>This text will also be eliminated  /&#42; The start of a comment...</CODE>)
076      @return
077<BLOCKQUOTE><PRE>new {@link com.github.xbn.linefilter.z.FilteredLineIterator_Cfg#FilteredLineIterator_Cfg() FilteredLineIterator_Cfg}().
078   {@link com.github.xbn.linefilter.z.FilteredLineIterator_CfgForNeeder#allJavaMultiLineComments(Appendable) allJavaMultiLineComments}(dbgJavaMlcs_ifNotNull).{@link com.github.xbn.linefilter.z.FilteredLineIterator_CfgForNeeder#line(ValueAlterer) line}(alterer).
079   {@link com.github.xbn.linefilter.z.FilteredLineIterator_CfgForNeeder#ifBlockOrLineOrNotActive(ActiveBlockLines, ActiveSingleLines, InactiveLines) ifBlockOrLineOrNotActive}({@link com.github.xbn.linefilter.z.ActiveBlockLines ActiveBlockLines}.{@link com.github.xbn.linefilter.z.ActiveBlockLines#DISCARD DISCARD}, {@link com.github.xbn.linefilter.z.ActiveSingleLines ActiveSingleLines}.{@link com.github.xbn.linefilter.z.ActiveSingleLines#DISCARD DISCARD}, {@link com.github.xbn.linefilter.z.InactiveLines InactiveLines}.{@link com.github.xbn.linefilter.z.InactiveLines#KEEP KEEP}).
080   {@link com.github.xbn.linefilter.z.FilteredLineIterator_CfgForNeeder#debugTo(Appendable) debugTo}(dbgAllLines_ifNonNull).{@link com.github.xbn.linefilter.z.FilteredLineIterator_CfgForNeeder#build() build}()</PRE></BLOCKQUOTE>
081   Where {@code alterer} is a
082   <BR> &nbsp; &nbsp; <CODE>{@link com.github.aliteralmind.codelet.alter.NewLineAltererFor NewLineAltererFor}.{@link com.github.aliteralmind.codelet.alter.NewLineAltererFor#eliminatePackageLine(Appendable, Appendable) eliminatePackageLine}(dbgPkgLnValidFilter_ifNonNull, dbgPkgLnVldtr_ifNonNull)</CODE>
083        @see  #eliminateAllCmtBlocksAndPackageLine(CodeletInstance, String, boolean, boolean) eliminateAllCmtBlocksAndPackageLine(CodeletInstance, String, *)
084        @see  #eliminateAllMultiLineComments(Appendable, Appendable) eliminateAllMultiLineComments
085        @see  #eliminatePackageLine(Appendable, Appendable, Appendable) eliminatePackageLine
086    **/
087   public static final FilteredLineIterator eliminateAllCmtBlocksAndPackageLine(boolean doDelete_pkgDecl, Appendable dbgPkgLnValidFilter_ifNonNull, Appendable dbgPkgLnVldtr_ifNonNull, boolean doElim_multiLineCmts, Appendable dbgJavaMlcs_ifNotNull, Appendable dbgAllLines_ifNonNull)  {
088/*
089      if(!doElim_multiLineCmts  &&  !doDelete_pkgDecl)  {
090         throw  new IllegalArgumentStateException("doElim_multiLineCmts and doDelete_pkgDecl and both false. Nothing to do.");
091      }
092 */
093      List<TextChildEntity> childList = new ArrayList<TextChildEntity>(3);
094
095      if(doDelete_pkgDecl)  {
096         PostFilterSelfActiveInOutRange onOffFilter = new PostFilterSelfActiveInOutRange(
097            NewLengthInRangeFor.maxInclusive(null, 0, null),
098            OnOffAbort.ON, OnOffAbort.OFF,
099            OutOfRangeResponseWhen.IMMEDIATE,
100            null);     //debug
101
102         SingleLineEntity pkgDeclLineEntity = NewSingleLineEntityFor.match(
103            "pkgdecl", KeepMatched.NO, EntityRequired.YES,
104            Pattern.compile(JavaRegexes.PACKAGE_DECL_ONE_LINE_NO_CMTS),
105            null,      //dbgAlter (on:System.out, off:null)
106            onOffFilter,
107            null);     //dbgLineNums
108         childList.add(pkgDeclLineEntity);
109      }
110
111      if(doElim_multiLineCmts)  {
112         BlockEntity javaMlcBlock = NewBlockEntityFor.javaComment_Cfg(
113            "comment", EntityRequired.YES, IncludeJavaDoc.YES,
114            null,      //dbgStart
115            null,      //dbgEnd
116            null,
117            null).     //dbgLineNums
118               keepNone().build();
119         childList.add(javaMlcBlock);
120      }
121
122      if(childList.size() == 0)  {
123         throw  new IllegalArgumentStateException("doElim_multiLineCmts and doDelete_pkgDecl and both false. Nothing to do.");
124      }
125
126      return  new FilteredLineIterator(
127         null, Returns.KEPT, KeepUnmatched.YES,
128         null, null,    //dbgEveryLine and its line-range
129         childList.toArray(new TextChildEntity[childList.size()]));
130   }
131   /**
132      <P>Create a new eliminate-comment-blocks-and-package-line filter with named debuggers.</P>
133
134      <P>{@linkplain com.github.aliteralmind.codelet.CodeletBootstrap#NAMED_DEBUGGERS_CONFIG_FILE Named debuggers} provided to the following {@link #eliminateAllCmtBlocksAndPackageLine(boolean, Appendable, Appendable, boolean, Appendable, Appendable) eliminateAllCmtBlocksAndPackageLine} parameters:<UL>
135         <LI><CODE><I>[named_debugPrefix]</I>.filter</CODE>: {@code dbgAllLines_ifNonNull}<UL>
136            <LI>{@code .packageline}: {@code dbgPkgLnValidFilter_ifNonNull}</LI>
137            <LI>{@code .packageline.validfilter}: {@code dbgPkgLnVldtr_ifNonNull}</LI>
138            <LI>{@code .javamlcs}: {@code dbgJavaMlcs_ifNotNull}</LI>
139         </UL></LI>
140      </UL>All of which must be added to the named-debug-level configuration file:</P>
141
142<BLOCKQUOTE><PRE>PREFIX.filter=-1
143PREFIX.filter.packageline=-1
144PREFIX.filter.packageline.validfilter=-1
145PREFIX.filter.javamlcs=-1</PRE></BLOCKQUOTE>
146
147      @param  instance  For determining the current {@linkplain com.github.aliteralmind.codelet.CodeletBaseConfig#getDebugApblIfOn(CodeletInstance, String) debugging level}.
148      @param  named_debugPrefix  Prepended to all named debuggers. May not be {@code null} or empty.
149    **/
150   public static final FilteredLineIterator eliminateAllCmtBlocksAndPackageLine(CodeletInstance instance, String named_debugPrefix, boolean doDelete_pkgDecl, boolean doElim_multiLineCmts)  {
151      CrashIfString.nullEmpty(named_debugPrefix, "named_debugPrefix", null);
152      String prefixFltr = named_debugPrefix + ".filter";
153      Appendable dbgPackageLine = getDebugApblIfOn(instance,
154         prefixFltr + ".packageline");
155      Appendable dbgPackageLineValidFltr = getDebugApblIfOn(instance,
156         prefixFltr + ".packageline.validfilter");
157      Appendable dbgMlcBlkStartEnd = getDebugApblIfOn(instance,
158         prefixFltr + ".javamlcs");
159      Appendable dbgFilter = getDebugApblIfOn(instance, prefixFltr + ".alllines");
160
161      return    eliminateAllCmtBlocksAndPackageLine(doDelete_pkgDecl,
162            dbgPackageLine,           //dbgPkgLnValidFilter_ifNonNull
163            dbgPackageLineValidFltr,  //dbgPkgLnVldtr_ifNonNull
164         doElim_multiLineCmts,
165            dbgMlcBlkStartEnd,        //dbgJavaMlcs_ifNotNull
166            dbgFilter);               //dbgAllLines_ifNonNull
167   }
168   /**
169      <P><I>A code snippet:</I> Keeps all lines in a specific range, based on the text existing in the first and last lines.</P>
170
171      @param  startAppearance_num  If the start-line search term is found on multiple lines, this is the desired occurance (if two, the second line the term is found on).
172      @param  is_startLineRegex  If {@code true} {@code startLine_findWhat} is treated as a regular expression. If {@code false}, literal.
173      @param  startLine_findWhat  The start-line search term. This is the text or pattern that exists in the first line that should be kept. May not be {@code null} or empty.
174      @param  endAppearance_num  If the end-line search term is found on multiple lines, this is the desired occurance. This is the appearance of the term <I>in the entire document</I>, including any appearances before the start line.
175      @param  is_endLineRegex  If {@code true} {@code startLine_findWhat} is treated as a regular expression.
176      @param  endLine_findWhat  The start-line search term.
177      @return
178<BLOCKQUOTE><PRE>new {@link com.github.xbn.linefilter.FilteredLineIterator#FilteredLineIterator(Iterator, Returns, KeepUnmatched, Appendable, LengthInRange, TextChildEntity...) FilteredLineIterator}(
179   null, {@link com.github.xbn.linefilter.Returns}.{@link com.github.xbn.linefilter.Returns#KEPT KEPT}, {@link com.github.xbn.linefilter.KeepUnmatched}.{@link com.github.xbn.linefilter.KeepUnmatched#NO NO},
180   dbgAllLines_ifNonNull, rangeForEveryLineDebug_ifNonNull,
181   snippetBlock)</PRE></BLOCKQUOTE>
182      Where {@code snippetBlock} is a
183<BLOCKQUOTE><PRE>
184{@link com.github.xbn.linefilter.entity.NewBlockEntityFor}.{@link com.github.xbn.linefilter.entity.NewBlockEntityFor#lineRange(String, KeepMatched, EntityRequired, Pattern, ValidResultFilter, Appendable, Pattern, ValidResultFilter, Appendable, RawOnOffEntityFilter, Appendable) lineRange}(&quot;lineRange&quot;,
185   {@link com.github.xbn.linefilter.entity.KeepMatched}.{@link com.github.xbn.linefilter.entity.KeepMatched#YES YES},
186   startLinePattern, startAppearanceFilter, dbgStart_ifNonNull,
187   endLinePattern, endAppearanceFilter, dbgEnd_ifNonNull,
188   {@link com.github.xbn.linefilter.entity.EntityRequired}.{@link com.github.xbn.linefilter.entity.EntityRequired#YES YES}, null, dbgLineNums_ifNonNull)</PRE></BLOCKQUOTE>
189      and {@code startAppearanceFilter} is a
190<BLOCKQUOTE><PRE>{@link com.github.xbn.analyze.validate.NewValidResultFilterFor}.{@link com.github.xbn.analyze.validate.NewValidResultFilterFor#exactly(int, String, Appendable) exactly}(
191   startAppearance_num, ..., dbgStartFilter_ifNonNull)</PRE></BLOCKQUOTE>
192      @see  #lineRange(CodeletInstance, String, int, boolean, String, int, boolean, String) lineRange(CodeletInstance, ...)
193      @see  #lineRangeWithReplace(int, boolean, String, String, ReplacedInEachInput, Appendable, Appendable, int, boolean, String, String, ReplacedInEachInput, Appendable, Appendable, Appendable, Appendable, LengthInRange) lineRangeWithReplace
194    **/
195   public static final FilteredLineIterator lineRange(int startAppearance_num, boolean is_startLineRegex, String startLine_findWhat, Appendable dbgStartFilter_ifNonNull, Appendable dbgStart_ifNonNull, int endAppearance_num, boolean is_endLineRegex, String endLine_findWhat, Appendable dbgEndFilter_ifNonNull, Appendable dbgEnd_ifNonNull, Appendable dbgLineNums_ifNonNull, Appendable dbgAllLines_ifNonNull, LengthInRange rangeForEveryLineDebug_ifNonNull) throws PatternSyntaxException  {
196      Pattern startLinePattern = NewPatternFor.regexIfTrueLiteralIfFalse(is_startLineRegex, startLine_findWhat, "startLine_findWhat");
197      Pattern endLinePattern = NewPatternFor.regexIfTrueLiteralIfFalse(is_endLineRegex, endLine_findWhat, "endLine_findWhat");
198
199      ValidResultFilter startAppearanceFilter = NewValidResultFilterFor.exactly(
200         startAppearance_num, "startAppearance_num",
201         dbgStartFilter_ifNonNull);
202      ValidResultFilter endAppearanceFilter = NewValidResultFilterFor.exactly(
203         endAppearance_num, "endAppearance_num",
204         dbgEndFilter_ifNonNull);
205
206      BlockEntity snippetBlock = NewBlockEntityFor.lineRange("lineRange",
207         KeepMatched.YES, EntityRequired.YES,
208         startLinePattern, startAppearanceFilter, dbgStart_ifNonNull,
209         endLinePattern, endAppearanceFilter, dbgEnd_ifNonNull,
210         null, dbgLineNums_ifNonNull);
211
212      return  new FilteredLineIterator(
213         null, Returns.KEPT, KeepUnmatched.NO,
214         dbgAllLines_ifNonNull, rangeForEveryLineDebug_ifNonNull,
215         snippetBlock);
216   }
217   /**
218      <P>Create a new line-range filter with named debuggers.</P>
219
220      <P>{@linkplain com.github.aliteralmind.codelet.CodeletBootstrap#NAMED_DEBUGGERS_CONFIG_FILE Named debuggers} provided to the following {@link #lineRange(int, boolean, String, Appendable, Appendable, int, boolean, String, Appendable, Appendable, Appendable, Appendable, LengthInRange) lineRange} parameters:<UL>
221         <LI><CODE><I>[named_debugPrefix]</I>.filter</CODE><UL>
222            <LI>{@code .blockstart}: {@code dbgStart_ifNonNull}</LI>
223            <LI>{@code .blockstart.validfilter}: {@code dbgStartFilter_ifNonNull}</LI>
224            <LI>{@code .blockend}: {@code dbgEnd_ifNonNull}</LI>
225            <LI>{@code .blockend.validfilter}: {@code dbgEndFilter_ifNonNull}</LI>
226            <LI>{@code .linenums}: {@code dbgLineNums_ifNonNull}</LI>
227            <LI>{@code .alllines}: {@code dbgAllLines_ifNonNull}</LI>
228         </UL></LI>
229      </UL>All of which must be added to the named-debug-level configuration file:</P>
230
231<BLOCKQUOTE><PRE>PREFIX.filter.alllines=-1
232PREFIX.filter.blockend.validfilter=-1
233PREFIX.filter.blockend=-1
234PREFIX.filter.blockstart.validfilter=-1
235PREFIX.filter.blockstart=-1
236PREFIX.filter.linenums=-1</PRE></BLOCKQUOTE>
237
238      @param  instance  For determining the current {@linkplain com.github.aliteralmind.codelet.CodeletBaseConfig#getDebugApblIfOn(CodeletInstance, String) debugging level}.
239      @param  named_debugPrefix  Prepended to all named debuggers. May not be {@code null} or empty.
240    **/
241   public static final FilteredLineIterator lineRange(CodeletInstance instance, String named_debugPrefix, int startAppearance_num, boolean is_startLineRegex, String startLine_findWhat, int endAppearance_num, boolean is_endLineRegex, String endLine_findWhat) throws PatternSyntaxException  {
242      CrashIfString.nullEmpty(named_debugPrefix, "named_debugPrefix", null);
243      String prefixFltr = named_debugPrefix + ".filter";
244      Appendable dbgBlkStart = getDebugApblIfOn(instance,
245         prefixFltr + ".blockstart");
246      Appendable dbgBlkStartValidFltr = getDebugApblIfOn(instance,
247         prefixFltr + ".blockstart.validfilter");
248      Appendable dbgBlkEnd = getDebugApblIfOn(instance,
249         prefixFltr + ".blockend");
250      Appendable dbgBlkEndValidFltr = getDebugApblIfOn(instance,
251         prefixFltr + ".blockend.validfilter");
252      Appendable dbgLineNums = getDebugApblIfOn(instance,
253         prefixFltr + ".linenums");
254      Appendable dbgAllLines = getDebugApblIfOn(instance,
255         prefixFltr + ".alllines");
256
257      return  lineRange(
258         startAppearance_num, is_startLineRegex, startLine_findWhat,
259            dbgBlkStartValidFltr, dbgBlkStart,
260         endAppearance_num, is_endLineRegex, endLine_findWhat,
261            dbgBlkEndValidFltr, dbgBlkEnd, dbgLineNums, dbgAllLines, null);
262   }
263   /**
264      <P>Keeps all lines in a specific range, based on the text existing in the first and last lines, making a replacement on the first and last lines only. This is useful when lines must be marked, but those marks should not be seen in the final output.</P>
265
266      <P>For documentation on all other parameters, see {@link #lineRange(int, boolean, String, Appendable, Appendable, int, boolean, String, Appendable, Appendable, Appendable, Appendable, LengthInRange) lineRange}.</P>
267
268      @param  startLine_rplcWith  The replacement term for the start-line search term ({@code startLine_findWhat}). May not be {@code null} or empty.
269      @param  startRplcs_notMtchNum  In most cases, this should be set to {@code "FIRST"}. See <CODE>com.github.xbn.regexutil.{@link com.github.xbn.regexutil.ReplacedInEachInput}</CODE>.
270      @param  endLine_rplcWith  The replacement term for the end-line search term ({@code endLine_findWhat}).
271      @param  endRplcs_notMtchNum  In most cases, this should be set to {@code "FIRST"}.
272      @return  The same as {@link #lineRange(CodeletInstance, String, int, boolean, String, int, boolean, String) lineRange}, with this alternative block entity:
273<BLOCKQUOTE><PRE>{@link com.github.xbn.linefilter.entity.NewBlockEntityFor}.{@link com.github.xbn.linefilter.entity.NewBlockEntityFor#lineRangeWithReplace(String, KeepStartLine, KeepMidLines, KeepEndLine, EntityRequired, Pattern, String, ReplacedInEachInput, ValidResultFilter, Appendable, ValueAlterer, Pattern, String, ReplacedInEachInput, ValidResultFilter, Appendable, RawOnOffEntityFilter, Appendable) lineRangeWithReplace}(
274   &quot;lineRangeWithReplace&quot;, {@link com.github.xbn.linefilter.KeepMatched}.{@link com.github.xbn.linefilter.KeepMatched#YES YES},
275   startLinePattern, startLine_rplcWith, startRplcs_notMtchNum, startAppearanceFilter,
276      dbgStartRplcr_ifNonNull,
277   null,         //No mid alterer
278   endLinePattern, endLine_rplcWith, endRplcs_notMtchNum, endAppearanceFilter,
279      dbgEndRplcr_ifNonNull,
280   {@link com.github.xbn.linefilter.entity.EntityRequired}.{@link com.github.xbn.linefilter.entity.EntityRequired#YES YES}, null, dbgLineNums_ifNonNull)</PRE></BLOCKQUOTE>
281    **/
282   public static final FilteredLineIterator lineRangeWithReplace(int startAppearance_num, boolean is_startLineRegex, String startLine_findWhat, String startLine_rplcWith, ReplacedInEachInput startRplcs_notMtchNum, Appendable dbgStartFilter_ifNonNull, Appendable dbgStartRplcr_ifNonNull, int endAppearance_num, boolean is_endLineRegex, String endLine_findWhat, String endLine_rplcWith, ReplacedInEachInput endRplcs_notMtchNum, Appendable dbgEndFilter_ifNonNull, Appendable dbgEndRplcr_ifNonNull, Appendable dbgLineNums_ifNonNull, Appendable dbgAllLines_ifNonNull, LengthInRange rangeForEveryLineDebug_ifNonNull) throws PatternSyntaxException  {
283      Pattern startLinePattern = NewPatternFor.regexIfTrueLiteralIfFalse(is_startLineRegex, startLine_findWhat, "startLine_findWhat");
284      Pattern endLinePattern = NewPatternFor.regexIfTrueLiteralIfFalse(is_endLineRegex, endLine_findWhat, "endLine_findWhat");
285
286      ValidResultFilter startAppearanceFilter = NewValidResultFilterFor.exactly(
287         startAppearance_num, "startAppearance_num",
288         dbgStartFilter_ifNonNull);
289      ValidResultFilter endAppearanceFilter = NewValidResultFilterFor.exactly(
290         endAppearance_num, "endAppearance_num",
291         dbgEndFilter_ifNonNull);
292
293      BlockEntity snippetBlock = NewBlockEntityFor.lineRangeWithReplace(
294         "lineRangeWithReplace", KeepMatched.YES, EntityRequired.YES,
295         startLinePattern, startLine_rplcWith, startRplcs_notMtchNum, startAppearanceFilter,
296            dbgStartRplcr_ifNonNull,
297         null,         //No mid alterer
298         endLinePattern, endLine_rplcWith, endRplcs_notMtchNum, endAppearanceFilter,
299            dbgEndRplcr_ifNonNull,
300         null, dbgLineNums_ifNonNull);
301
302      return  new FilteredLineIterator(
303         null, Returns.KEPT, KeepUnmatched.NO,
304         dbgAllLines_ifNonNull, rangeForEveryLineDebug_ifNonNull,
305         snippetBlock);
306   }
307
308   /**
309      <P>Create a new line-range filter with named debuggers.</P>
310
311      <P>{@linkplain com.github.aliteralmind.codelet.CodeletBootstrap#NAMED_DEBUGGERS_CONFIG_FILE Named debuggers} provided to the following {@link #lineRangeWithReplace(int, boolean, String, String, ReplacedInEachInput, Appendable, Appendable, int, boolean, String, String, ReplacedInEachInput, Appendable, Appendable, Appendable, Appendable, LengthInRange) lineRangeWithReplace} parameters:<UL>
312         <LI><CODE><I>[named_debugPrefix]</I>.filter</CODE><UL>
313            <LI>{@code .blockstart}: {@code dbgStartRplcr_ifNonNull}</LI>
314            <LI>{@code .blockstart.validfilter}: {@code dbgStartFilter_ifNonNull}</LI>
315            <LI>{@code .blockend}: {@code dbgEndRplcr_ifNonNull}</LI>
316            <LI>{@code .blockend.validfilter}: {@code dbgEndFilter_ifNonNull}</LI>
317            <LI>{@code .linenums}: {@code dbgLineNums_ifNonNull}</LI>
318            <LI>{@code .alllines}: {@code dbgAllLines_ifNonNull}</LI>
319         </UL></LI>
320      </UL>All of which must be added to the named-debug-level configuration file:</P>
321
322<BLOCKQUOTE><PRE>PREFIX.filter.alllines=-1
323<BLOCKQUOTE><PRE>PREFIX.filter.linenums=-1
324PREFIX.filter.blockend.validfilter=-1
325PREFIX.filter.blockend=-1
326PREFIX.filter.blockstart.validfilter=-1
327PREFIX.filter.blockstart=-1</PRE></BLOCKQUOTE>
328
329      @param  instance  For determining the current {@linkplain com.github.aliteralmind.codelet.CodeletBaseConfig#getDebugApblIfOn(CodeletInstance, String) debugging level}.
330      @param  named_debugPrefix  Prepended to all named debuggers. May not be {@code null} or empty.
331    **/
332   public static final FilteredLineIterator lineRangeWithReplace(CodeletInstance instance, String named_debugPrefix, int startAppearance_num, boolean is_startLineRegex, String startLine_findWhat, String startLine_rplcWith, ReplacedInEachInput startRplcs_notMtchNum, int endAppearance_num, boolean is_endLineRegex, String endLine_findWhat, String endLine_rplcWith, ReplacedInEachInput endRplcs_notMtchNum) throws PatternSyntaxException  {
333      CrashIfString.nullEmpty(named_debugPrefix, "named_debugPrefix", null);
334      String prefixFltr = named_debugPrefix + ".filter";
335      Appendable dbgBlkStart = getDebugApblIfOn(instance,
336         prefixFltr + ".blockstart");
337      Appendable dbgBlkStartValidFltr = getDebugApblIfOn(instance,
338         prefixFltr + ".blockstart.validfilter");
339      Appendable dbgBlkEnd = getDebugApblIfOn(instance,
340         prefixFltr + ".blockend");
341      Appendable dbgBlkEndValidFltr = getDebugApblIfOn(instance,
342         prefixFltr + ".blockend.validfilter");
343      Appendable dbgLineNums = getDebugApblIfOn(instance,
344         prefixFltr + ".linenums");
345      Appendable dbgAllLines = getDebugApblIfOn(instance,
346         prefixFltr + ".alllines");
347
348      return  lineRangeWithReplace(
349         startAppearance_num, is_startLineRegex,
350         startLine_findWhat, startLine_rplcWith, startRplcs_notMtchNum,
351            dbgBlkStartValidFltr, dbgBlkStart,
352         endAppearance_num, is_endLineRegex,
353         endLine_findWhat, endLine_rplcWith, endRplcs_notMtchNum,
354            dbgBlkEndValidFltr, dbgBlkEnd,
355            dbgLineNums, dbgAllLines, null);
356   }
357   private NewLineFilterFor()  {
358      throw  new IllegalStateException("Do not instantiate.");
359   }
360}