@Override
  public WaveletChromatid clone() {
    try {
      final WaveletChromatid copy = (WaveletChromatid) super.clone();

      copy.centromerePosition = this.centromerePosition;
      copy.mutability = this.mutability;

      copy.sequencedGenes = new ArrayList<AbstractWaveletGene>();
      copy.promoters = new ArrayList<PromoterGene>();
      copy.localSignalGenes = new ArrayList<SignalGene>();
      copy.externalSignalGenes = new ArrayList<ExternalSignalGene>();

      for (AbstractWaveletGene currentGene : this.sequencedGenes)
        copy.sequencedGenes.add(currentGene.clone());
      for (PromoterGene currentGene : this.promoters) copy.promoters.add(currentGene.clone());
      for (SignalGene currentGene : this.localSignalGenes)
        copy.localSignalGenes.add(currentGene.clone());
      for (ExternalSignalGene currentGene : this.externalSignalGenes)
        copy.externalSignalGenes.add(currentGene.clone());

      return copy;
    } catch (CloneNotSupportedException caught) {
      LOGGER.error("CloneNotSupportedException caught but not expected!", caught);
      throw new UnexpectedDannError("CloneNotSupportedException caught but not expected", caught);
    }
  }
  public WaveletChromatid(WaveletChromatid copy) {
    this.centromerePosition = copy.centromerePosition;
    this.mutability = copy.mutability;

    this.sequencedGenes = new ArrayList<AbstractWaveletGene>();
    this.promoters = new ArrayList<PromoterGene>();
    this.localSignalGenes = new ArrayList<SignalGene>();
    this.externalSignalGenes = new ArrayList<ExternalSignalGene>();

    for (AbstractWaveletGene currentGene : copy.sequencedGenes)
      this.sequencedGenes.add(currentGene.clone());
    for (PromoterGene currentGene : copy.promoters) this.promoters.add(currentGene.clone());
    for (SignalGene currentGene : copy.localSignalGenes)
      this.localSignalGenes.add(currentGene.clone());
    for (ExternalSignalGene currentGene : copy.externalSignalGenes)
      this.externalSignalGenes.add(currentGene.clone());
  }
  public void tick() {
    // first we need to calculate the promotion of each site
    final Hashtable<Integer, Double> promotions = new Hashtable<Integer, Double>();
    for (PromoterGene promoter : this.promoters) {
      final int promoterIndex = this.sequencedGenes.indexOf(promoter);
      final int promotedIndex = promoter.getTargetDistance() + promoterIndex;
      if (promotedIndex < this.sequencedGenes.size()) {
        double promotion = 0.0;
        if (promotions.contains(promotedIndex)) promotion = promotions.get(promotedIndex);
        final double newPromotion = promotion + promoter.expressionActivity();
        if (newPromotion != 0.0) promotions.put(promotedIndex, newPromotion);
      }
    }

    for (int sequenceIndex = 0; sequenceIndex < this.sequencedGenes.size(); sequenceIndex++) {
      this.sequencedGenes
          .get(sequenceIndex)
          .tick(promotions.containsKey(sequenceIndex) ? promotions.get(sequenceIndex) : 0);
    }
  }