// Path: src/java/org/sidoh/collections/Pair.java
// public class Pair<T1, T2> {
// 	protected T1 v1;
// 	protected T2 v2;
// 	
// 	public Pair(T1 v1, T2 v2) {
// 		this.v1 = v1;
// 		this.v2 = v2;
// 	}
// 
// 	public T1 getV1() {
// 		return v1;
// 	}
// 
// 	public void setV1(T1 v1) {
// 		this.v1 = v1;
// 	}
// 
// 	public T2 getV2() {
// 		return v2;
// 	}
// 
// 	public void setV2(T2 v2) {
// 		this.v2 = v2;
// 	}
// 	
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + ((v1 == null) ? 0 : v1.hashCode());
// 		result = prime * result + ((v2 == null) ? 0 : v2.hashCode());
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Pair other = (Pair) obj;
// 		if (v1 == null) {
// 			if (other.v1 != null)
// 				return false;
// 		} else if (!v1.equals(other.v1))
// 			return false;
// 		if (v2 == null) {
// 			if (other.v2 != null)
// 				return false;
// 		} else if (!v2.equals(other.v2))
// 			return false;
// 		return true;
// 	}
// 	
// 	public String toString() {
// 		return "(" + v1 + "," + v2 + ")";
// 	}
// 
// 	public static <T1, T2> Pair<T1, T2> create(T1 v1, T2 v2) {
// 		return new Pair<T1, T2>(v1, v2);
// 	}
// }
// 
// Path: src/java/org/sidoh/song_recognition/signature/ConstellationMap.java
// public static class Star implements Serializable {
// 	private static final long serialVersionUID = 1851275921474044916L;
// 		
// 
// 	private final double time;
// 	private final double frequency;
// 	private final double intensity;
// 	private final int x;
// 	private final int y;
// 		
// 	public Star(final double time, final double frequency, final double intensity, final int x, final int y) {
// 		this.time = time;
// 		this.frequency = frequency;
// 		this.intensity = intensity;
// 		this.x = x;
// 		this.y = y;
// 	}
// 
// 	public double getTime() {
// 		return time;
// 	}
// 
// 	public double getFrequency() {
// 		return frequency;
// 	}
// 
// 	public double getIntensity() {
// 		return intensity;
// 	}
// 		
// 	public int getTick() {
// 		return x;
// 	}
// 		
// 	public int getBin() {
// 		return y;
// 	}
// 		
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + x;
// 		result = prime * result + y;
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Star other = (Star) obj;
// 		if (x != other.x)
// 			return false;
// 		if (y != other.y)
// 			return false;
// 		return true;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "Star [x=" + x + ", y=" + y + ", intensity=" + intensity + "]";
// 	}
// }


import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedList;
import org.sidoh.collections.Pair;
import org.sidoh.song_recognition.signature.ConstellationMap.Star;
import org.sidoh.song_recognition.signature.EvenFrequencyBandsStarBuffer.Builder;
import org.sidoh.song_recognition.spectrogram.Spectrogram;
		this.innerBufferList = new ArrayList<StarBuffer>(bandSizes.length);
		
		// Compute the end indexes of the bands given the percentage sizes
		Deque<Pair<Double, Integer>> buckets = new LinkedList<Pair<Double, Integer>>();
		int lastStart = 0;
		
		for (int i = 0; i < bandSizes.length; i++) {
			int nextStart = lastStart + (int)(bandSizes[i] * innerBuffers.length);
			double density = bandWeights[i] * starDensityFactor;
			buckets.addLast(Pair.create(density, nextStart));
			lastStart = nextStart;
		}
		
		if (buckets.peekLast().getV2() < innerBuffers.length) {
			Pair<Double, Integer> old = buckets.pollLast();
			buckets.addLast(Pair.create(old.getV1(), innerBuffers.length));
		}
		
		StarBuffer currentBuffer = getStarBuffer(buckets.peekFirst());
		innerBufferList.add(currentBuffer);
		for (int i = 0; i < innerBuffers.length; i++) {
			if (i >= buckets.peekFirst().getV2()) {
				buckets.pollFirst();
				currentBuffer = getStarBuffer(buckets.peekFirst());
				innerBufferList.add(currentBuffer);
			}
			innerBuffers[i] = currentBuffer;
		}
	}
	
// Path: src/java/org/sidoh/collections/Pair.java
// public class Pair<T1, T2> {
// 	protected T1 v1;
// 	protected T2 v2;
// 	
// 	public Pair(T1 v1, T2 v2) {
// 		this.v1 = v1;
// 		this.v2 = v2;
// 	}
// 
// 	public T1 getV1() {
// 		return v1;
// 	}
// 
// 	public void setV1(T1 v1) {
// 		this.v1 = v1;
// 	}
// 
// 	public T2 getV2() {
// 		return v2;
// 	}
// 
// 	public void setV2(T2 v2) {
// 		this.v2 = v2;
// 	}
// 	
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + ((v1 == null) ? 0 : v1.hashCode());
// 		result = prime * result + ((v2 == null) ? 0 : v2.hashCode());
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Pair other = (Pair) obj;
// 		if (v1 == null) {
// 			if (other.v1 != null)
// 				return false;
// 		} else if (!v1.equals(other.v1))
// 			return false;
// 		if (v2 == null) {
// 			if (other.v2 != null)
// 				return false;
// 		} else if (!v2.equals(other.v2))
// 			return false;
// 		return true;
// 	}
// 	
// 	public String toString() {
// 		return "(" + v1 + "," + v2 + ")";
// 	}
// 
// 	public static <T1, T2> Pair<T1, T2> create(T1 v1, T2 v2) {
// 		return new Pair<T1, T2>(v1, v2);
// 	}
// }
// 
// Path: src/java/org/sidoh/song_recognition/signature/ConstellationMap.java
// public static class Star implements Serializable {
// 	private static final long serialVersionUID = 1851275921474044916L;
// 		
// 
// 	private final double time;
// 	private final double frequency;
// 	private final double intensity;
// 	private final int x;
// 	private final int y;
// 		
// 	public Star(final double time, final double frequency, final double intensity, final int x, final int y) {
// 		this.time = time;
// 		this.frequency = frequency;
// 		this.intensity = intensity;
// 		this.x = x;
// 		this.y = y;
// 	}
// 
// 	public double getTime() {
// 		return time;
// 	}
// 
// 	public double getFrequency() {
// 		return frequency;
// 	}
// 
// 	public double getIntensity() {
// 		return intensity;
// 	}
// 		
// 	public int getTick() {
// 		return x;
// 	}
// 		
// 	public int getBin() {
// 		return y;
// 	}
// 		
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + x;
// 		result = prime * result + y;
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		Star other = (Star) obj;
// 		if (x != other.x)
// 			return false;
// 		if (y != other.y)
// 			return false;
// 		return true;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "Star [x=" + x + ", y=" + y + ", intensity=" + intensity + "]";
// 	}
// }


// Path: src/java/org/sidoh/song_recognition/signature/ManuallyBucketizedFrequencyBandsStarBuffer.java
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedList;
import org.sidoh.collections.Pair;
import org.sidoh.song_recognition.signature.ConstellationMap.Star;
import org.sidoh.song_recognition.signature.EvenFrequencyBandsStarBuffer.Builder;
import org.sidoh.song_recognition.spectrogram.Spectrogram;

		this.innerBufferList = new ArrayList<StarBuffer>(bandSizes.length);
		
		// Compute the end indexes of the bands given the percentage sizes
		Deque<Pair<Double, Integer>> buckets = new LinkedList<Pair<Double, Integer>>();
		int lastStart = 0;
		
		for (int i = 0; i < bandSizes.length; i++) {
			int nextStart = lastStart + (int)(bandSizes[i] * innerBuffers.length);
			double density = bandWeights[i] * starDensityFactor;
			buckets.addLast(Pair.create(density, nextStart));
			lastStart = nextStart;
		}
		
		if (buckets.peekLast().getV2() < innerBuffers.length) {
			Pair<Double, Integer> old = buckets.pollLast();
			buckets.addLast(Pair.create(old.getV1(), innerBuffers.length));
		}
		
		StarBuffer currentBuffer = getStarBuffer(buckets.peekFirst());
		innerBufferList.add(currentBuffer);
		for (int i = 0; i < innerBuffers.length; i++) {
			if (i >= buckets.peekFirst().getV2()) {
				buckets.pollFirst();
				currentBuffer = getStarBuffer(buckets.peekFirst());
				innerBufferList.add(currentBuffer);
			}
			innerBuffers[i] = currentBuffer;
		}
	}
	
	protected StarBuffer getStarBuffer(Pair<Double, Integer> bucket) {