bool IsConstructedClusterNotErroneous(size_t constr_cluster_ind) {
		vector<string> read_names = GetReadNamesFromCluster(constr_cluster_ind,
				constructed_clusters_, constructed_reads_);
		set<size_t> orig_clusters_inds;
		for(auto it = read_names.begin(); it != read_names.end(); it++)
			orig_clusters_inds.insert(original_clusters_.GetCluster(*it));
		return orig_clusters_inds.size() == 1;
	}
	bool IsClusterNotMerged(size_t orig_cluster_ind) {
		vector<string> read_names = GetReadNamesFromCluster(orig_cluster_ind, original_clusters_, original_reads_);
		set<size_t> constr_cluster_inds;
		for(auto it = read_names.begin(); it != read_names.end(); it++)
			if(constructed_clusters_.ReadExists(*it))
				constr_cluster_inds.insert(constructed_clusters_.GetCluster(*it));
		return constr_cluster_inds.size() > 1;
	}
	size_t GetOriginalSuperCluster(size_t constr_cluster_ind) {
		vector<string> read_names = GetReadNamesFromCluster(constr_cluster_ind,
				constructed_clusters_, constructed_reads_);
		set<size_t> orig_clusters_inds;
		for(auto it = read_names.begin(); it != read_names.end(); it++)
			orig_clusters_inds.insert(original_clusters_.GetCluster(*it));
		assert(orig_clusters_inds.size() == 1);
		return *(orig_clusters_inds.begin());
	}
	void ComputeConstructedSingletons() {
		for(auto it = constructed_clusters_.clusters_begin(); it != constructed_clusters_.clusters_end(); it++)
					if(constructed_clusters_.IsClusterSingleton(it->first)) {
						metrics_.constructed_metrics.num_singletons++;
						auto read_name = constructed_reads_[(it->second)[0]];
						if(original_clusters_.IsClusterSingleton(original_clusters_.GetCluster(read_name)))
							metrics_.constructed_metrics.num_corr_singletons++;
					}
		metrics_.correct_singletons = metrics_.constructed_metrics.num_corr_singletons;
	}
	bool IsClusterBigAndSingletons(size_t orig_cluster_ind) {
		assert(IsClusterNotMerged(orig_cluster_ind));
		vector<string> read_names = GetReadNamesFromCluster(orig_cluster_ind, original_clusters_, original_reads_);

		set<size_t> not_trivial_clusters;
		for(auto it = read_names.begin(); it != read_names.end(); it++) {
			if(constructed_clusters_.GetClusterSizeByReadName(*it) > 1) {
				not_trivial_clusters.insert(constructed_clusters_.GetCluster(*it));
			}
		}
		return not_trivial_clusters.size() == 1;
	}
	double ComputeNotMergedFillin(size_t orig_cluster_ind) {
		vector<string> read_names = GetReadNamesFromCluster(orig_cluster_ind, original_clusters_, original_reads_);
		map<size_t, vector<size_t> > constr_subclusters;
		for(auto it = read_names.begin(); it != read_names.end(); it++) {
			size_t cluster_ind = constructed_clusters_.GetCluster(*it);
			constr_subclusters[constructed_clusters_.ClusterSize(cluster_ind)].push_back(cluster_ind);
		}

		for(auto it = constr_subclusters.rbegin(); it != constr_subclusters.rend(); it++) {
			auto clusters = it->second;
			for(auto cluster_ind = clusters.begin(); cluster_ind != clusters.end(); cluster_ind++)
				if(IsConstructedClusterNotErroneous(*cluster_ind)) {
					return double(constructed_clusters_.ClusterSize(*cluster_ind)) / original_clusters_.ClusterSize(orig_cluster_ind);
				}
		}
		return 0;
	}