bool PathAdjacentRelatedEdges(Graph &g, vector<EdgeId> path, bool check_start = false,
		bool check_end = false){
	for(auto e = path.begin(); e != path.end() - 1; e++)
		if(VertexAdjacentRelatedEdges(g, g.EdgeEnd(*e)))
			return true;
	if(path.size() != 0)
		if(check_start)
			if(VertexAdjacentRelatedEdges(g, g.EdgeStart(path[0])))
				return true;
		if(check_end)
			if(VertexAdjacentRelatedEdges(g, g.EdgeEnd(path[path.size() - 1])))
				return true;
	return false;
}
Sequence MergeSequences(const Graph& g,
		const vector<typename Graph::EdgeId>& continuous_path) {
	vector < Sequence > path_sequences;
	path_sequences.push_back(g.EdgeNucls(continuous_path[0]));
	for (size_t i = 1; i < continuous_path.size(); ++i) {
		VERIFY(
				g.EdgeEnd(continuous_path[i - 1])
						== g.EdgeStart(continuous_path[i]));
		path_sequences.push_back(g.EdgeNucls(continuous_path[i]));
	}
	return MergeOverlappingSequences(path_sequences, g.k());
}
vector<VertexId> get_list_of_vertices_in_path(Graph &g, vector<EdgeId> path){
	vector<VertexId> list;
	if(path.size() == 0)
		return list;

	for(size_t i = 0; i < path.size(); i++)
		list.push_back(g.EdgeStart(path[i]));

	list.push_back(g.EdgeEnd(path[path.size() - 1]));

	return list;
}
bool PathContainsLoop(Graph &g, vector<EdgeId> p){
	if(p.size() == 0)
		return false;

	set<VertexId> pathv;
	pathv.insert(g.EdgeStart(p[0]));

	for(auto e = p.begin(); e != p.end(); e++){
		VertexId end = g.EdgeEnd(*e);
		if(pathv.find(end) == pathv.end())
			pathv.insert(end);
		else
			return true;
	}

	return false;
}
void VisualizeNontrivialComponentAutoInc(
        const Graph& g, const set<typename Graph::EdgeId>& edges,
        const string& folder, const GraphLabeler<Graph>& labeler,
        shared_ptr<visualization::GraphColorer<Graph>> colorer) {
    static size_t cnt = 0;

    auto edge_colorer = make_shared<visualization::CompositeEdgeColorer<Graph>>("black");
    edge_colorer->AddColorer(colorer);
    edge_colorer->AddColorer(make_shared<visualization::SetColorer<Graph>>(g, edges, "green"));
//    shared_ptr<visualization::GraphColorer<Graph>>
    auto resulting_colorer = make_shared<visualization::CompositeGraphColorer<Graph>>(colorer, edge_colorer);
    if (edges.size() > 1) {
        set<typename Graph::VertexId> vertices;
        for (auto e : edges) {
            vertices.insert(g.EdgeStart(e));
            vertices.insert(g.EdgeEnd(e));
        }

        visualization::WriteComponent(
                ComponentCloser<Graph>(g, 0).CloseComponent(GraphComponent<Graph>(g, vertices.begin(), vertices.end())),
                folder + ToString(cnt++) + ".dot", colorer, labeler);
    }
}
 Component(const Graph& g, EdgeId e) : g_(g), cumm_length_(0), contains_deadends_(false) {
     edges_.insert(e);
     cumm_length_ += g_.length(e);
     border_.insert(g.EdgeStart(e));
     border_.insert(g.EdgeEnd(e));
 }
bool AreEdgesConnected(Graph &g, EdgeId e1, EdgeId e2){
	return g.EdgeEnd(e1) == g.EdgeStart(e2);
}
bool IsEdgeLoop(Graph &g, EdgeId edge){
	return g.EdgeStart(edge) == g.EdgeEnd(edge);
}
bool IsEdgeRelated(Graph &g, EdgeId edge){
	return g.RelatedVertices(g.EdgeStart(edge), g.EdgeEnd(edge));
}