gt: 			for (int i = 0; i < elementCount; i++) {
context: /*
   *  Freeplane - mind map editor
   *  Copyright (C) 2008 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitry Polivaev
   *
   *  This file is created by Dimitry Polivaev in 2008.
   *
   *  This program is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation, either version 2 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package org.freeplane.features.clipboard.mindmapmode;
  
  import java.awt.Image;
  import java.awt.datatransfer.DataFlavor;
  import java.awt.datatransfer.Transferable;
  import java.awt.datatransfer.UnsupportedFlavorException;
  import java.awt.dnd.DnDConstants;
  import java.awt.image.BufferedImage;
  import java.io.File;
  import java.io.IOException;
  import java.io.StringReader;
  import java.io.StringWriter;
  import java.io.Writer;
  import java.net.URI;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  import javax.swing.JFileChooser;
  import javax.swing.JOptionPane;
  import javax.swing.text.BadLocationException;
  import javax.swing.text.Element;
  import javax.swing.text.ElementIterator;
  import javax.swing.text.html.HTMLDocument;
  import javax.swing.text.html.HTMLEditorKit;
  
  import org.apache.commons.lang.StringUtils;
  import org.freeplane.core.resources.ResourceController;
  import org.freeplane.core.ui.ExampleFileFilter;
  import org.freeplane.core.ui.components.UITools;
  import org.freeplane.core.util.FileUtils;
  import org.freeplane.core.util.FixedHTMLWriter;
  import org.freeplane.core.util.HtmlUtils;
  import org.freeplane.core.util.LogUtils;
  import org.freeplane.core.util.TextUtils;
  import org.freeplane.features.attribute.AttributeController;
  import org.freeplane.features.clipboard.ClipboardController;
  import org.freeplane.features.clipboard.MindMapNodesSelection;
  import org.freeplane.features.link.LinkController;
  import org.freeplane.features.link.NodeLinks;
  import org.freeplane.features.link.mindmapmode.MLinkController;
  import org.freeplane.features.map.CloneEncryptedNodeException;
  import org.freeplane.features.map.FreeNode;
  import org.freeplane.features.map.IMapSelection;
  import org.freeplane.features.map.MapModel;
  import org.freeplane.features.map.MapReader;
  import org.freeplane.features.map.MapReader.NodeTreeCreator;
  import org.freeplane.features.map.MapWriter.Hint;
  import org.freeplane.features.map.MapWriter.Mode;
  import org.freeplane.features.map.NodeModel;
  import org.freeplane.features.map.mindmapmode.MMapController;
  import org.freeplane.features.map.mindmapmode.SummaryGroupEdgeListAdder;
  import org.freeplane.features.mode.Controller;
  import org.freeplane.features.mode.ModeController;
  import org.freeplane.features.text.TextController;
  import org.freeplane.features.text.mindmapmode.MTextController;
  import org.freeplane.features.url.UrlManager;
  import org.freeplane.n3.nanoxml.XMLException;
  import org.freeplane.view.swing.features.filepreview.ImageAdder;
  import org.freeplane.view.swing.features.filepreview.ViewerController;
  import org.freeplane.view.swing.features.filepreview.ViewerController.PasteMode;
  
  /**
   * @author Dimitry Polivaev
   */
  public class MClipboardController extends ClipboardController {
  	public static final String RESOURCES_REMIND_USE_RICH_TEXT_IN_NEW_NODES = "remind_use_rich_text_in_new_nodes";
  	private class DirectHtmlFlavorHandler implements IDataFlavorHandler {
  		private String textFromClipboard;
  
  		public DirectHtmlFlavorHandler(final String textFromClipboard) {
  			this.textFromClipboard = textFromClipboard;
  		}
  
  		void paste(final NodeModel target) {
  			textFromClipboard = cleanHtml(textFromClipboard);
  			final NodeModel node = Controller.getCurrentModeController().getMapController().newNode(textFromClipboard,
  					Controller.getCurrentController().getMap());
  			final String text = textFromClipboard;
  			final Matcher m = HREF_PATTERN.matcher(text);
  			if (m.matches()) {
  				final String body = m.group(2);
  				if (!body.matches(".*<\\s*a.*")) {
  					final String href = m.group(1);
  					((MLinkController) LinkController.getController()).setLinkTypeDependantLink(node, href);
  				}
  			}
  			((MMapController) Controller.getCurrentModeController().getMapController()).insertNode(node, target);
  		}
  
  		public void paste(Transferable t, final NodeModel target, final boolean asSibling, final boolean isLeft, int dropAction) {
  			paste(target);
  		}
  	}
  
  	private class FileListFlavorHandler implements IDataFlavorHandler {
  		final List<File> fileList;
  
  		public FileListFlavorHandler(final List<File> fileList) {
  			super();
  			this.fileList = fileList;
  		}
  
  		public void paste(Transferable t, final NodeModel target, final boolean asSibling, final boolean isLeft, int dropAction) {
  	        if (LinkController.getLinkType() == LinkController.LINK_RELATIVE_TO_MINDMAP && target.getMap().getFile() == null) {
  	        	JOptionPane.showMessageDialog(Controller.getCurrentController().getViewController().getCurrentRootComponent(),
  	        	    TextUtils.getText("map_not_saved"), "Freeplane", JOptionPane.WARNING_MESSAGE);
  	        	return;
  	        }
  			boolean pasteImages = dropAction == DnDConstants.ACTION_COPY;
  			ViewerController viewerController = ((ViewerController)Controller.getCurrentModeController().getExtension(ViewerController.class));
  			for (final File file : fileList) {
  				if(pasteImages  && viewerController.paste(file, target, PasteMode.valueOf(asSibling), isLeft)){
  					continue;
  				}
  				final MMapController mapController = (MMapController) Controller.getCurrentModeController().getMapController();
  				final NodeModel node = mapController.newNode(file.getName(), target.getMap());
  				((MLinkController) LinkController.getController()).setLinkTypeDependantLink(node, file);
  				mapController.insertNode(node, target, asSibling, isLeft, isLeft);
  			}
  		}
  	}
  
  	interface IDataFlavorHandler {
  		void paste(Transferable t, NodeModel target, boolean asSibling, boolean isLeft, int dropAction);
  	}
  
  	private class MindMapNodesFlavorHandler implements IDataFlavorHandler {
  		private final String textFromClipboard;
  
  		public MindMapNodesFlavorHandler(final String textFromClipboard) {
  			this.textFromClipboard = textFromClipboard;
  		}
  
  		public void paste(Transferable t, final NodeModel target, final boolean asSibling, final boolean isLeft, int dropAction) {
  			if (textFromClipboard != null) {
  				paste(textFromClipboard, target, asSibling, isLeft);
  			}
  		}
  
  		private void paste(final String text, final NodeModel target, final boolean asSibling, final boolean isLeft) {
  			final String[] textLines = text.split(ClipboardController.NODESEPARATOR);
  			final MMapController mapController = (MMapController) Controller.getCurrentModeController().getMapController();
  			final MapReader mapReader = mapController.getMapReader();
  			final NodeTreeCreator nodeTreeCreator = mapReader.nodeTreeCreator(target.getMap());
  			nodeTreeCreator.setHint(Hint.MODE, Mode.CLIPBOARD);
  			for (int i = 0; i < textLines.length; ++i) {
  				try {
  					final NodeModel newModel = nodeTreeCreator.create(new StringReader(textLines[i]));
  					newModel.removeExtension(FreeNode.class);
  					final boolean wasLeft = newModel.isLeft();
  					mapController.insertNode(newModel, target, asSibling, isLeft, wasLeft != isLeft);
  				}
  				catch (final XMLException e) {
  					LogUtils.severe("error on paste", e);
  				}
  			}
  			nodeTreeCreator.finish(target);
  		}
  	}
  
  	private static class PasteHtmlWriter extends FixedHTMLWriter {
  		private final Element element;
  
  		public PasteHtmlWriter(final Writer writer, final Element element, final HTMLDocument doc, final int pos,
  		                       final int len) {
  			super(writer, doc, pos, len);
  			this.element = getStandAloneElement(element);
  		}
  
  		@Override
  		protected ElementIterator getElementIterator() {
  			return new ElementIterator(element);
  		}
  
  		private Element getStandAloneElement(final Element element) {
  			final String name = element.getName();
  			if (name.equals("ul") || name.equals("ol") || name.equals("table") || name.equals("html")) {
  				return element;
  			}
  			return getStandAloneElement(element.getParentElement());
  		}
  
  		@Override
  		public void write() throws IOException, BadLocationException {
  			if (element.getName().equals("html")) {
  				super.write();
  				return;
  			}
  			write("<html>");
  			super.write();
  			write("</html>");
  		}
  	}
  
  	private class StringFlavorHandler implements IDataFlavorHandler {
  		private final String textFromClipboard;
  
  		public StringFlavorHandler(final String textFromClipboard) {
  			this.textFromClipboard = textFromClipboard;
  		}
  
  		public void paste(Transferable t, final NodeModel target, final boolean asSibling, final boolean isLeft, int dropAction) {
  			final TextFragment[] textFragments = split(textFromClipboard);
  			pasteStringWithoutRedisplay(textFragments, target, asSibling, isLeft);
  		}
  
  		private TextFragment[] split(final String textFromClipboard) {
  			final LinkedList<TextFragment> textFragments = new LinkedList<TextFragment>();
  			final String[] textLines = textFromClipboard.split("\n");
  			for (int i = 0; i < textLines.length; ++i) {
  				String text = textLines[i];
  				text = text.replaceAll("\t", "        ");
  				if (text.matches(" *")) {
  					continue;
  				}
  				int depth = 0;
  				while (depth < text.length() && text.charAt(depth) == ' ') {
  					++depth;
  				}
  				final String visibleText = text.trim();
  				final String link = LinkController.findLink(text);
  				if (!visibleText.equals("")) {
  					textFragments.add(new TextFragment(visibleText, link, depth));
  				}
  			}
  			return textFragments.toArray(new TextFragment[textFragments.size()]);
  		}
  	}
  
  	private class StructuredHtmlFlavorHandler implements IDataFlavorHandler {
  		private final String textFromClipboard;
  
  		public StructuredHtmlFlavorHandler(final String textFromClipboard) {
  			this.textFromClipboard = textFromClipboard;
  		}
  
  		private String addFragment(final HTMLDocument doc, final Element element, final int depth, final int start,
  		                           final int end, final LinkedList<TextFragment> htmlFragments)
  		        throws BadLocationException, IOException {
  			final String paragraphText = doc.getText(start, end - start).trim();
  			if (paragraphText.length() > 0) {
  				final StringWriter out = new StringWriter();
  				new PasteHtmlWriter(out, element, doc, start, end - start).write();
  				final String string = out.toString();
  				if (!string.equals("")) {
  					final String link = LinkController.findLink(string);
  					final TextFragment htmlFragment = new TextFragment(string, link, depth);
  					htmlFragments.add(htmlFragment);
  				}
  			}
  			return paragraphText;
  		}
  
  		private Element getParentElement(final HTMLDocument doc) {
  			final Element htmlRoot = doc.getDefaultRootElement();
  			final Element bodyElement = htmlRoot.getElement(htmlRoot.getElementCount() - 1);
  			Element parentCandidate = bodyElement;
  			do {
  				if (parentCandidate.getElementCount() > 1) {
  					return parentCandidate;
  				}
  				parentCandidate = parentCandidate.getElement(0);
  			} while (!(parentCandidate.isLeaf() || parentCandidate.getName().equalsIgnoreCase("p-implied")));
  			return bodyElement;
  		}
  
  		private boolean isSeparateElement(final Element current) {
  			return !current.isLeaf();
  		}
  
  		public void paste(Transferable t, final NodeModel target, final boolean asSibling, final boolean isLeft, int dropAction) {
  			pasteHtmlWithoutRedisplay(textFromClipboard, target, asSibling, isLeft);
  		}
  
  		private void pasteHtmlWithoutRedisplay(final Object t, final NodeModel parent, final boolean asSibling,
  		                                       final boolean isLeft) {
  			String textFromClipboard = (String) t;
  			textFromClipboard = cleanHtml(textFromClipboard);
  			final TextFragment[] htmlFragments = split(textFromClipboard);
  			pasteStringWithoutRedisplay(htmlFragments, parent, asSibling, isLeft);
  		}
  
  		private void split(final HTMLDocument doc, final Element parent, final LinkedList<TextFragment> htmlFragments,
  		                   int depth) throws BadLocationException, IOException {
  			final int elementCount = parent.getElementCount();
  			int headerDepth = 0;
  			boolean headerFound = false;
  			int start = -1;
  			int end = -1;
  			Element last = null;
  