Program: 187966
Project: 187966
Buggy source:
/** 
 * Export a pony to the file
 * @param pony  The pony
 * @throws IOException  On I/O error
 */
public void exportPony(Pony pony) throws IOException {
  Color[] colours=new Color[256];
  boolean[] format=new boolean[9];
  Color background=null, foreground=null;
  for (int i=0; i < 256; i++) {
    Colour colour=new Colour(i);
    colours[i]=new Color(colour.red,colour.green,colour.blue);
  }
  if (this.palette != null)   System.arraycopy(this.palette,0,colours,0,16);
  StringBuilder resetpalette=null;
  if (this.tty)   if (this.colourful) {
    resetpalette=new StringBuilder();
    for (int i=0; i < 16; i++) {
      Colour colour=new Colour(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append("String_Node_Str".charAt(i));
      resetpalette.append("String_Node_Str".charAt(colour.red >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.red & 15));
      resetpalette.append("String_Node_Str".charAt(colour.green >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.green & 15));
      resetpalette.append("String_Node_Str".charAt(colour.blue >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.blue & 15));
    }
  }
 else {
    resetpalette=new StringBuilder();
    for (    int i : new int[]{7,15}) {
      Colour colour=new Colour(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append("String_Node_Str".charAt(i));
      resetpalette.append("String_Node_Str".charAt(colour.red >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.red & 15));
      resetpalette.append("String_Node_Str".charAt(colour.green >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.green & 15));
      resetpalette.append("String_Node_Str".charAt(colour.blue >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.blue & 15));
    }
  }
 else   if (this.fullcolour) {
    resetpalette=new StringBuilder();
    for (int i=0; i < 16; i++) {
      Colour colour=new Colour(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append("String_Node_Str".charAt(colour.red >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.red & 15));
      resetpalette.append('/');
      resetpalette.append("String_Node_Str".charAt(colour.green >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.green & 15));
      resetpalette.append('/');
      resetpalette.append("String_Node_Str".charAt(colour.blue >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.blue & 15));
      resetpalette.append("String_Node_Str");
    }
  }
  StringBuilder databuf=new StringBuilder();
  int curleft=0, curright=0, curtop=0, curbottom=0;
  Pony.Cell[][] matrix=pony.matrix;
  Pony.Meta[][][] metamatrix=pony.metamatrix;
  boolean[] plain=new boolean[9];
  if ((pony.tags != null) || (pony.comment != null))   databuf.append("String_Node_Str");
  if (pony.tags != null)   for (  String[] tag : pony.tags) {
    databuf.append(tag[0].toUpperCase());
    databuf.append("String_Node_Str");
    databuf.append(tag[1]);
  }
  if (pony.comment != null) {
    if ((pony.tags != null) && (pony.tags.length != 0))     databuf.append('\n');
    String comment='\n' + pony.comment.trim() + '\n';
    while (comment.contains("String_Node_Str"))     comment=comment.replace("String_Node_Str","String_Node_Str");
    comment=comment.substring(1,comment.length() - 1);
    databuf.append(comment);
  }
  if ((pony.tags != null) || (pony.comment != null))   databuf.append("String_Node_Str");
  if (this.ignoreballoon)   for (  Pony.Meta[][] row : metamatrix)   for (  Pony.Meta[] cell : row)   if (cell != null)   for (int i=0, n=cell.length; i < n; i++)   if ((cell[i] != null) && (cell[i] instanceof Pony.Balloon))   row[i]=null;
  if (this.ignorelink)   for (  Pony.Cell[] row : matrix)   for (int i=0, n=row.length; i < n; i++) {
    Pony.Cell cell;
    if ((cell=row[i]) != null)     if (this.ignorelink && ((cell.character == Pony.Cell.NNE_SSW) || (cell.character == Pony.Cell.NNW_SSE)))     row[i]=new Pony.Cell(' ',null,null,plain);
 else {
      Color back=((cell.lowerColour == null) || (cell.lowerColour.getAlpha() < 112)) ? null : cell.lowerColour;
      Color fore=((cell.upperColour == null) || (cell.upperColour.getAlpha() < 112)) ? null : cell.upperColour;
      row[i]=new Pony.Cell(cell.character,back,fore,cell.format);
    }
  }
  if (this.left >= 0) {
    int cur=0;
    outer:     for (int n=matrix[0].length; cur < n; cur++)     for (int j=0, m=matrix.length; j < m; j++) {
      boolean cellpass=true;
      Pony.Cell cell=matrix[j][cur];
      if (cell != null)       if ((cell.character != ' ') || (cell.lowerColour != null))       if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))       cellpass=false;
      if (cellpass == false) {
        Pony.Meta[] meta=metamatrix[j][cur];
        if ((meta != null) && (meta.length != 0)) {
          for (int k=0, l=meta.length; k < l; k++)           if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))           break outer;
        }
 else         break outer;
      }
    }
    this.left-=cur;
  }
 else   this.left=0;
  if (this.right >= 0) {
    int cur=0;
    outer:     for (int n=matrix[0].length - 1; cur <= n; cur++)     for (int j=0, m=matrix.length; j < m; j++) {
      boolean cellpass=true;
      Pony.Cell cell=matrix[j][n - cur];
      if (cell != null)       if ((cell.character != ' ') || (cell.lowerColour != null))       if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))       cellpass=false;
      if (cellpass == false) {
        Pony.Meta[] meta=metamatrix[j][n - cur];
        if ((meta != null) && (meta.length != 0)) {
          for (int k=0, l=meta.length; k < l; k++)           if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))           break outer;
        }
 else         break outer;
      }
    }
    this.right-=cur;
  }
 else   this.right=0;
  if (this.top >= 0) {
    int cur=0, m=matrix[0].length - this.right;
    outer:     for (int n=matrix.length; cur < n; cur++) {
      Pony.Cell[] row=matrix[cur];
      Pony.Meta[][] metarow=metamatrix[cur];
      for (int j=this.left; j < m; j++) {
        boolean cellpass=true;
        Pony.Cell cell=row[j];
        if (cell != null)         if ((cell.character != ' ') || (cell.lowerColour != null))         if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))         cellpass=false;
        if (cellpass == false) {
          Pony.Meta[] meta=metarow[j];
          if ((meta != null) && (meta.length != 0)) {
            for (int k=0, l=meta.length; k < l; k++)             if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))             break outer;
          }
 else           break outer;
        }
      }
    }
    this.top-=cur;
  }
 else   this.top=0;
  if (this.bottom >= 0) {
    int cur=0, m=matrix[0].length - this.right;
    outer:     for (int n=matrix.length - 1 - this.top; cur <= n; cur++) {
      Pony.Cell[] row=matrix[n - cur];
      Pony.Meta[][] metarow=metamatrix[n - cur];
      for (int j=this.left; j < m; j++) {
        boolean cellpass=true;
        Pony.Cell cell=row[j];
        if (cell != null)         if ((cell.character != ' ') || (cell.lowerColour != null))         if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))         cellpass=false;
        if (cellpass == false) {
          Pony.Meta[] meta=metarow[j];
          if ((meta != null) && (meta.length != 0)) {
            for (int k=0, l=meta.length; k < l; k++)             if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))             break outer;
          }
 else           break outer;
        }
      }
    }
    this.bottom-=cur;
  }
 else   this.bottom=0;
  if (this.left > 0) {
    int w=matrix[0].length;
    for (int y=0, h=matrix.length; y < h; y++) {
      System.arraycopy(matrix[y],this.left,matrix[y]=new Pony.Cell[w + this.left],0,w);
      System.arraycopy(metamatrix[y],this.left,metamatrix[y]=new Pony.Meta[w + 1 + this.left][],0,w + 1);
    }
    this.left=0;
  }
 else   this.left=-this.left;
  if (this.right > 0) {
    int w=matrix[0].length;
    for (int y=0, h=matrix.length; y < h; y++) {
      System.arraycopy(matrix[y],0,matrix[y]=new Pony.Cell[w + this.right],0,w);
      System.arraycopy(metamatrix[y],0,metamatrix[y]=new Pony.Meta[w + 1 + this.right][],0,w + 1);
    }
    this.right=0;
  }
 else   this.right=-this.right;
  if (this.top > 0) {
    int h=matrix.length, w=matrix[0].length;
    Pony.Cell[][] appendix=new Pony.Cell[this.top][w];
    System.arraycopy(matrix,this.top,matrix=new Pony.Cell[h + this.top][],0,h);
    System.arraycopy(matrix,0,appendix,0,this.top);
    Pony.Meta[][][] metaappendix=new Pony.Meta[this.top][][];
    System.arraycopy(metamatrix,this.top,metamatrix=new Pony.Meta[h + this.top][w + 1][],0,h);
    System.arraycopy(metamatrix,0,metaappendix,0,this.top);
    this.top=0;
  }
 else   this.top=-this.top;
  if (this.bottom > 0) {
    int h=matrix.length, w=matrix[0].length;
    Pony.Cell[][] appendix=new Pony.Cell[this.bottom][w];
    System.arraycopy(matrix,0,matrix=new Pony.Cell[h + this.bottom][],0,h);
    System.arraycopy(matrix,h,appendix,0,this.bottom);
    Pony.Meta[][][] metaappendix=new Pony.Meta[this.bottom][w + 1][];
    System.arraycopy(metamatrix,0,metamatrix=new Pony.Meta[h + this.bottom][][],0,h);
    System.arraycopy(metamatrix,h,metaappendix,0,this.bottom);
    this.bottom=0;
  }
 else   this.bottom=-this.bottom;
  for (int y=0; y < this.top; y++) {
    Pony.Meta[][] metarow=metamatrix[y];
    for (int x=0, w=metarow.length; x < w; x++) {
      Pony.Meta[] metacell=metarow[x];
      for (int z=0, d=metacell.length; z < d; z++) {
        Pony.Meta metaelem;
        if (((metaelem=metacell[z]) != null) && (metaelem instanceof Pony.Store))         databuf.append("String_Node_Str" + (((Pony.Store)(metaelem)).name + "String_Node_Str" + ((Pony.Store)(metaelem)).value).replace("String_Node_Str","String_Node_Str") + "String_Node_Str");
      }
    }
  }
  if (this.right != 0) {
    int w=matrix[0].length, r=metamatrix[0].length - this.right;
    Pony.Meta[] leftovers=new Pony.Meta[32];
    for (int y=this.top, h=matrix.length - this.bottom; y < h; y++) {
      int ptr=0;
      Pony.Meta[][] metarow=metamatrix[y];
      for (int x=r; x <= w; x++)       if (metarow[x] != null)       for (      Pony.Meta meta : metarow[x])       if ((meta != null) && (meta instanceof Pony.Store)) {
        if (ptr == leftovers.length)         System.arraycopy(leftovers,0,leftovers=new Pony.Meta[ptr << 1],0,ptr);
        leftovers[ptr++]=meta;
      }
      if (ptr != 0) {
        Pony.Meta[] metacell=metarow[r];
        System.arraycopy(metacell,0,metarow[r]=metacell=new Pony.Meta[metacell.length + ptr],0,metacell.length - ptr);
        System.arraycopy(leftovers,0,metacell,metacell.length - ptr,ptr);
      }
      System.arraycopy(matrix[y],0,matrix[y]=new Pony.Cell[w - this.right],0,w - this.right);
      System.arraycopy(metarow,0,metamatrix[y]=new Pony.Meta[w - this.right + 1][],0,w - this.right + 1);
    }
  }
  int[] endings=null;
  if (this.even == false) {
    int w=matrix[0].length;
    endings=new int[matrix.length];
    for (int y=0, h=matrix.length; y < h; y++) {
      Pony.Cell[] row=matrix[y];
      Pony.Meta[][] metarow=metamatrix[y];
      int cur=0;
      mid:       for (int n=w - 1; cur <= n; cur++) {
        boolean cellpass=true;
        Pony.Cell cell=row[n - cur];
        if (cell != null)         if ((cell.character != ' ') || (cell.lowerColour != null))         if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))         cellpass=false;
        if (cellpass == false) {
          Pony.Meta[] meta=metarow[n - cur];
          if ((meta != null) && (meta.length != 0)) {
            for (int k=0, l=meta.length; k < l; k++)             if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))             break mid;
          }
 else           break mid;
        }
      }
      endings[y]=w - cur;
    }
  }
  Pony.Cell defaultcell=new Pony.Cell(' ',null,null,plain);
  for (int y=this.top, h=matrix.length - this.bottom; y < h; y++) {
    Pony.Cell[] row=matrix[y];
    Pony.Meta[][] metarow=metamatrix[y];
    int ending=endings == null ? row.length : endings[y];
    for (int x=0, w=row.length; x <= w; x++) {
      Pony.Meta[] metacell=metarow[row.length];
      if (metacell != null)       for (int z=0, d=metacell.length; z < d; z++) {
        Pony.Meta meta=metacell[z];
        if ((meta != null) && ((x >= this.left) || (meta instanceof Pony.Store))) {
          Class<?> metaclass=meta.getClass();
          if (metaclass == Pony.Store.class)           databuf.append("String_Node_Str" + (((Pony.Store)meta).name + "String_Node_Str" + ((Pony.Store)meta).value).replace("String_Node_Str","String_Node_Str") + "String_Node_Str");
 else           if (metaclass == Pony.Recall.class) {
            Pony.Recall recall=(Pony.Recall)meta;
            Color back=((recall.backgroundColour == null) || (recall.backgroundColour.getAlpha() < 112)) ? null : recall.backgroundColour;
            Color fore=((recall.foregroundColour == null) || (recall.foregroundColour.getAlpha() < 112)) ? null : recall.foregroundColour;
            databuf.append(applyColour(colours,background,foreground,format,background=back,foreground=fore,recall.format));
            databuf.append("String_Node_Str" + recall.name.replace("String_Node_Str","String_Node_Str") + "String_Node_Str");
          }
 else           if (metaclass == Pony.Balloon.class) {
            databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=null,format=plain));
            Pony.Balloon balloon=(Pony.Balloon)meta;
            if (balloon.left != null) {
              int justification=balloon.minWidth != null ? balloon.justification & (Pony.Balloon.LEFT | Pony.Balloon.RIGHT) : Pony.Balloon.NONE;
switch (justification) {
case Pony.Balloon.NONE:
                char[] spaces=new char[balloon.left.intValue()];
              Arrays.fill(spaces,' ');
            databuf.append(new String(spaces));
          databuf.append("String_Node_Str" + balloon.left.intValue());
        break;
case Pony.Balloon.LEFT:
      databuf.append("String_Node_Str" + balloon.left.intValue() + "String_Node_Str");
    databuf.append(balloon.left.intValue() + balloon.minWidth.intValue() - 1);
  break;
case Pony.Balloon.RIGHT:
databuf.append("String_Node_Str" + balloon.left.intValue() + "String_Node_Str");
databuf.append(balloon.left.intValue() + balloon.minWidth.intValue() - 1);
break;
default :
databuf.append("String_Node_Str" + balloon.left.intValue() + "String_Node_Str");
databuf.append(balloon.left.intValue() + balloon.minWidth.intValue() - 1);
break;
}
}
 else if (balloon.minWidth != null) databuf.append("String_Node_Str" + balloon.minWidth.toString());
if (balloon.minHeight != null) databuf.append("String_Node_Str" + balloon.minHeight.toString());
databuf.append("String_Node_Str");
}
}
}
if ((x != w) && (x >= this.left) && (x < ending)) {
Pony.Cell cell=row[x];
if (cell == null) cell=defaultcell;
if (cell.character >= 0) {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=cell.upperColour,format=cell.format));
databuf.append(cell.character);
}
 else if (cell.character == Pony.Cell.NNE_SSW) {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=null,format=plain));
databuf.append("String_Node_Str");
}
 else if (cell.character == Pony.Cell.NNW_SSE) {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=null,format=plain));
databuf.append("String_Node_Str");
}
 else if (cell.character == Pony.Cell.PIXELS) if (cell.lowerColour == null) if (cell.upperColour == null) {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=this.spacesave ? foreground : null,format=plain));
databuf.append(' ');
}
 else {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=cell.upperColour,format=plain));
databuf.append('▀');
}
 else if (cell.upperColour == null) {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=null,format=plain));
databuf.append('▀');
}
 else if (cell.upperColour.equals(cell.lowerColour)) if (this.zebra) {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=cell.lowerColour,format=plain));
databuf.append('▄');
}
 else if (this.fullblocks) {
databuf.append(applyColour(colours,background,foreground,format,background=this.spacesave ? background : cell.lowerColour,foreground=cell.lowerColour,format=plain));
databuf.append('█');
}
 else {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=this.spacesave ? foreground : cell.lowerColour,format=plain));
databuf.append(' ');
}
 else {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=cell.upperColour,format=plain));
databuf.append('▄');
}
}
}
background=foreground=null;
format=plain;
databuf.append("String_Node_Str");
}
String data=databuf.toString();
if (this.version == VERSION_COWSAY) {
String metadata=null;
if (data.startsWith("String_Node_Str")) {
metadata=data.substring(4);
if (metadata.startsWith("String_Node_Str")) metadata=null;
 else {
metadata=metadata.substring(0,metadata.indexOf("String_Node_Str") + 5);
data=data.substring(data.indexOf("String_Node_Str") + 5);
metadata='#' + metadata.replace("String_Node_Str","String_Node_Str");
}
}
String eop="String_Node_Str";
while (data.contains(eop + '\n')) eop+='P';
data=data.replace("String_Node_Str","String_Node_Str").replace("String_Node_Str","String_Node_Str");
while (data.contains("String_Node_Str")) {
int start=data.indexOf("String_Node_Str");
int end=data.indexOf("String_Node_Str",start + 8);
data=data.substring(0,start) + data.substring(end + 1);
}
data="String_Node_Str" + eop + "String_Node_Str"+ data;
data+=eop + '\n';
if (metadata != null) data=metadata + data;
if (this.utf8 == false) data=data.replace("String_Node_Str","String_Node_Str").replace("String_Node_Str","String_Node_Str");
}
 else {
if (this.version < VERSION_METADATA) {
if (data.startsWith("String_Node_Str")) data=data.substring(data.indexOf("String_Node_Str") + 5);
}
if (this.version < VERSION_HORIZONTAL_JUSTIFICATION) {
databuf=new StringBuilder();
int pos=data.indexOf("String_Node_Str");
pos+=pos < 0 ? 1 : 5;
databuf.append(data.substring(0,pos));
StringBuilder dollarbuf=null;
boolean esc=false;
for (int i=0, n=data.length(); i < n; ) {
char c=data.charAt(i++);
if (dollarbuf != null) {
dollarbuf.append(c);
if (esc || (c == '\033')) esc^=true;
 else if (c == '$') {
String dollar=dollarbuf.toString();
dollarbuf=null;
if (dollar.startsWith("String_Node_Str") == false) databuf.append(dollar);
 else {
databuf.append("String_Node_Str");
dollar=dollar.substring(8);
if (dollar.contains("String_Node_Str")) dollar=dollar.substring(dollar.indexOf('l') + 1);
 else if (dollar.contains("String_Node_Str")) dollar=dollar.substring(dollar.indexOf('r') + 1);
 else if (dollar.contains("String_Node_Str")) dollar=dollar.substring(dollar.indexOf('c') + 1);
databuf.append(dollar);
}
}
}
 else if (c == '$') dollarbuf=new StringBuilder("String_Node_Str");
 else databuf.append(c);
}
data=databuf.toString();
}
}
if (resetpalette != null) data+=resetpalette.toString();
if (this.escesc) data=data.replace("String_Node_Str","String_Node_Str");
OutputStream out=System.out;
if (this.file != null) out=new FileOutputStream(this.file);
out.write(data.getBytes("String_Node_Str"));
out.flush();
if (out != System.out) out.close();
}

Fixed version (ground truth):
/** 
 * Export a pony to the file
 * @param pony  The pony
 * @throws IOException  On I/O error
 */
public void exportPony(Pony pony) throws IOException {
  Color[] colours=new Color[256];
  boolean[] format=new boolean[9];
  Color background=null, foreground=null;
  for (int i=0; i < 256; i++) {
    Colour colour=new Colour(i);
    colours[i]=new Color(colour.red,colour.green,colour.blue);
  }
  if (this.palette != null)   System.arraycopy(this.palette,0,colours,0,16);
  StringBuilder resetpalette=null;
  if (this.tty)   if (this.colourful) {
    resetpalette=new StringBuilder();
    for (int i=0; i < 16; i++) {
      Colour colour=new Colour(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append("String_Node_Str".charAt(i));
      resetpalette.append("String_Node_Str".charAt(colour.red >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.red & 15));
      resetpalette.append("String_Node_Str".charAt(colour.green >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.green & 15));
      resetpalette.append("String_Node_Str".charAt(colour.blue >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.blue & 15));
    }
  }
 else {
    resetpalette=new StringBuilder();
    for (    int i : new int[]{7,15}) {
      Colour colour=new Colour(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append("String_Node_Str".charAt(i));
      resetpalette.append("String_Node_Str".charAt(colour.red >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.red & 15));
      resetpalette.append("String_Node_Str".charAt(colour.green >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.green & 15));
      resetpalette.append("String_Node_Str".charAt(colour.blue >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.blue & 15));
    }
  }
 else   if (this.fullcolour) {
    resetpalette=new StringBuilder();
    for (int i=0; i < 16; i++) {
      Colour colour=new Colour(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append(i);
      resetpalette.append("String_Node_Str");
      resetpalette.append("String_Node_Str".charAt(colour.red >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.red & 15));
      resetpalette.append('/');
      resetpalette.append("String_Node_Str".charAt(colour.green >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.green & 15));
      resetpalette.append('/');
      resetpalette.append("String_Node_Str".charAt(colour.blue >>> 4));
      resetpalette.append("String_Node_Str".charAt(colour.blue & 15));
      resetpalette.append("String_Node_Str");
    }
  }
  StringBuilder databuf=new StringBuilder();
  int curleft=0, curright=0, curtop=0, curbottom=0;
  Pony.Cell[][] matrix=pony.matrix;
  Pony.Meta[][][] metamatrix=pony.metamatrix;
  boolean[] PLAIN=new boolean[9];
  if ((pony.tags != null) || (pony.comment != null))   databuf.append("String_Node_Str");
  if (pony.tags != null)   for (  String[] tag : pony.tags) {
    databuf.append(tag[0].toUpperCase());
    databuf.append("String_Node_Str");
    databuf.append(tag[1]);
  }
  if (pony.comment != null) {
    if ((pony.tags != null) && (pony.tags.length != 0))     databuf.append('\n');
    String comment='\n' + pony.comment.trim() + '\n';
    while (comment.contains("String_Node_Str"))     comment=comment.replace("String_Node_Str","String_Node_Str");
    comment=comment.substring(1,comment.length() - 1);
    databuf.append(comment);
  }
  if ((pony.tags != null) || (pony.comment != null))   databuf.append("String_Node_Str");
  if (this.ignoreballoon)   for (  Pony.Meta[][] row : metamatrix)   for (  Pony.Meta[] cell : row)   if (cell != null)   for (int i=0, n=cell.length; i < n; i++)   if ((cell[i] != null) && (cell[i] instanceof Pony.Balloon))   row[i]=null;
  if (this.ignorelink)   for (  Pony.Cell[] row : matrix)   for (int i=0, n=row.length; i < n; i++) {
    Pony.Cell cell;
    if ((cell=row[i]) != null)     if (this.ignorelink && ((cell.character == Pony.Cell.NNE_SSW) || (cell.character == Pony.Cell.NNW_SSE)))     row[i]=new Pony.Cell(' ',null,null,PLAIN);
 else {
      Color back=((cell.lowerColour == null) || (cell.lowerColour.getAlpha() < 112)) ? null : cell.lowerColour;
      Color fore=((cell.upperColour == null) || (cell.upperColour.getAlpha() < 112)) ? null : cell.upperColour;
      row[i]=new Pony.Cell(cell.character,back,fore,cell.format);
    }
  }
  if (this.left >= 0) {
    int cur=0;
    outer:     for (int n=matrix[0].length; cur < n; cur++)     for (int j=0, m=matrix.length; j < m; j++) {
      boolean cellpass=true;
      Pony.Cell cell=matrix[j][cur];
      if (cell != null)       if ((cell.character != ' ') || (cell.lowerColour != null))       if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))       cellpass=false;
      if (cellpass == false) {
        Pony.Meta[] meta=metamatrix[j][cur];
        if ((meta != null) && (meta.length != 0)) {
          for (int k=0, l=meta.length; k < l; k++)           if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))           break outer;
        }
 else         break outer;
      }
    }
    this.left-=cur;
  }
 else   this.left=0;
  if (this.right >= 0) {
    int cur=0;
    outer:     for (int n=matrix[0].length - 1; cur <= n; cur++)     for (int j=0, m=matrix.length; j < m; j++) {
      boolean cellpass=true;
      Pony.Cell cell=matrix[j][n - cur];
      if (cell != null)       if ((cell.character != ' ') || (cell.lowerColour != null))       if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))       cellpass=false;
      if (cellpass == false) {
        Pony.Meta[] meta=metamatrix[j][n - cur];
        if ((meta != null) && (meta.length != 0)) {
          for (int k=0, l=meta.length; k < l; k++)           if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))           break outer;
        }
 else         break outer;
      }
    }
    this.right-=cur;
  }
 else   this.right=0;
  if (this.top >= 0) {
    int cur=0, m=matrix[0].length - this.right;
    outer:     for (int n=matrix.length; cur < n; cur++) {
      Pony.Cell[] row=matrix[cur];
      Pony.Meta[][] metarow=metamatrix[cur];
      for (int j=this.left; j < m; j++) {
        boolean cellpass=true;
        Pony.Cell cell=row[j];
        if (cell != null)         if ((cell.character != ' ') || (cell.lowerColour != null))         if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))         cellpass=false;
        if (cellpass == false) {
          Pony.Meta[] meta=metarow[j];
          if ((meta != null) && (meta.length != 0)) {
            for (int k=0, l=meta.length; k < l; k++)             if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))             break outer;
          }
 else           break outer;
        }
      }
    }
    this.top-=cur;
  }
 else   this.top=0;
  if (this.bottom >= 0) {
    int cur=0, m=matrix[0].length - this.right;
    outer:     for (int n=matrix.length - 1 - this.top; cur <= n; cur++) {
      Pony.Cell[] row=matrix[n - cur];
      Pony.Meta[][] metarow=metamatrix[n - cur];
      for (int j=this.left; j < m; j++) {
        boolean cellpass=true;
        Pony.Cell cell=row[j];
        if (cell != null)         if ((cell.character != ' ') || (cell.lowerColour != null))         if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))         cellpass=false;
        if (cellpass == false) {
          Pony.Meta[] meta=metarow[j];
          if ((meta != null) && (meta.length != 0)) {
            for (int k=0, l=meta.length; k < l; k++)             if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))             break outer;
          }
 else           break outer;
        }
      }
    }
    this.bottom-=cur;
  }
 else   this.bottom=0;
  if (this.left > 0) {
    int w=matrix[0].length;
    for (int y=0, h=matrix.length; y < h; y++) {
      System.arraycopy(matrix[y],0,matrix[y]=new Pony.Cell[w + this.left],this.left,w);
      System.arraycopy(metamatrix[y],0,metamatrix[y]=new Pony.Meta[w + 1 + this.left][],this.left,w + 1);
    }
    this.left=0;
  }
 else   this.left=-this.left;
  if (this.right > 0) {
    int w=matrix[0].length;
    for (int y=0, h=matrix.length; y < h; y++) {
      System.arraycopy(matrix[y],0,matrix[y]=new Pony.Cell[w + this.right],0,w);
      System.arraycopy(metamatrix[y],0,metamatrix[y]=new Pony.Meta[w + 1 + this.right][],0,w + 1);
    }
    this.right=0;
  }
 else   this.right=-this.right;
  if (this.top > 0) {
    int h=matrix.length, w=matrix[0].length;
    Pony.Cell[][] appendix=new Pony.Cell[this.top][w];
    System.arraycopy(matrix,0,matrix=new Pony.Cell[h + this.top][],this.top,h);
    System.arraycopy(appendix,0,matrix,0,this.top);
    Pony.Meta[][][] metaappendix=new Pony.Meta[this.top][w + 1][];
    System.arraycopy(metamatrix,0,metamatrix=new Pony.Meta[h + this.top][w + 1][],this.top,h);
    System.arraycopy(metaappendix,0,metamatrix,0,this.top);
    this.top=0;
  }
 else   this.top=-this.top;
  if (this.bottom > 0) {
    int h=matrix.length, w=matrix[0].length;
    Pony.Cell[][] appendix=new Pony.Cell[this.bottom][w];
    System.arraycopy(matrix,0,matrix=new Pony.Cell[h + this.bottom][],0,h);
    System.arraycopy(appendix,0,matrix,h,this.bottom);
    Pony.Meta[][][] metaappendix=new Pony.Meta[this.bottom][w + 1][];
    System.arraycopy(metamatrix,0,metamatrix=new Pony.Meta[h + this.bottom][][],0,h);
    System.arraycopy(metaappendix,0,metamatrix,h,this.bottom);
    this.bottom=0;
  }
 else   this.bottom=-this.bottom;
  for (int y=0; y < this.top; y++) {
    Pony.Meta[][] metarow=metamatrix[y];
    for (int x=0, w=metarow.length; x < w; x++) {
      Pony.Meta[] metacell=metarow[x];
      for (int z=0, d=metacell.length; z < d; z++) {
        Pony.Meta metaelem;
        if (((metaelem=metacell[z]) != null) && (metaelem instanceof Pony.Store))         databuf.append("String_Node_Str" + (((Pony.Store)(metaelem)).name + "String_Node_Str" + ((Pony.Store)(metaelem)).value).replace("String_Node_Str","String_Node_Str") + "String_Node_Str");
      }
    }
  }
  if (this.right != 0) {
    int w=matrix[0].length, r=metamatrix[0].length - this.right;
    Pony.Meta[] leftovers=new Pony.Meta[32];
    for (int y=this.top, h=matrix.length - this.bottom; y < h; y++) {
      int ptr=0;
      Pony.Meta[][] metarow=metamatrix[y];
      for (int x=r; x <= w; x++)       if (metarow[x] != null)       for (      Pony.Meta meta : metarow[x])       if ((meta != null) && (meta instanceof Pony.Store)) {
        if (ptr == leftovers.length)         System.arraycopy(leftovers,0,leftovers=new Pony.Meta[ptr << 1],0,ptr);
        leftovers[ptr++]=meta;
      }
      if (ptr != 0) {
        Pony.Meta[] metacell=metarow[r];
        System.arraycopy(metacell,0,metarow[r]=metacell=new Pony.Meta[metacell.length + ptr],0,metacell.length - ptr);
        System.arraycopy(leftovers,0,metacell,metacell.length - ptr,ptr);
      }
      System.arraycopy(matrix[y],0,matrix[y]=new Pony.Cell[w - this.right],0,w - this.right);
      System.arraycopy(metarow,0,metamatrix[y]=new Pony.Meta[w - this.right + 1][],0,w - this.right + 1);
    }
  }
  int[] endings=null;
  if (this.even == false) {
    int w=matrix[0].length;
    endings=new int[matrix.length];
    for (int y=0, h=matrix.length; y < h; y++) {
      Pony.Cell[] row=matrix[y];
      Pony.Meta[][] metarow=metamatrix[y];
      int cur=0;
      mid:       for (int n=w - 1; cur <= n; cur++) {
        boolean cellpass=true;
        Pony.Cell cell=row[n - cur];
        if (cell != null)         if ((cell.character != ' ') || (cell.lowerColour != null))         if ((cell.character != Pony.Cell.PIXELS) || (cell.lowerColour != null) || (cell.upperColour != null))         cellpass=false;
        if (cellpass == false) {
          Pony.Meta[] meta=metarow[n - cur];
          if ((meta != null) && (meta.length != 0)) {
            for (int k=0, l=meta.length; k < l; k++)             if ((meta[k] != null) && ((meta[k] instanceof Pony.Store) == false))             break mid;
          }
 else           break mid;
        }
      }
      endings[y]=w - cur;
    }
  }
  Pony.Cell defaultcell=new Pony.Cell(' ',null,null,PLAIN);
  for (int y=this.top, h=matrix.length - this.bottom; y < h; y++) {
    Pony.Cell[] row=matrix[y];
    Pony.Meta[][] metarow=metamatrix[y];
    int ending=endings == null ? row.length : endings[y];
    for (int x=0, w=row.length; x <= w; x++) {
      Pony.Meta[] metacell=metarow[x];
      if (metacell != null)       for (int z=0, d=metacell.length; z < d; z++) {
        Pony.Meta meta=metacell[z];
        if ((meta != null) && ((x >= this.left) || (meta instanceof Pony.Store))) {
          Class<?> metaclass=meta.getClass();
          if (metaclass == Pony.Store.class)           databuf.append("String_Node_Str" + (((Pony.Store)meta).name + "String_Node_Str" + ((Pony.Store)meta).value).replace("String_Node_Str","String_Node_Str") + "String_Node_Str");
 else           if (metaclass == Pony.Recall.class) {
            Pony.Recall recall=(Pony.Recall)meta;
            Color back=((recall.backgroundColour == null) || (recall.backgroundColour.getAlpha() < 112)) ? null : recall.backgroundColour;
            Color fore=((recall.foregroundColour == null) || (recall.foregroundColour.getAlpha() < 112)) ? null : recall.foregroundColour;
            databuf.append(applyColour(colours,background,foreground,format,background=back,foreground=fore,recall.format));
            databuf.append("String_Node_Str" + recall.name.replace("String_Node_Str","String_Node_Str") + "String_Node_Str");
          }
 else           if (metaclass == Pony.Balloon.class) {
            databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=null,format=PLAIN));
            Pony.Balloon balloon=(Pony.Balloon)meta;
            if (balloon.left != null) {
              int justification=balloon.minWidth != null ? balloon.justification & (Pony.Balloon.LEFT | Pony.Balloon.RIGHT) : Pony.Balloon.NONE;
switch (justification) {
case Pony.Balloon.NONE:
                char[] spaces=new char[balloon.left.intValue()];
              Arrays.fill(spaces,' ');
            databuf.append(new String(spaces));
          databuf.append("String_Node_Str" + balloon.left.intValue());
        break;
case Pony.Balloon.LEFT:
      databuf.append("String_Node_Str" + balloon.left.intValue() + "String_Node_Str");
    databuf.append(balloon.left.intValue() + balloon.minWidth.intValue() - 1);
  break;
case Pony.Balloon.RIGHT:
databuf.append("String_Node_Str" + balloon.left.intValue() + "String_Node_Str");
databuf.append(balloon.left.intValue() + balloon.minWidth.intValue() - 1);
break;
default :
databuf.append("String_Node_Str" + balloon.left.intValue() + "String_Node_Str");
databuf.append(balloon.left.intValue() + balloon.minWidth.intValue() - 1);
break;
}
}
 else if (balloon.minWidth != null) databuf.append("String_Node_Str" + balloon.minWidth.toString());
if (balloon.minHeight != null) databuf.append("String_Node_Str" + balloon.minHeight.toString());
databuf.append("String_Node_Str");
}
}
}
if ((x != w) && (x >= this.left) && (x < ending)) {
Pony.Cell cell=row[x];
if (cell == null) cell=defaultcell;
if (cell.character >= 0) {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=cell.upperColour,format=cell.format));
databuf.append(cell.character);
}
 else if (cell.character == Pony.Cell.NNE_SSW) {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=null,format=PLAIN));
databuf.append("String_Node_Str");
}
 else if (cell.character == Pony.Cell.NNW_SSE) {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=null,format=PLAIN));
databuf.append("String_Node_Str");
}
 else if (cell.character == Pony.Cell.PIXELS) if (cell.lowerColour == null) if (cell.upperColour == null) {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=this.spacesave ? foreground : null,format=PLAIN));
databuf.append(' ');
}
 else {
databuf.append(applyColour(colours,background,foreground,format,background=null,foreground=cell.upperColour,format=PLAIN));
databuf.append('▀');
}
 else if (cell.upperColour == null) {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=null,format=PLAIN));
databuf.append('▀');
}
 else if (cell.upperColour.equals(cell.lowerColour)) if (this.zebra) {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=cell.lowerColour,format=PLAIN));
databuf.append('▄');
}
 else if (this.fullblocks) {
databuf.append(applyColour(colours,background,foreground,format,background=this.spacesave ? background : cell.lowerColour,foreground=cell.lowerColour,format=PLAIN));
databuf.append('█');
}
 else {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=this.spacesave ? foreground : cell.lowerColour,format=PLAIN));
databuf.append(' ');
}
 else {
databuf.append(applyColour(colours,background,foreground,format,background=cell.lowerColour,foreground=cell.upperColour,format=PLAIN));
databuf.append('▄');
}
}
}
background=foreground=null;
format=PLAIN;
databuf.append("String_Node_Str");
}
String data=databuf.toString();
if (this.version == VERSION_COWSAY) {
String metadata=null;
if (data.startsWith("String_Node_Str")) {
metadata=data.substring(4);
if (metadata.startsWith("String_Node_Str")) metadata=null;
 else {
metadata=metadata.substring(0,metadata.indexOf("String_Node_Str") + 5);
data=data.substring(data.indexOf("String_Node_Str") + 5);
metadata='#' + metadata.replace("String_Node_Str","String_Node_Str");
}
}
String eop="String_Node_Str";
while (data.contains(eop + '\n')) eop+='P';
data=data.replace("String_Node_Str","String_Node_Str").replace("String_Node_Str","String_Node_Str");
while (data.contains("String_Node_Str")) {
int start=data.indexOf("String_Node_Str");
int end=data.indexOf("String_Node_Str",start + 8);
data=data.substring(0,start) + data.substring(end + 1);
}
data="String_Node_Str" + eop + "String_Node_Str"+ data;
data+=eop + '\n';
if (metadata != null) data=metadata + data;
if (this.utf8 == false) data=data.replace("String_Node_Str","String_Node_Str").replace("String_Node_Str","String_Node_Str");
}
 else {
if (this.version < VERSION_METADATA) {
if (data.startsWith("String_Node_Str")) data=data.substring(data.indexOf("String_Node_Str") + 5);
}
if (this.version < VERSION_HORIZONTAL_JUSTIFICATION) {
databuf=new StringBuilder();
int pos=data.indexOf("String_Node_Str");
pos+=pos < 0 ? 1 : 5;
databuf.append(data.substring(0,pos));
StringBuilder dollarbuf=null;
boolean esc=false;
for (int i=0, n=data.length(); i < n; ) {
char c=data.charAt(i++);
if (dollarbuf != null) {
dollarbuf.append(c);
if (esc || (c == '\033')) esc^=true;
 else if (c == '$') {
String dollar=dollarbuf.toString();
dollarbuf=null;
if (dollar.startsWith("String_Node_Str") == false) databuf.append(dollar);
 else {
databuf.append("String_Node_Str");
dollar=dollar.substring(8);
if (dollar.contains("String_Node_Str")) dollar=dollar.substring(dollar.indexOf('l') + 1);
 else if (dollar.contains("String_Node_Str")) dollar=dollar.substring(dollar.indexOf('r') + 1);
 else if (dollar.contains("String_Node_Str")) dollar=dollar.substring(dollar.indexOf('c') + 1);
databuf.append(dollar);
}
}
}
 else if (c == '$') dollarbuf=new StringBuilder("String_Node_Str");
 else databuf.append(c);
}
data=databuf.toString();
}
}
if (resetpalette != null) data+=resetpalette.toString();
if (this.escesc) data=data.replace("String_Node_Str","String_Node_Str");
OutputStream out=System.out;
if (this.file != null) out=new FileOutputStream(this.file);
out.write(data.getBytes("String_Node_Str"));
out.flush();
if (out != System.out) out.close();
}