bool
Alignment::unionn(Alignment& al2) {
  if (!are_the_same_alignment(al2)) {
    wcerr<<L"Error when uniting the following two alignments:\n";
    wcerr<<to_wstring()<<L"\n";
    wcerr<<al2.to_wstring()<<L"\n";
    return false;
  }

  for(unsigned i=0; i<source.size(); i++) {
    for(unsigned j=0; j<target.size(); j++) {
      if (al2.alignment[i][j]) {
	alignment[i][j]=true;
      }
    }
  }

  return true;
}
bool 
Alignment::refined_intersection(Alignment& al2) {
  if (!are_the_same_alignment(al2)) {
    wcerr<<L"Error when performing the refined intersection of the following two alignments:\n";
    wcerr<<to_wstring()<<L"\n";
    wcerr<<al2.to_wstring()<<L"\n";
    return false;
  }

  //We save the alignment of (*this) before intersecting
  map<int, map<int, bool> > al1;
  for(unsigned i=0; i<source.size(); i++) {
    for(unsigned j=0; j<target.size(); j++) {
      al1[i][j]=alignment[i][j];
    }
  }

  //First, the intersection
  intersection(al2);
  //cerr<<"(0) "<<to_string()<<"\n";
  bool alignments_changed;
  //int nit=0;
  do {
    alignments_changed=false;
    //nit++;
    for (unsigned i=0; i<source.size(); i++) {
      for(unsigned j=0; j<target.size(); j++) {
	if (!alignment[i][j]) {
	  if ((al1[i][j]) || (al2.alignment[i][j])) {
	    //cerr<<"   considering ("<<i<<","<<j<<")\n";
	    bool add_alignment=true;
	    for(unsigned k=0; k<target.size(); k++) {
	      if (alignment[i][k])
		add_alignment=false;
	    }
	    for(unsigned k=0; k<source.size(); k++) {
	      if (alignment[k][j])
		add_alignment=false;
	    }
	    if (!add_alignment) {
	      //cerr<<"   ("<<i<<","<<"*) or (*,"<<j<<") are already in A\n";
	      //The aligment can still be added if it has an horizontal
	      //neighbor or a vertical neighbor already in 'alignment'
	      if ( ((alignment[i-1][j])||(alignment[i+1][j])) ||
		   ((alignment[i][j-1])||(alignment[i][j+1])) ) {
		//cerr<<"   ("<<i<<","<<j<<") has an horizontal or a vertical neighbor in A\n";
		alignment[i][j]=true; 
		//Now we that test there is no aligments in 'alignment' with
		//both horizontal and vertical neighbors
		bool neighbors=false;
		for(unsigned ii=0; (ii<source.size()) && (!neighbors); ii++) {
		  for(unsigned jj=0; (jj<target.size()) && (!neighbors); jj++) {
		    if (alignment[ii][jj]) {
		      if ( ((alignment[ii-1][jj])||(alignment[ii+1][jj])) &&
			   ((alignment[ii][jj-1])||(alignment[ii][jj+1])) ) {
			//cerr<<"   ("<<i<<","<<j<<") has both horizontal and vertical neighbors\n";
			neighbors=true;
		      }
		    }
		  }
		}
		alignment[i][j]=false;
		if(!neighbors)
		  add_alignment=true;
	      }
	    }
	    if (add_alignment) {
	      //cerr<<"   adding ("<<i<<","<<j<<")\n";
	      alignment[i][j]=true;
	      alignments_changed=true;
	    }
	  }
	}
      }
    }
    //cerr<<"("<<nit<<") "<<to_string()<<"\n";
  } while(alignments_changed);

  return true;
}