// Path: src/main/java/com/athaydes/logfx/config/HighlightGroups.java
// public final class HighlightGroups {
//     private final ObservableSet<LogFile> observableFiles;
//     private final ObservableMap<String, ObservableList<HighlightExpression>> configByGroupName;
// 
//     private InvalidationListener invalidationListener;
// 
//     public HighlightGroups( ObservableSet<LogFile> observableFiles ) {
//         this.observableFiles = observableFiles;
//         configByGroupName = FXCollections.observableMap( new LinkedHashMap<>( 4 ) );
//         configByGroupName.put( "", createNewExpressions( null ) );
//     }
// 
//     public ObservableList<HighlightExpression> getByName( String name ) {
//         return configByGroupName.get( name );
//     }
// 
//     public ObservableList<HighlightExpression> getDefault() {
//         return configByGroupName.get( "" );
//     }
// 
//     public ObservableList<HighlightExpression> add( String groupName ) {
//         return configByGroupName.computeIfAbsent( groupName,
//                 this::createNewExpressions );
//     }
// 
//     public void remove( String groupName ) {
//         if ( groupName.isEmpty() ) {
//             return;
//         }
//         configByGroupName.remove( groupName );
//         observableFiles.stream()
//                 .filter( it -> groupName.equals( it.getHighlightGroup() ) )
//                 .forEach( file -> file.highlightGroupProperty().setValue( "" ) );
//     }
// 
//     public void renameGroup( String oldName, String newName ) {
//         configByGroupName.put( newName, configByGroupName.remove( oldName ) );
//         observableFiles.stream()
//                 .filter( it -> oldName.equals( it.getHighlightGroup() ) )
//                 .forEach( file -> file.highlightGroupProperty().setValue( newName ) );
//     }
// 
//     public Set<String> groupNames() {
//         return Collections.unmodifiableSet( configByGroupName.keySet() );
//     }
// 
//     public Map<String, ObservableList<HighlightExpression>> toMap() {
//         return Collections.unmodifiableMap( configByGroupName );
//     }
// 
//     public void addGroupNameListener( InvalidationListener listener ) {
//         configByGroupName.addListener( listener );
//     }
// 
//     public void removeGroupNameListener( InvalidationListener listener ) {
//         configByGroupName.removeListener( listener );
//     }
// 
//     public void clear() {
//         configByGroupName.clear();
//         configByGroupName.put( "", createNewExpressions( null ) );
//     }
// 
//     void setListener( InvalidationListener listener ) {
//         if ( invalidationListener != null ) throw new RuntimeException( "invalidation listener has already been set" );
//         invalidationListener = listener;
//         configByGroupName.addListener( listener );
//         configByGroupName.values().forEach( ( v ) -> v.addListener( listener ) );
//     }
// 
//     private ObservableList<HighlightExpression> createNewExpressions( Object ignore ) {
//         ObservableList<HighlightExpression> newList = FXCollections.observableArrayList();
//         if ( invalidationListener != null ) newList.addListener( invalidationListener );
//         return newList;
//     }
// }
// 
// Path: src/main/java/com/athaydes/logfx/text/HighlightExpression.java
// public final class HighlightExpression {
// 
//     private final Pattern expression;
//     private final Paint bkgColor;
//     private final Paint fillColor;
//     private final boolean isFiltered;
// 
//     public HighlightExpression( String expression, Paint bkgColor, Paint fillColor, boolean isFiltered ) {
//         this( Pattern.compile( expression ), bkgColor, fillColor, isFiltered );
//     }
// 
//     public HighlightExpression( Pattern expression, Paint bkgColor, Paint fillColor, boolean isFiltered ) {
//         this.expression = expression;
//         this.bkgColor = bkgColor;
//         this.fillColor = fillColor;
//         this.isFiltered = isFiltered;
//     }
// 
//     public Paint getBkgColor() {
//         return bkgColor;
//     }
// 
//     public Paint getFillColor() {
//         return fillColor;
//     }
// 
//     public Pattern getPattern() {
//         return expression;
//     }
// 
//     public boolean isFiltered() {
//         return isFiltered;
//     }
// 
//     public LogLineColors getLogLineColors() {
//         return new LogLineColors( bkgColor, fillColor );
//     }
// 
//     public boolean matches( String text ) {
//         if ( text == null ) {
//             text = "";
//         }
// 
//         // the find method does not anchor the String by default, unlike matches()
//         return expression.matcher( text ).find();
//     }
// 
//     public HighlightExpression withFilter( boolean enable ) {
//         return new HighlightExpression( this.expression, this.bkgColor, this.fillColor, enable );
//     }
// 
//     @Override
//     public String toString() {
//         return "{" +
//                 "expression=" + expression +
//                 ", bkgColor=" + bkgColor +
//                 ", fillColor=" + fillColor +
//                 ", isFiltered=" + isFiltered +
//                 '}';
//     }
// 
//     @Override
//     public boolean equals( Object o ) {
//         if ( this == o ) return true;
//         if ( o == null || getClass() != o.getClass() ) return false;
//         HighlightExpression that = ( HighlightExpression ) o;
//         return isFiltered == that.isFiltered &&
//                 expression.toString().equals( that.expression.toString() ) &&
//                 bkgColor.equals( that.bkgColor ) &&
//                 fillColor.equals( that.fillColor );
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash( expression.toString(), bkgColor, fillColor, isFiltered );
//     }
// }


import com.athaydes.logfx.config.HighlightGroups;
import com.athaydes.logfx.text.HighlightExpression;
import javafx.collections.ObservableList;
import javafx.util.StringConverter;
import java.util.Collection;
package com.athaydes.logfx.ui;



final class HighlightOptionsSelectorConverter extends StringConverter<HighlightOptions> {

    public static final String DEFAULT_GROUP_DISPLAY_NAME = "Default";

    private final HighlightOptions defaultOption;
// Path: src/main/java/com/athaydes/logfx/config/HighlightGroups.java
// public final class HighlightGroups {
//     private final ObservableSet<LogFile> observableFiles;
//     private final ObservableMap<String, ObservableList<HighlightExpression>> configByGroupName;
// 
//     private InvalidationListener invalidationListener;
// 
//     public HighlightGroups( ObservableSet<LogFile> observableFiles ) {
//         this.observableFiles = observableFiles;
//         configByGroupName = FXCollections.observableMap( new LinkedHashMap<>( 4 ) );
//         configByGroupName.put( "", createNewExpressions( null ) );
//     }
// 
//     public ObservableList<HighlightExpression> getByName( String name ) {
//         return configByGroupName.get( name );
//     }
// 
//     public ObservableList<HighlightExpression> getDefault() {
//         return configByGroupName.get( "" );
//     }
// 
//     public ObservableList<HighlightExpression> add( String groupName ) {
//         return configByGroupName.computeIfAbsent( groupName,
//                 this::createNewExpressions );
//     }
// 
//     public void remove( String groupName ) {
//         if ( groupName.isEmpty() ) {
//             return;
//         }
//         configByGroupName.remove( groupName );
//         observableFiles.stream()
//                 .filter( it -> groupName.equals( it.getHighlightGroup() ) )
//                 .forEach( file -> file.highlightGroupProperty().setValue( "" ) );
//     }
// 
//     public void renameGroup( String oldName, String newName ) {
//         configByGroupName.put( newName, configByGroupName.remove( oldName ) );
//         observableFiles.stream()
//                 .filter( it -> oldName.equals( it.getHighlightGroup() ) )
//                 .forEach( file -> file.highlightGroupProperty().setValue( newName ) );
//     }
// 
//     public Set<String> groupNames() {
//         return Collections.unmodifiableSet( configByGroupName.keySet() );
//     }
// 
//     public Map<String, ObservableList<HighlightExpression>> toMap() {
//         return Collections.unmodifiableMap( configByGroupName );
//     }
// 
//     public void addGroupNameListener( InvalidationListener listener ) {
//         configByGroupName.addListener( listener );
//     }
// 
//     public void removeGroupNameListener( InvalidationListener listener ) {
//         configByGroupName.removeListener( listener );
//     }
// 
//     public void clear() {
//         configByGroupName.clear();
//         configByGroupName.put( "", createNewExpressions( null ) );
//     }
// 
//     void setListener( InvalidationListener listener ) {
//         if ( invalidationListener != null ) throw new RuntimeException( "invalidation listener has already been set" );
//         invalidationListener = listener;
//         configByGroupName.addListener( listener );
//         configByGroupName.values().forEach( ( v ) -> v.addListener( listener ) );
//     }
// 
//     private ObservableList<HighlightExpression> createNewExpressions( Object ignore ) {
//         ObservableList<HighlightExpression> newList = FXCollections.observableArrayList();
//         if ( invalidationListener != null ) newList.addListener( invalidationListener );
//         return newList;
//     }
// }
// 
// Path: src/main/java/com/athaydes/logfx/text/HighlightExpression.java
// public final class HighlightExpression {
// 
//     private final Pattern expression;
//     private final Paint bkgColor;
//     private final Paint fillColor;
//     private final boolean isFiltered;
// 
//     public HighlightExpression( String expression, Paint bkgColor, Paint fillColor, boolean isFiltered ) {
//         this( Pattern.compile( expression ), bkgColor, fillColor, isFiltered );
//     }
// 
//     public HighlightExpression( Pattern expression, Paint bkgColor, Paint fillColor, boolean isFiltered ) {
//         this.expression = expression;
//         this.bkgColor = bkgColor;
//         this.fillColor = fillColor;
//         this.isFiltered = isFiltered;
//     }
// 
//     public Paint getBkgColor() {
//         return bkgColor;
//     }
// 
//     public Paint getFillColor() {
//         return fillColor;
//     }
// 
//     public Pattern getPattern() {
//         return expression;
//     }
// 
//     public boolean isFiltered() {
//         return isFiltered;
//     }
// 
//     public LogLineColors getLogLineColors() {
//         return new LogLineColors( bkgColor, fillColor );
//     }
// 
//     public boolean matches( String text ) {
//         if ( text == null ) {
//             text = "";
//         }
// 
//         // the find method does not anchor the String by default, unlike matches()
//         return expression.matcher( text ).find();
//     }
// 
//     public HighlightExpression withFilter( boolean enable ) {
//         return new HighlightExpression( this.expression, this.bkgColor, this.fillColor, enable );
//     }
// 
//     @Override
//     public String toString() {
//         return "{" +
//                 "expression=" + expression +
//                 ", bkgColor=" + bkgColor +
//                 ", fillColor=" + fillColor +
//                 ", isFiltered=" + isFiltered +
//                 '}';
//     }
// 
//     @Override
//     public boolean equals( Object o ) {
//         if ( this == o ) return true;
//         if ( o == null || getClass() != o.getClass() ) return false;
//         HighlightExpression that = ( HighlightExpression ) o;
//         return isFiltered == that.isFiltered &&
//                 expression.toString().equals( that.expression.toString() ) &&
//                 bkgColor.equals( that.bkgColor ) &&
//                 fillColor.equals( that.fillColor );
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash( expression.toString(), bkgColor, fillColor, isFiltered );
//     }
// }


// Path: src/main/java/com/athaydes/logfx/ui/HighlightOptionsSelectorConverter.java
import com.athaydes.logfx.config.HighlightGroups;
import com.athaydes.logfx.text.HighlightExpression;
import javafx.collections.ObservableList;
import javafx.util.StringConverter;
import java.util.Collection;

package com.athaydes.logfx.ui;



final class HighlightOptionsSelectorConverter extends StringConverter<HighlightOptions> {

    public static final String DEFAULT_GROUP_DISPLAY_NAME = "Default";

    private final HighlightOptions defaultOption;
    private final HighlightGroups groups;