COSTA: COSt and Termination Analyzer for Java Bytecode
    
    package x10;


public class HeatTransferv1 {
    static final int n = 3;
    static final int epsilon = 1; //double epsilon = 1.0e-5;

    int BigD[][];// = new int[n+1][n+1];
    int D[][];// = new int[n][n];
    int LastRow[][];// = new int[1][n];
    double A[][];// = new double[n+1][n+1];
    double Temp[][];// = new double[n+1][n+1];


    public HeatTransferv1(int n) {
	//for (int i=0; i<n; i++) {
	//    LastRow[0][i] = i;
	//}
	//for (int j=0; j<n+1; j++) {
	//    A[0][j] = 1.0;
	//}
	for (int i=1; i<n+1; i++) {
	    for (int j=0; j<n+1; j++) {
	//		A[i][j] = 0.0;
	    }
	}
    }

    public static double stencil1(HeatTransferv1 s, int x, int y) {
	double aux = 0.0;
	if (x>0) aux += s.A[x-1][y];
	if (y>0) aux += s.A[x][y-1];
	if (x<n) aux += s.A[x+1][y];
	if (y<n) aux += s.A[x][y+1];
	return aux/4;
    }

    public static void run(HeatTransferv1 s,int n) {
	// I'm trying to have it working on int values , in order to
	// be easier for COSTA to get a ranking function
	for(int delta=100000; delta>0; delta--) {

	    //do {
	    Conc.finish_begin();
	    run1(s,n);
	    Conc.finish_end();

	    double aux[] = new double[1];
	    aux[0] = 0.0;
	    double B[][] = new double[n][n];
	    for (int i=0; i<n; i++) {
		Conc.async_begin();
		run2(s,n);
		Conc.async_end();
		run3(s,n,i,aux,B);
	    }
	    //delta = (int) (aux*100000); // this ensures termination,
	    // but clearly alters the total task-level
	    
	    Conc.finish_begin();
	    run2(s,n);
	    Conc.finish_end();
	    //} while (delta > epsilon);
	}
    }
 
    public static void run1(HeatTransferv1 s, int n) {
	for (int i=0; i<n; i++) {
	    for (int j=0; j<n; j++) {
		Conc.async_begin();
		run11(s,n,i,j);
		Conc.async_end();
	    }
	}
    }

    public static void run11(HeatTransferv1 s, int n, int i, int j) {
	s.Temp[i][j] = stencil1(s,i,j);
    }

    public static void run2(HeatTransferv1 s, int n) {
	for (int i=0; i<n; i++) {
	    for (int j=0; j<n; j++) {
		Conc.async_begin();
		run21(s,n,i,j);
		Conc.async_end();
	    }
	}
    }

    public static void run21(HeatTransferv1 s, int n, int i, int j) {
	s.A[i][j] = s.Temp[i][j];
    }

    public static void run3(HeatTransferv1 s, int n, int i, double aux[], double B[][]) {
	for (int j=0; j<n; j++) {
	    //    //    B[i][j] = ( s.A[i][j]>s.Temp[i][j] ? (s.A[i][j]-s.Temp[i][j]) : (s.Temp[i][j]-s.A[i][j]) );
	    Conc.async_begin();
	    mymax(aux,B[i][0]);
	    Conc.async_end();
	}
    }

    public static void mymax(double a[],double b) {
	if (a[0]<b) a[0] = b;
    }

    //public static void prettyPrintResult(HeatTransferv1 s) {
    //for ((i) in A.region.projection(0)) {
    //    for ((j) in A.region.projection(1)) {
    //	val pt = Point.make(i,j);
    //	at (BigD(pt)) {
    //	    val tmp = A(pt);
    //            at (Place.FIRST_PLACE) Console.OUT.printf("%1.4f ",tmp);
    //        }
    //    }
    //    Console.OUT.println();
    //}
    //}

    public static void main(String args[]) {
	int n = args.length;
        HeatTransferv1 s = new HeatTransferv1(n);
        run(s,n);
	//prettyPrintResult(s);
    }
}