// Path: berserker-commons/src/main/java/io/smartcat/berserker/api/RateGenerator.java
// public interface RateGenerator {
// 
//     /**
//      * Returns rate per second as a function of time.
//      *
//      * @param time Relative time in nanoseconds from starting load generator.
//      * @return Rate per second as a function of time.
//      */
//     double getRate(long time);
// }
// 
// Path: berserker-core/src/main/java/io/smartcat/berserker/rategenerator/ConstantRateGenerator.java
// public class ConstantRateGenerator implements RateGenerator {
// 
//     private final double perSecondRate;
// 
//     /**
//      * Constructs rate generator with specified <code>perSecondRate</code>.
//      *
//      * @param perSecondRate Rate of the rate generator per second, must be positive number.
//      */
//     public ConstantRateGenerator(double perSecondRate) {
//         if (perSecondRate <= 0) {
//             throw new IllegalArgumentException("Rate must be positive number.");
//         }
//         this.perSecondRate = perSecondRate;
//     }
// 
//     @Override
//     public double getRate(long time) {
//         return perSecondRate;
//     }
// }
// 
// Path: berserker-core/src/main/java/io/smartcat/berserker/rategenerator/RateGeneratorProxy.java
// public class RateGeneratorProxy implements RateGenerator {
// 
//     private RateGenerator delegate;
// 
//     /**
//      * Constructs proxy without delegate.
//      */
//     public RateGeneratorProxy() {
//     }
// 
//     /**
//      * Constructs proxy with specified <code>delegate</code>.
//      *
//      * @param delegate Value which will be evaluated and cached.
//      */
//     public RateGeneratorProxy(RateGenerator delegate) {
//         setDelegate(delegate);
//     }
// 
//     /**
//      * Sets value to this proxy.
//      *
//      * @param delegate Value which will be evaluated and cached.
//      */
//     public void setDelegate(RateGenerator delegate) {
//         if (delegate == null) {
//             throw new IllegalArgumentException("Delegate cannot be null.");
//         }
//         this.delegate = delegate;
//     }
// 
//     @Override
//     public double getRate(long time) {
//         checkDelegate();
//         return delegate.getRate(time);
//     }
// 
//     private void checkDelegate() {
//         if (delegate == null) {
//             throw new DelegateNotSetException();
//         }
//     }
// 
//     /**
//      * Signals that delegate is not set.
//      */
//     public static class DelegateNotSetException extends RuntimeException {
// 
//         private static final long serialVersionUID = 6257779717961934851L;
// 
//         /**
//          * Constructs {@link DelegateNotSetException} with default message.
//          */
//         public DelegateNotSetException() {
//             super("Delegate not set for ValueProxy.");
//         }
//     }
// }


import io.smartcat.berserker.api.RateGenerator;
import io.smartcat.berserker.rategenerator.ConstantRateGenerator;
import io.smartcat.berserker.rategenerator.RateGeneratorProxy;
import org.parboiled.Parboiled;
import org.parboiled.parserunners.ReportingParseRunner;
import org.parboiled.support.ParsingResult;
import java.util.HashMap;
import java.util.Map;
package io.smartcat.berserker.configuration.rategenerator;



/**
 * Constructs {@link RateGenerator} out of parsed configuration.
 */
public class RateGeneratorConfigurationParser {

    private static final String OFFSET = "offset";
    private static final String RATES = "rates";
    private static final String OUTPUT = "output";

    private final Map<String, Object> rates;
    private final Object outputExpression;
// Path: berserker-commons/src/main/java/io/smartcat/berserker/api/RateGenerator.java
// public interface RateGenerator {
// 
//     /**
//      * Returns rate per second as a function of time.
//      *
//      * @param time Relative time in nanoseconds from starting load generator.
//      * @return Rate per second as a function of time.
//      */
//     double getRate(long time);
// }
// 
// Path: berserker-core/src/main/java/io/smartcat/berserker/rategenerator/ConstantRateGenerator.java
// public class ConstantRateGenerator implements RateGenerator {
// 
//     private final double perSecondRate;
// 
//     /**
//      * Constructs rate generator with specified <code>perSecondRate</code>.
//      *
//      * @param perSecondRate Rate of the rate generator per second, must be positive number.
//      */
//     public ConstantRateGenerator(double perSecondRate) {
//         if (perSecondRate <= 0) {
//             throw new IllegalArgumentException("Rate must be positive number.");
//         }
//         this.perSecondRate = perSecondRate;
//     }
// 
//     @Override
//     public double getRate(long time) {
//         return perSecondRate;
//     }
// }
// 
// Path: berserker-core/src/main/java/io/smartcat/berserker/rategenerator/RateGeneratorProxy.java
// public class RateGeneratorProxy implements RateGenerator {
// 
//     private RateGenerator delegate;
// 
//     /**
//      * Constructs proxy without delegate.
//      */
//     public RateGeneratorProxy() {
//     }
// 
//     /**
//      * Constructs proxy with specified <code>delegate</code>.
//      *
//      * @param delegate Value which will be evaluated and cached.
//      */
//     public RateGeneratorProxy(RateGenerator delegate) {
//         setDelegate(delegate);
//     }
// 
//     /**
//      * Sets value to this proxy.
//      *
//      * @param delegate Value which will be evaluated and cached.
//      */
//     public void setDelegate(RateGenerator delegate) {
//         if (delegate == null) {
//             throw new IllegalArgumentException("Delegate cannot be null.");
//         }
//         this.delegate = delegate;
//     }
// 
//     @Override
//     public double getRate(long time) {
//         checkDelegate();
//         return delegate.getRate(time);
//     }
// 
//     private void checkDelegate() {
//         if (delegate == null) {
//             throw new DelegateNotSetException();
//         }
//     }
// 
//     /**
//      * Signals that delegate is not set.
//      */
//     public static class DelegateNotSetException extends RuntimeException {
// 
//         private static final long serialVersionUID = 6257779717961934851L;
// 
//         /**
//          * Constructs {@link DelegateNotSetException} with default message.
//          */
//         public DelegateNotSetException() {
//             super("Delegate not set for ValueProxy.");
//         }
//     }
// }


// Path: berserker-core/src/main/java/io/smartcat/berserker/configuration/rategenerator/RateGeneratorConfigurationParser.java
import io.smartcat.berserker.api.RateGenerator;
import io.smartcat.berserker.rategenerator.ConstantRateGenerator;
import io.smartcat.berserker.rategenerator.RateGeneratorProxy;
import org.parboiled.Parboiled;
import org.parboiled.parserunners.ReportingParseRunner;
import org.parboiled.support.ParsingResult;
import java.util.HashMap;
import java.util.Map;

package io.smartcat.berserker.configuration.rategenerator;



/**
 * Constructs {@link RateGenerator} out of parsed configuration.
 */
public class RateGeneratorConfigurationParser {

    private static final String OFFSET = "offset";
    private static final String RATES = "rates";
    private static final String OUTPUT = "output";

    private final Map<String, Object> rates;
    private final Object outputExpression;
    private Map<String, RateGeneratorProxy> proxyValues;