text:
package loon;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;

import loon.LGame.Location;
import loon.core.CallQueue;
import loon.core.event.Drawable;
import loon.core.event.Updateable;
import loon.core.geom.RectBox;
import loon.core.graphics.Screen;
import loon.core.graphics.device.LColor;
import loon.core.graphics.opengl.FrameBuffer;
import loon.core.graphics.opengl.GL;
import loon.core.graphics.opengl.LTexture;
import loon.core.graphics.opengl.LTexture.Format;
import loon.core.resource.ConfigReader;
import loon.core.resource.Resources;
import loon.core.timer.SystemTimer;
import loon.utils.MathUtils;
import loon.utils.StringUtils;
import loon.utils.collection.IntArray;

import android.app.Activity;
import android.os.Build;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;

public final class LSystem {

	static String _configFile = "assets/def.txt";

	static LConfig _config;

	public static LConfig getConfig() {
		synchronized (LConfig.class) {
			if (_config == null) {
				_config = new LConfig();
				_config.blend = GL.MODE_NORMAL;
				try {
					ConfigReader reader = ConfigReader.getInstance(_configFile);
					_config.autofilterColor = reader.getBoolValue(
							"auto_filter", false);
					_config.autofilterAll = reader.getBoolValue(
							"auto_filter_all", false);
					String result = reader.get("auto_colors_files");
					if (result == null) {
						_config.autofilterColor = false;
					} else {
						HashSet<String> list = new HashSet<String>(10);
						String[] files = StringUtils.split(result, ",");
						if (files.length > 0) {
							for (int i = 0; i < files.length; i++) {
								list.add(files[i]);
							}
							if (list.size() > 0) {
								_config.filterFiles = list
										.toArray(new String[0]);
							}
						}
					}
					result = reader.get("blend");
					if (result != null) {
						int mode = GL.MODE_NORMAL;
						if ("normal".equalsIgnoreCase(result)) {
							mode = GL.MODE_NORMAL;
						} else if ("alphamap".equalsIgnoreCase(result)) {
							mode = GL.MODE_ALPHA_MAP;
						} else if ("alphablend".equalsIgnoreCase(result)) {
							mode = GL.MODE_ALPHA_BLEND;
						} else if ("colormultiply".equalsIgnoreCase(result)) {
							mode = GL.MODE_COLOR_MULTIPLY;
						} else if ("add".equalsIgnoreCase(result)) {
							mode = GL.MODE_ADD;
						} else if ("screen".equalsIgnoreCase(result)) {
							mode = GL.MODE_SCREEN;
						} else if ("alpha".equalsIgnoreCase(result)) {
							mode = GL.MODE_ALPHA;
						} else if ("speed".equalsIgnoreCase(result)) {
							mode = GL.MODE_SPEED;
						} else if ("alphaone".equalsIgnoreCase(result)) {
							mode = GL.MODE_ALPHA_ONE;
						} else if ("none".equalsIgnoreCase(result)) {
							mode = GL.MODE_NONE;
						}
						_config.blend = mode;
					}
					result = reader.get("auto_filter_keywords");
					if (result != null) {
						_config.filterkeywords = StringUtils.split(result, ",");
					}
					result = reader.get("auto_colors");
					if (result == null) {
						_config.filterColors = new int[1];
						_config.filterColors[0] = LColor.black.getRGB();
					} else {
						String[] colors = StringUtils.split(result, ",");
						if (colors.length > 0) {
							IntArray ints = new IntArray();
							for (int i = 0; i < colors.length; i++) {
								String colorName = colors[i];
								if (MathUtils.isNan(colorName)) {
									ints.add(Double.valueOf(colorName)
											.intValue());
								} else {
									int color_int = LColor.black.getRGB();
									if (colorName.startsWith("#")
											|| colorName.startsWith("0")) {
										color_int = LColor.decode(colorName)
												.getRGB();
									} else {
										if (colorName.equalsIgnoreCase("red")) {
											color_int = LColor.red.getRGB();
										} else if (colorName
												.equalsIgnoreCase("white")) {
											color_int = LColor.white.getRGB();
										} else if (colorName
												.equalsIgnoreCase("blue")) {
											color_int = LColor.blue.getRGB();
										} else if (colorName
												.equalsIgnoreCase("gray")) {
											color_int = LColor.gray.getRGB();
										} else if (colorName
												.equalsIgnoreCase("yellow")) {
											color_int = LColor.yellow.getRGB();
										} else if (colorName
												.equalsIgnoreCase("green")) {
											color_int = LColor.green.getRGB();
										} else if (colorName
												.equalsIgnoreCase("orange")) {
											color_int = LColor.orange.getRGB();
										} else if (colorName
												.equalsIgnoreCase("wheat")) {
											color_int = LColor.wheat.getRGB();
										} else if (colorName
												.equalsIgnoreCase("gold")) {
											color_int = LColor.gold.getRGB();
										}

									}
									if (!ints.contains(color_int)) {
										ints.add(color_int);
									}
								}
							}
							_config.filterColors = ints.toArray();
						}
					}

				} catch (IOException e) {
				}
			}
			return _config;
		}
	}

	public static FrameBuffer newFrameBuffer(LTexture texture) {
		return new AndroidFrameBuffer(texture);
	}

	public static FrameBuffer newFrameBuffer(int width, int height,
			Format format) {
		return new AndroidFrameBuffer(width, height, format);
	}

	public static FrameBuffer newFrameBuffer(int width, int height) {
		return new AndroidFrameBuffer(width, height);
	}

	/**
	 * 执行一个位于Screen线程中的Runnable
	 *
	 * @param runnable
	 */
	public final static void callScreenRunnable(Runnable runnable) {
		LProcess process = LSystem.screenProcess;
		if (process != null) {
			Screen screen = process.getScreen();
			if (screen != null) {
				synchronized (screen) {
					screen.callEvent(runnable);
				}
			}
		}
	}

	public static Files files = null;

	public static Files files() {
		if (files == null) {
			if (screenActivity != null) {
				screenActivity.getFilesDir();
				files = new AndroidFiles(screenActivity.getAssets(),
						screenActivity.getFilesDir().getAbsolutePath());
			}
		}
		return files;
	}

	public static String getFileName(String name) {
		if (name == null) {
			return "";
		}
		int length = name.length();
		int size = name.lastIndexOf(LSystem.FS) + 1;
		if (size < length) {
			return name.substring(size, length);
		} else {
			return "";
		}
	}

	public static String getExtension(String name) {
		if (name == null) {
			return "";
		}
		int index = name.lastIndexOf(".");
		if (index == -1) {
			return "";
		} else {
			return name.substring(index + 1);
		}
	}

	public String getLanguage() {
		return java.util.Locale.getDefault().getLanguage();
	}

	public enum ApplicationType {
		Android, JavaSE, XNA, IOS, HTML5, PSM
	}

	public static CallQueue global_queue;

	public static ApplicationType type = ApplicationType.Android;

	public static float EMULATOR_BUTTIN_SCALE = 1f;

	public final static int RESOLUTION_LOW = 0;

	public final static int RESOLUTION_MEDIUM = 1;

	public final static int RESOLUTION_HIGH = 2;

	public final static int ICE_CREAM_SANDWICH = 14;

	public final static int HONEYCOMB = 11;

	public static int getResolutionType() {
		final int max = MathUtils.max(screenRect.width, screenRect.height);
		if (max < 480) {
			return RESOLUTION_LOW;
		} else if (max <= 800 && max >= 480) {
			return RESOLUTION_MEDIUM;
		} else {
			return RESOLUTION_HIGH;
		}
	}

	public final static int TRANSPARENT = 0xff000000;

	public final static boolean isThreadDrawing() {
		Thread thread = Thread.currentThread();
		if (thread != null) {
			String name = thread.getName();
			if (name != null && name.toLowerCase().startsWith("glthread")) {
				return true;
			}
		}
		return false;
	}

	public static final int DEFAULT_BUFFER_SIZE = 8192;
	public static final byte[] EMPTY_BYTES = new byte[0];

	public static void copyStream(InputStream input, OutputStream output)
			throws IOException {
		copyStream(input, output, DEFAULT_BUFFER_SIZE);
	}

	public static void copyStream(InputStream input, OutputStream output,
			int bufferSize) throws IOException {
		byte[] buffer = new byte[bufferSize];
		int bytesRead;
		while ((bytesRead = input.read(buffer)) != -1) {
			output.write(buffer, 0, bytesRead);
		}
	}

	public static byte[] copyStreamToByteArray(InputStream input)
			throws IOException {
		return copyStreamToByteArray(input, input.available());
	}

	public static byte[] copyStreamToByteArray(InputStream input,
			int estimatedSize) throws IOException {
		ByteArrayOutputStream baos = new OptimizedByteArrayOutputStream(
				Math.max(0, estimatedSize));
		copyStream(input, baos);
		return baos.toByteArray();
	}

	public static String copyStreamToString(InputStream input)
			throws IOException {
		return copyStreamToString(input, input.available());
	}

	public static String copyStreamToString(InputStream input,
			int approxStringLength) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(input));
		StringWriter w = new StringWriter(Math.max(0, approxStringLength));
		char[] buffer = new char[DEFAULT_BUFFER_SIZE];

		int charsRead;
		while ((charsRead = reader.read(buffer)) != -1) {
			w.write(buffer, 0, charsRead);
		}

		return w.toString();
	}

	static public class OptimizedByteArrayOutputStream extends
			ByteArrayOutputStream {

		public OptimizedByteArrayOutputStream(int initialSize) {
			super(initialSize);
		}

		@Override
		public synchronized byte[] toByteArray() {
			if (count == buf.length) {
				return buf;
			}
			return super.toByteArray();
		}

		public byte[] getBuffer() {
			return buf;
		}
	}

	public static void close(Closeable in) {
		if (in != null)
			try {
				in.close();
			} catch (Exception e) {
			}
	}

	public final static void close(LTexture tex2d) {
		if (tex2d != null) {
			try {
				tex2d.destroy();
				tex2d = null;
			} catch (Exception e) {
			}
		}
	}

	public final static void load(Updateable u) {
		if (LSystem.isThreadDrawing()) {
			u.action(null);
		} else {
			LProcess process = LSystem.screenProcess;
			if (process != null) {
				process.addLoad(u);
			}
		}
	}

	public final static void unload(Updateable u) {
		if (LSystem.isThreadDrawing()) {
			u.action(null);
		} else {
			LProcess process = LSystem.screenProcess;
			if (process != null) {
				process.addUnLoad(u);
			}
		}
	}

	public final static void clearUpdate() {
		LProcess process = LSystem.screenProcess;
		if (process != null) {
			process.removeAllDrawing();
		}
	}

	public final static void drawing(Drawable d) {
		LProcess process = LSystem.screenProcess;
		if (process != null) {
			process.addDrawing(d);
		}
	}

	public final static void clearDrawing() {
		LProcess process = LSystem.screenProcess;
		if (process != null) {
			process.removeAllDrawing();
		}
	}

	// 框架名
	final static public String FRAMEWORK = "loon";

	// 包内默认的图片路径
	final static public String FRAMEWORK_IMG_NAME = "assets/loon_";

	// 框架版本信息
	final static public String VERSION = "0.4.1";

	// 默认的最大窗体宽(横屏)
	public static int MAX_SCREEN_WIDTH = 480;

	// 默认的最大窗体高(横屏)
	public static int MAX_SCREEN_HEIGHT = 320;

	public static RectBox screenRect = new RectBox(0, 0, MAX_SCREEN_WIDTH,
			MAX_SCREEN_HEIGHT);

	// 图像缩放值
	public static int IMAGE_SIZE = 0;

	// 秒
	final static public long SECOND = 1000;

	// 分
	final static public long MINUTE = SECOND * 60;

	// 小时
	final static public long HOUR = MINUTE * 60;

	// 天
	final static public long DAY = HOUR * 24;

	// 周
	final static public long WEEK = DAY * 7;

	// 理论上一年
	final static public long YEAR = DAY * 365;

	// 行分隔符
	final static public String LS = System.getProperty("line.separator", "\n");

	// 文件分割符
	final static public String FS = System.getProperty("file.separator", "\\");

	// 随机数
	final static public Random random = new Random();

	// 屏幕是否横屏
	public static boolean SCREEN_LANDSCAPE;

	// 最大缓存数量
	final static public int DEFAULT_MAX_CACHE_SIZE = 30;

	final static public String encoding = "UTF-8";

	final static public String FONT_NAME = "Monospaced";

	final static public int DEFAULT_MAX_FPS = 60;

	public static LGame screenActivity;

	public static LProcess screenProcess;

	public static boolean isStringTexture = false, isBackLocked = false;

	public static float scaleWidth = 1, scaleHeight = 1;

	public static boolean isCreated, isLogo, isRunning, isResume, isDestroy,
			isPaused, AUTO_REPAINT;

	private static boolean EMULATOR;

	private static android.os.Handler OS_HANDLER;

	final private static String BULID_BRAND, BULID_MODEL, BULIDM_PRODUCT,
			BULIDM_RELEASE, BULIDM_DEVICE;

	private static int BULIDM_SDK;

	public static boolean USE_BITMAP_MEMORY_HACK;

	private static HashMap<String, Object> settings = new HashMap<String, Object>(
			5);

	/**
	 * 打开当前系统浏览器
	 *
	 * @param url
	 */
	public static void openURL(String url) {
		if (LSystem.screenActivity != null) {
			android.content.Intent browserIntent = new android.content.Intent(
					android.content.Intent.ACTION_VIEW,
					android.net.Uri.parse(url));
			LSystem.screenActivity.startActivity(browserIntent);
		}
	}

	public static String getResourcePath(String name) throws IOException {
		if (LSystem.screenActivity == null) {
			return name;
		}
		if (LSystem.type == LSystem.ApplicationType.Android) {
			if (name.toLowerCase().startsWith("assets/")) {
				name = StringUtils.replaceIgnoreCase(name, "assets/", "");
			}
			if (name.startsWith("/") || name.startsWith("\\")) {
				name = name.substring(1, name.length());
			}
		}
		File file = new File(LSystem.screenActivity.getFilesDir(), name);
		if (!file.exists()) {
			retrieveFromAssets(LSystem.screenActivity, name);
		}
		return file.getAbsolutePath();
	}

	private static void retrieveFromAssets(Activity activity, String filename)
			throws IOException {
		InputStream is = activity.getAssets().open(filename);
		File outFile = new File(activity.getFilesDir(), filename);
		makedirs(outFile);
		FileOutputStream fos = new FileOutputStream(outFile);
		byte[] buffer = new byte[2048];
		int length;
		while ((length = is.read(buffer)) > 0) {
			fos.write(buffer, 0, length);
		}
		fos.flush();
		fos.close();
		is.close();
	}

	private static void makedirs(File file) throws IOException {
		checkFile(file);
		File parentFile = file.getParentFile();
		if (parentFile != null) {
			if (!parentFile.exists() && !parentFile.mkdirs()) {
				throw new IOException("Creating directories "
						+ parentFile.getPath() + " failed.");
			}
		}
	}

	private static void checkFile(File file) throws IOException {
		boolean exists = file.exists();
		if (exists && !file.isFile()) {
			throw new IOException("File " + file.getPath()
					+ " is actually not a file.");
		}
	}

	/**
	 * 设定一组键值对到缓存当中
	 *
	 * @param key
	 * @param value
	 */
	public static void set(String key, Object value) {
		if (key == null || "".equals(key)) {
			return;
		}
		settings.put(key, value);
	}

	/**
	 * 获得指定键所对应的数值
	 *
	 * @param key
	 * @return
	 */
	public static Object get(String key) {
		if (key == null || "".equals(key)) {
			return null;
		}
		return settings.get(key);
	}

	static {
		BULID_BRAND = Build.BRAND.toLowerCase();
		BULID_MODEL = Build.MODEL.toLowerCase();
		BULIDM_PRODUCT = Build.PRODUCT.toLowerCase();
		BULIDM_RELEASE = Build.VERSION.RELEASE;
		try {
			BULIDM_SDK = Integer.parseInt(String.valueOf(Build.VERSION.class
					.getDeclaredField("SDK").get(null)));
		} catch (Exception ex) {
			try {
				BULIDM_SDK = Build.VERSION.class.getDeclaredField("SDK_INT")
						.getInt(null);
			} catch (Exception e) {
				BULIDM_SDK = 3;
			}
		}
		BULIDM_DEVICE = Build.DEVICE;
		EMULATOR = BULID_BRAND.indexOf("generic") != -1
				&& BULID_MODEL.indexOf("sdk") != -1;
		USE_BITMAP_MEMORY_HACK = BULIDM_SDK < ICE_CREAM_SANDWICH;
	}

	/**
	 * 设定常规图像加载方法(非全部)的默认劣化值
	 *
	 * @param sampleSize
	 */
	public static void setPoorImage(int sampleSize) {
		if (sampleSize > 0) {
			LSystem.IMAGE_SIZE = sampleSize;
		} else {
			LSystem.IMAGE_SIZE = 0;
		}
	}

	/**
	 * 判定是否使用了"奇异"的三星机型
	 *
	 * @return
	 */
	public static boolean isSamsung7500() {
		return isDevice("GT-I7500");
	}

	/**
	 * 判断手机驱动
	 *
	 * @param d
	 * @return
	 */
	public static boolean isDevice(String d) {
		return BULIDM_DEVICE.equalsIgnoreCase(d);
	}

	/**
	 * 设定LayoutParams为全屏模式
	 *
	 * @return
	 */
	public static LayoutParams createFillLayoutParams() {
		return new LayoutParams(0xffffffff, 0xffffffff);
	}

	/**
	 * 生成一个对应指定位置的RelativeLayout
	 *
	 * @param location
	 * @return
	 */
	public static RelativeLayout.LayoutParams createRelativeLayout(
			Location location) {
		return createRelativeLayout(location, LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);
	}

	/**
	 * 生成一个对应指定位置的RelativeLayout
	 *
	 * @param location
	 * @return
	 */
	public static RelativeLayout.LayoutParams createRelativeLayout(
			Location location, int w, int h) {
		RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
				w, h);
		if (location == Location.LEFT) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,
					RelativeLayout.TRUE);
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
					RelativeLayout.TRUE);
		} else if (location == Location.RIGHT) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,
					RelativeLayout.TRUE);
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
					RelativeLayout.TRUE);
		} else if (location == Location.TOP) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
					RelativeLayout.TRUE);
		} else if (location == Location.BOTTOM) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,
					RelativeLayout.TRUE);
		} else if (location == Location.BOTTOM_LEFT) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,
					RelativeLayout.TRUE);
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,
					RelativeLayout.TRUE);
		} else if (location == Location.BOTTOM_RIGHT) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,
					RelativeLayout.TRUE);
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,
					RelativeLayout.TRUE);
		} else if (location == Location.CENTER) {
			relativeParams.addRule(RelativeLayout.CENTER_VERTICAL,
					RelativeLayout.TRUE);
			relativeParams.addRule(RelativeLayout.CENTER_IN_PARENT,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_BASELINE) {
			relativeParams.addRule(RelativeLayout.ALIGN_BASELINE,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_LEFT) {
			relativeParams.addRule(RelativeLayout.ALIGN_LEFT,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_TOP) {
			relativeParams.addRule(RelativeLayout.ALIGN_TOP,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_RIGHT) {
			relativeParams.addRule(RelativeLayout.ALIGN_RIGHT,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_BOTTOM) {
			relativeParams.addRule(RelativeLayout.ALIGN_BOTTOM,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_PARENT_LEFT) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_PARENT_TOP) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_PARENT_RIGHT) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,
					RelativeLayout.TRUE);
		} else if (location == Location.ALIGN_PARENT_BOTTOM) {
			relativeParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,
					RelativeLayout.TRUE);
		} else if (location == Location.CENTER_IN_PARENT) {
			relativeParams.addRule(RelativeLayout.CENTER_IN_PARENT,
					RelativeLayout.TRUE);
		} else if (location == Location.CENTER_HORIZONTAL) {
			relativeParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
					RelativeLayout.TRUE);
		} else if (location == Location.CENTER_VERTICAL) {
			relativeParams.addRule(RelativeLayout.CENTER_VERTICAL,
					RelativeLayout.TRUE);
		}

		return relativeParams;
	}

	/**
	 * 跳转到指定的Activity
	 *
	 * @param from
	 */
	public static void action(android.app.Activity from, Class<?> clazz) {

		screenActivity.setDestroy(false);

		android.content.Intent intent = new android.content.Intent(from, clazz);
		from.startActivity(intent);
	}

	/**
	 * 跳转到指定的Activity,并将其设定为最初的Activity
	 *
	 * @param from
	 * @param clazz
	 */
	public static void go(android.app.Activity from, Class<?> clazz) {
		LSystem.getActivity().setDestroy(false);
		android.content.Intent intent = new android.content.Intent(from, clazz);
		intent.setFlags(android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP);
		from.startActivity(intent);
	}

	public static android.os.Handler getOSHandler() {
		if (OS_HANDLER == null) {
			OS_HANDLER = new android.os.Handler();
		}
		return OS_HANDLER;
	}

	public final static void post(final Updateable update) {
		if (LSystem.isPaused) {
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					update.action(null);
				}
			});
		} else {
			if (global_queue != null) {
				global_queue.invokeLater(update);
			} else {
				LSystem.load(update);
			}
		}
	}

	public static void runOnUiThread(final Runnable runnable) {
		LSystem.getActivity().runOnUiThread(runnable);
	}

	public static void dispose(final Runnable runnable) {
		getOSHandler().removeCallbacks(runnable);
		getOSHandler().removeMessages(0);
	}

	public static void stopRepaint() {
		LSystem.AUTO_REPAINT = false;
		LSystem.isPaused = true;
	}

	public static void startRepaint() {
		LSystem.AUTO_REPAINT = true;
		LSystem.isPaused = false;
	}

	public static long getJavaHeap() {
		return Runtime.getRuntime().totalMemory()
				- Runtime.getRuntime().freeMemory();
	}

	/**
	 * 判定当前Android系统版本是否高于指定的版本
	 *
	 * @param ver
	 * @return
	 */
	public static boolean isAndroidVersionHigher(final int ver) {
		return BULIDM_SDK >= ver;
	}

	public static String getModel() {
		return BULID_MODEL;
	}

	public static String getProductName() {
		return BULIDM_PRODUCT;
	}

	public static String getOSVersion() {
		return BULIDM_RELEASE;
	}

	public static int getSDKVersion() {
		return BULIDM_SDK;
	}

	public static boolean isPaused() {
		return isPaused;
	}

	public static String getBRANDName() {
		return BULID_BRAND;
	}

	public static boolean isEmulator() {
		return EMULATOR;
	}

	public static boolean isHTC() {
		return BULID_BRAND.indexOf("htc") != -1;
	}

	public static boolean isSamsungGalaxy() {
		final boolean isSamsung = BULID_BRAND.indexOf("samsung") != -1;
		final boolean isGalaxy = BULID_MODEL.indexOf("galaxy") != -1;
		return isSamsung && isGalaxy;
	}

	public static boolean isDroidOrMilestone() {
		final boolean isMotorola = BULID_BRAND.indexOf("moto") != -1;
		final boolean isDroid = BULID_MODEL.indexOf("droid") != -1;
		final boolean isMilestone = BULID_MODEL.indexOf("milestone") != -1;
		return isMotorola && (isDroid || isMilestone);
	}

	/**
	 * 清空框架临时资源
	 */
	public static void destroy() {
		AndroidGraphicsUtils.destroy();
		Resources.destroy();
		LSystem.gc();
	}

	/**
	 * 退出当前应用
	 *
	 */
	public static void exit() {
		if (screenProcess == null) {
			return;
		}
		synchronized (screenProcess) {
			if (screenProcess != null) {
				LSystem.isRunning = false;
				if (screenActivity != null) {
					if (screenActivity.isDestroy()) {
						screenActivity.finish();
					}
				}
			}
		}
	}

	/**
	 * 返回当前的Activity
	 *
	 * @return
	 */
	public static LGame getActivity() {
		return screenActivity;
	}

	public static SystemTimer getSystemTimer() {
		return new SystemTimer();
	}

	/**
	 * 申请回收系统资源
	 *
	 */
	final public static void gc() {
		System.gc();
	}

	/**
	 * 以指定范围内的指定概率执行gc
	 *
	 * @param size
	 * @param rand
	 */
	final public static void gc(final int size, final long rand) {
		if (rand > size) {
			throw new RuntimeException(
					("GC random probability " + rand + " > " + size).intern());
		}
		if (LSystem.random.nextInt(size) <= rand) {
			LSystem.gc();
		}
	}

	/**
	 * 以指定概率使用gc回收系统资源
	 *
	 * @param rand
	 */
	final public static void gc(final long rand) {
		gc(100, rand);
	}

	/**
	 * 写入整型数据到OutputStream
	 *
	 * @param out
	 * @param number
	 */
	public final static void writeInt(final OutputStream out, final int number) {
		byte[] bytes = new byte[4];
		try {
			for (int i = 0; i < 4; i++) {
				bytes[i] = (byte) ((number >> (i * 8)) & 0xff);
			}
			out.write(bytes);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	/**
	 * 从InputStream中获得整型数据
	 *
	 * @param in
	 * @return
	 */
	final static public int readInt(final InputStream in) {
		int data = -1;
		try {
			data = (in.read() & 0xff);
			data |= ((in.read() & 0xff) << 8);
			data |= ((in.read() & 0xff) << 16);
			data |= ((in.read() & 0xff) << 24);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
		return data;
	}

	/**
	 * 合并hashCode和指定类型的数值生成新的Code值(以下同)
	 *
	 * @param hashCode
	 * @param value
	 * @return
	 */
	public static int unite(int hashCode, boolean value) {
		int v = value ? 1231 : 1237;
		return unite(hashCode, v);
	}

	public static int unite(int hashCode, long value) {
		int v = (int) (value ^ (value >>> 32));
		return unite(hashCode, v);
	}

	public static int unite(int hashCode, float value) {
		int v = Float.floatToIntBits(value);
		return unite(hashCode, v);
	}

	public static int unite(int hashCode, double value) {
		long v = Double.doubleToLongBits(value);
		return unite(hashCode, v);
	}

	public static int unite(int hashCode, Object value) {
		return unite(hashCode, value.hashCode());
	}

	public static int unite(int hashCode, int value) {
		return 31 * hashCode + value;
	}
}


text:
///
///
///
///

#include "MorphableEntity.h"
#include <iostream>

#define N_DEFAULT_DELAY 15

MorphableEntity::MorphableEntity() : Entity()
{
	m_bIsMorphable = false;
	m_nBaseDelay = 0;
	m_nCurDelay = 0;

	m_curShape = nullptr;//new MeshSet();
	m_vecMorphs.push_back(m_curShape);
	init();

}

MorphableEntity::MorphableEntity(const MeshSet* start, glm::vec3 pos) : Entity(start, pos)
{
	m_bIsMorphable = false;
	m_nBaseDelay = N_DEFAULT_DELAY;
	m_nCurDelay = N_DEFAULT_DELAY;

	m_curShape = start;
	m_vecMorphs.push_back(m_curShape);
	init();

}

MorphableEntity::MorphableEntity(const MeshSet* start, glm::vec3 pos, glm::vec3 orient) : Entity(start, pos)
{
	m_bIsMorphable = false;
	m_nBaseDelay = N_DEFAULT_DELAY;
	m_nCurDelay = N_DEFAULT_DELAY;

	m_curShape = start;
	m_vecMorphs.push_back(m_curShape);
	init();
}

MorphableEntity::MorphableEntity(std::vector<const MeshSet *> morphs)
{
	assert(morphs.size() > 0);

	m_vecMorphs = morphs;

	if (morphs.size() > 0)
	{
		m_curShape = m_vecMorphs[m_nCurMorph];
	}
	init();
}

void MorphableEntity::init()
{
	m_bIsMorphable = false;
	m_bIsVisible = false;
	m_nCurMorph = 0;
	m_biggestRadius = 0.0;

	calcBiggestRadius();

	//Entity::setShape(m_curShape);
}

bool MorphableEntity::morph()
{
	//std::cout << "Morphing from original index " << m_nCurMorph << "!" << std::endl;

	bool bSuccess = true;

	if (!m_bIsMorphable)
	{
		return false;
	}

	if (m_nCurMorph + 1 < m_vecMorphs.size())
	{
		m_nCurMorph++;
	}
	else
	{
		assert(m_vecMorphs.size() > 0);
		m_nCurMorph = 0;
	}

	m_curShape = m_vecMorphs[m_nCurMorph];
	setShape(m_curShape);
	m_bIsMorphable = false;

	//std::cout << "Morphed to  " << m_nCurMorph << "!" << std::endl;

	return bSuccess;
}

void MorphableEntity::setStartMorph(const MeshSet *start)
{
	m_vecMorphs.push_back(start);
	m_nCurMorph = m_vecMorphs.size() - 1;

	m_curShape = m_vecMorphs[m_nCurMorph];
}

float MorphableEntity::getBoundingSphereRadius()
{
	return m_biggestRadius;

	std::cout << "Getting Biggest Radius: " << m_biggestRadius << std::endl;
}

const MeshSet* MorphableEntity::getCurMesh()
{
	return m_curShape;
}

//Scales each radius based on the scale of the mesh!!!
void MorphableEntity::calcBiggestRadius(bool isSingleAdd)
{

	float curMax = getBoundingSphereRadius();

	if (isSingleAdd)
	{
		const MeshSet *last = m_vecMorphs[m_vecMorphs.size() - 1];
		curMax = std::fmax(last->calcBoundingBox().getRadius() * last->getScale(), curMax);
	}
	else
	{
		for (const MeshSet *mesh : m_vecMorphs)
		{
			curMax = std::fmax(mesh->calcBoundingBox().getRadius() * mesh->getScale(), curMax);
		}
	}

	m_biggestRadius = curMax;

	//std::cout << "CALCULATING BIGGEST RADIUS FOR " << m_vecMorphs[m_nCurMorph]->m_fileName << ": " << m_biggestRadius << std::endl;

}

void MorphableEntity::addMorph(const MeshSet *toAdd)
{
	m_vecMorphs.push_back(toAdd);
	calcBiggestRadius(true);
}

bool MorphableEntity::getIsVisible() { return m_bIsVisible; }
void MorphableEntity::setIsVisible(bool change) { m_bIsVisible = change; }

bool MorphableEntity::getIsMorphable() {return m_bIsMorphable; }
void MorphableEntity::setIsMorphable(bool change) {m_bIsMorphable = change; }

int MorphableEntity::getBaseDelay() { return m_nBaseDelay; }
void MorphableEntity::setBaseDelay(int delay) { m_nBaseDelay = delay; }

int MorphableEntity::getCurDelay() { return m_nCurDelay; }
void MorphableEntity::setCurDelay(int delay) { m_nCurDelay = delay; }

/*std::string MorphableEntity::toString()
{
	return "MorphableEntity:\n\tMorph Options: " +
		m_vecMorphs.size() +
		std::string("\n\tBase Delay: ") + m_nBaseDelay + "\n" +
		"\n\tCurrent Delay: " + m_nCurDelay + "\n";
}*/

redpajama_set_name: RedPajamaGithub


text:
#include "mtl/Sort.h"
#include "simp/SimpSolver.h"
#include "utils/System.h"

using namespace Minisat;

//=================================================================================================
// Options:

static const char* _cat = "SIMP";

static BoolOption   opt_use_asymm        (_cat, "asymm",        "Shrink clauses by asymmetric branching.", false);
static BoolOption   opt_use_rcheck       (_cat, "rcheck",       "Check if a clause is already implied. (costly)", false);
static BoolOption   opt_use_elim         (_cat, "elim",         "Perform variable elimination.", true);
static IntOption    opt_grow             (_cat, "grow",         "Allow a variable elimination step to grow by a number of clauses.", 0);
static IntOption    opt_clause_lim       (_cat, "cl-lim",       "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20,   IntRange(-1, INT32_MAX));
static IntOption    opt_subsumption_lim  (_cat, "sub-lim",      "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX));
static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.",  0.5, DoubleRange(0, false, HUGE_VAL, false));

//=================================================================================================
// Constructor/Destructor:

SimpSolver::SimpSolver() :
    grow               (opt_grow)
  , clause_lim         (opt_clause_lim)
  , subsumption_lim    (opt_subsumption_lim)
  , simp_garbage_frac  (opt_simp_garbage_frac)
  , use_asymm          (opt_use_asymm)
  , use_rcheck         (opt_use_rcheck)
  , use_elim           (opt_use_elim)
  , merges             (0)
  , asymm_lits         (0)
  , eliminated_vars    (0)
  , elimorder          (1)
  , use_simplification (true)
  , occurs             (ClauseDeleted(ca))
  , elim_heap          (ElimLt(n_occ))
  , bwdsub_assigns     (0)
  , n_touched          (0)
{
    vec<Lit> dummy(1,lit_Undef);
    ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
    bwdsub_tmpunit        = ca.alloc(dummy);
    remove_satisfied      = false;
}

SimpSolver::~SimpSolver()
{
}

Var SimpSolver::newVar(bool sign, bool dvar) {
    Var v = Solver::newVar(sign, dvar);

    frozen    .push((char)false);
    eliminated.push((char)false);

    if (use_simplification){
        n_occ     .push(0);
        n_occ     .push(0);
        occurs    .init(v);
        touched   .push(0);
        elim_heap .insert(v);
    }
    return v; }

lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp)
{
    vec<Var> extra_frozen;
    lbool    result = l_True;

    do_simp &= use_simplification;

    if (do_simp){
        // Assumptions must be temporarily frozen to run variable elimination:
        for (int i = 0; i < assumptions.size(); i++){
            Var v = var(assumptions[i]);

            // If an assumption has been eliminated, remember it.
            assert(!isEliminated(v));

            if (!frozen[v]){
                // Freeze and store.
                setFrozen(v, true);
                extra_frozen.push(v);
            } }

        result = lbool(eliminate(turn_off_simp,true));
    }

    if (result == l_True)
        result = Solver::solve_();
    else if (verbosity >= 1)
        printf("c ===============================================================================\n");

    if (result == l_True)
        extendModel();

    if (do_simp)
        // Unfreeze the assumptions that were frozen:
        for (int i = 0; i < extra_frozen.size(); i++)
            setFrozen(extra_frozen[i], false);

    return result;
}

bool SimpSolver::addClause_(vec<Lit>& ps)
{
#ifndef NDEBUG
    for (int i = 0; i < ps.size(); i++)
        assert(!isEliminated(var(ps[i])));
#endif

    int nclauses = clauses.size();

    if (use_rcheck && implied(ps))
        return true;

    if (!Solver::addClause_(ps))
        return false;

     if(!parsing && output != NULL) {
      for (int i = 0; i < ps.size(); i++)
        fprintf(output, "%i " , (var(ps[i]) + 1) * (-2 * sign(ps[i]) + 1) );
      fprintf(output, "0\n");
    }

    if (use_simplification && clauses.size() == nclauses + 1){
        CRef          cr = clauses.last();
        const Clause& c  = ca[cr];

        // NOTE: the clause is added to the queue immediately and then
        // again during 'gatherTouchedClauses()'. If nothing happens
        // in between, it will only be checked once. Otherwise, it may
        // be checked twice unnecessarily. This is an unfortunate
        // consequence of how backward subsumption is used to mimic
        // forward subsumption.
        subsumption_queue.insert(cr);
        for (int i = 0; i < c.size(); i++){
            occurs[var(c[i])].push(cr);
            n_occ[toInt(c[i])]++;
            touched[var(c[i])] = 1;
            n_touched++;
            if (elim_heap.inHeap(var(c[i])))
                elim_heap.increase(var(c[i]));
        }
    }

    return true;
}

void SimpSolver::removeClause(CRef cr)
{
    const Clause& c = ca[cr];

    if (use_simplification)
        for (int i = 0; i < c.size(); i++){
            n_occ[toInt(c[i])]--;
            updateElimHeap(var(c[i]));
            occurs.smudge(var(c[i]));
        }

    Solver::removeClause(cr);
}

bool SimpSolver::strengthenClause(CRef cr, Lit l)
{
    Clause& c = ca[cr];
    assert(decisionLevel() == 0);
    assert(use_simplification);

    // FIX: this is too inefficient but would be nice to have (properly implemented)
    // if (!find(subsumption_queue, &c))
    subsumption_queue.insert(cr);

         if (output != NULL) {
      for (int i = 0; i < c.size(); i++)
        if (c[i] != l) fprintf(output, "%i " , (var(c[i]) + 1) * (-2 * sign(c[i]) + 1) );
      fprintf(output, "0\n");
    }

    if (c.size() == 2){
        removeClause(cr);
        c.strengthen(l);
    }else{
            if (output != NULL) {
          fprintf(output, "d ");
          for (int i = 0; i < c.size(); i++)
            fprintf(output, "%i " , (var(c[i]) + 1) * (-2 * sign(c[i]) + 1) );
          fprintf(output, "0\n");
        }

        detachClause(cr, true);
        c.strengthen(l);
        attachClause(cr);
        remove(occurs[var(l)], cr);
        n_occ[toInt(l)]--;
        updateElimHeap(var(l));
    }

    return c.size() == 1 ? enqueue(c[0]) && propagate(true) == CRef_Undef : true;
}

// Returns FALSE if clause is always satisfied ('out_clause' should not be used).
bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
{
    merges++;
    out_clause.clear();

    bool  ps_smallest = _ps.size() < _qs.size();
    const Clause& ps  =  ps_smallest ? _qs : _ps;
    const Clause& qs  =  ps_smallest ? _ps : _qs;

    for (int i = 0; i < qs.size(); i++){
        if (var(qs[i]) != v){
            for (int j = 0; j < ps.size(); j++)
                if (var(ps[j]) == var(qs[i]))
                    if (ps[j] == ~qs[i])
                        return false;
                    else
                        goto next;
            out_clause.push(qs[i]);
        }
        next:;
    }

    for (int i = 0; i < ps.size(); i++)
        if (var(ps[i]) != v)
            out_clause.push(ps[i]);

    return true;
}

// Returns FALSE if clause is always satisfied.
bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size)
{
    merges++;

    bool  ps_smallest = _ps.size() < _qs.size();
    const Clause& ps  =  ps_smallest ? _qs : _ps;
    const Clause& qs  =  ps_smallest ? _ps : _qs;
    const Lit*  __ps  = (const Lit*)ps;
    const Lit*  __qs  = (const Lit*)qs;

    size = ps.size()-1;

    for (int i = 0; i < qs.size(); i++){
        if (var(__qs[i]) != v){
            for (int j = 0; j < ps.size(); j++)
                if (var(__ps[j]) == var(__qs[i]))
                    if (__ps[j] == ~__qs[i])
                        return false;
                    else
                        goto next;
            size++;
        }
        next:;
    }

    return true;
}

void SimpSolver::gatherTouchedClauses()
{
    if (n_touched == 0) return;

    int i,j;
    for (i = j = 0; i < subsumption_queue.size(); i++)
        if (ca[subsumption_queue[i]].mark() == 0)
            ca[subsumption_queue[i]].mark(2);

    for (i = 0; i < touched.size(); i++)
        if (touched[i]){
            const vec<CRef>& cs = occurs.lookup(i);
            for (j = 0; j < cs.size(); j++)
                if (ca[cs[j]].mark() == 0){
                    subsumption_queue.insert(cs[j]);
                    ca[cs[j]].mark(2);
                }
            touched[i] = 0;
        }

    for (i = 0; i < subsumption_queue.size(); i++)
        if (ca[subsumption_queue[i]].mark() == 2)
            ca[subsumption_queue[i]].mark(0);

    n_touched = 0;
}

bool SimpSolver::implied(const vec<Lit>& c)
{
    assert(decisionLevel() == 0);

    trail_lim.push(trail.size());
    for (int i = 0; i < c.size(); i++)
        if (value(c[i]) == l_True){
            cancelUntil(0);
            return false;
        }else if (value(c[i]) != l_False){
            assert(value(c[i]) == l_Undef);
            uncheckedEnqueue(~c[i]);
        }

    bool result = propagate(true) != CRef_Undef;
    cancelUntil(0);
    return result;
}

// Backward subsumption + backward subsumption resolution
bool SimpSolver::backwardSubsumptionCheck(bool verbose)
{
    int cnt = 0;
    int subsumed = 0;
    int deleted_literals = 0;
    assert(decisionLevel() == 0);

    while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){

        // Empty subsumption queue and return immediately on user-interrupt:
        if (asynch_interrupt){
            subsumption_queue.clear();
            bwdsub_assigns = trail.size();
            break; }

        // Check top-level assignments by creating a dummy clause and placing it in the queue:
        if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
            Lit l = trail[bwdsub_assigns++];
            ca[bwdsub_tmpunit][0] = l;
            ca[bwdsub_tmpunit].calcAbstraction();
            subsumption_queue.insert(bwdsub_tmpunit); }

        CRef    cr = subsumption_queue.peek(); subsumption_queue.pop();
        Clause& c  = ca[cr];

        if (c.mark()) continue;

        if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
            printf("c subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);

        assert(c.size() > 1 || value(c[0]) == l_True);    // Unit-clauses should have been propagated before this point.

        // Find best variable to scan:
        Var best = var(c[0]);
        for (int i = 1; i < c.size(); i++)
            if (occurs[var(c[i])].size() < occurs[best].size())
                best = var(c[i]);

        // Search all candidates:
        vec<CRef>& _cs = occurs.lookup(best);
        CRef*       cs = (CRef*)_cs;

        for (int j = 0; j < _cs.size(); j++)
            if (c.mark())
                break;
            else if (!ca[cs[j]].mark() &&  cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){
                Lit l = c.subsumes(ca[cs[j]]);

                if (l == lit_Undef)
                    subsumed++, removeClause(cs[j]);
                else if (l != lit_Error){
                    deleted_literals++;

                    if (!strengthenClause(cs[j], ~l))
                        return false;

                    // Did current candidate get deleted from cs? Then check candidate at index j again:
                    if (var(l) == best)
                        j--;
                }
            }
    }

    return true;
}

bool SimpSolver::asymm(Var v, CRef cr)
{
    Clause& c = ca[cr];
    assert(decisionLevel() == 0);

    if (c.mark() || satisfied(c)) return true;

    trail_lim.push(trail.size());
    Lit l = lit_Undef;
    for (int i = 0; i < c.size(); i++)
        if (var(c[i]) != v && value(c[i]) != l_False)
            uncheckedEnqueue(~c[i]);
        else
            l = c[i];

    if (propagate(true) != CRef_Undef){
        cancelUntil(0);
        asymm_lits++;
        if (!strengthenClause(cr, l))
            return false;
    }else
        cancelUntil(0);

    return true;
}

bool SimpSolver::asymmVar(Var v)
{
    assert(use_simplification);

    const vec<CRef>& cls = occurs.lookup(v);

    if (value(v) != l_Undef || cls.size() == 0)
        return true;

    for (int i = 0; i < cls.size(); i++)
        if (!asymm(v, cls[i]))
            return false;

    return backwardSubsumptionCheck();
}

static void mkElimClause(vec<uint32_t>& elimclauses, Lit x)
{
    elimclauses.push(toInt(x));
    elimclauses.push(1);
}

static void mkElimClause(vec<uint32_t>& elimclauses, Var v, Clause& c)
{
    int first = elimclauses.size();
    int v_pos = -1;

    // Copy clause to elimclauses-vector. Remember position where the
    // variable 'v' occurs:
    for (int i = 0; i < c.size(); i++){
        elimclauses.push(toInt(c[i]));
        if (var(c[i]) == v)
            v_pos = i + first;
    }
    assert(v_pos != -1);

    // Swap the first literal with the 'v' literal, so that the literal
    // containing 'v' will occur first in the clause:
    uint32_t tmp = elimclauses[v_pos];
    elimclauses[v_pos] = elimclauses[first];
    elimclauses[first] = tmp;

    // Store the length of the clause last:
    elimclauses.push(c.size());
}

bool SimpSolver::eliminateVar(Var v)
{
    assert(!frozen[v]);
    assert(!isEliminated(v));
    assert(value(v) == l_Undef);

    // Split the occurrences into positive and negative:
    //
    const vec<CRef>& cls = occurs.lookup(v);
    vec<CRef>        pos, neg;
    for (int i = 0; i < cls.size(); i++)
        (find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]);

    // Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no
    // clause must exceed the limit on the maximal clause size (if it is set):
    //
    int cnt         = 0;
    int clause_size = 0;

    for (int i = 0; i < pos.size(); i++)
        for (int j = 0; j < neg.size(); j++)
            if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) &&
                (++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim)))
                return true;

    // Delete and store old clauses:
    eliminated[v] = true;
    setDecisionVar(v, false);
    eliminated_vars++;

    if (pos.size() > neg.size()){
        for (int i = 0; i < neg.size(); i++)
            mkElimClause(elimclauses, v, ca[neg[i]]);
        mkElimClause(elimclauses, mkLit(v));
    }else{
        for (int i = 0; i < pos.size(); i++)
            mkElimClause(elimclauses, v, ca[pos[i]]);
        mkElimClause(elimclauses, ~mkLit(v));
    }

    // Produce clauses in cross product:
    vec<Lit>& resolvent = add_tmp;
    for (int i = 0; i < pos.size(); i++)
        for (int j = 0; j < neg.size(); j++)
            if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent))
                return false;
       for (int i = 0; i < cls.size(); i++)
        removeClause(cls[i]);
    // Free occurs list for this variable:
    occurs[v].clear(true);

    // Free watchers lists for this variable, if possible:
    if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true);
    if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true);

    return backwardSubsumptionCheck();
}

bool SimpSolver::substitute(Var v, Lit x)
{
    assert(!frozen[v]);
    assert(!isEliminated(v));
    assert(value(v) == l_Undef);

    if (!ok) return false;

    eliminated[v] = true;
    setDecisionVar(v, false);
    const vec<CRef>& cls = occurs.lookup(v);

    vec<Lit>& subst_clause = add_tmp;
    for (int i = 0; i < cls.size(); i++){
        Clause& c = ca[cls[i]];

        subst_clause.clear();
        for (int j = 0; j < c.size(); j++){
            Lit p = c[j];
            subst_clause.push(var(p) == v ? x ^ sign(p) : p);
        }

        if (!addClause_(subst_clause))
            return ok = false;

            removeClause(cls[i]);
    }

    return true;
}

void SimpSolver::extendModel()
{
    int i, j;
    Lit x;

    for (i = elimclauses.size()-1; i > 0; i -= j){
        for (j = elimclauses[i--]; j > 1; j--, i--)
            if (modelValue(toLit(elimclauses[i])) != l_False)
                goto next;

        x = toLit(elimclauses[i]);
        model[var(x)] = lbool(!sign(x));
    next:;
    }
}

bool SimpSolver::eliminate(bool turn_off_elim,bool ini)
{
    if (!simplify(ini))
        return false;
    else if (!use_simplification)
        return true;

    // Main simplification loop:
    //
    while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){

        gatherTouchedClauses();
        // printf("  ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns);
        if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) &&
            !backwardSubsumptionCheck(true)){
            ok = false; goto cleanup; }

        // Empty elim_heap and return immediately on user-interrupt:
        if (asynch_interrupt){
            assert(bwdsub_assigns == trail.size());
            assert(subsumption_queue.size() == 0);
            assert(n_touched == 0);
            elim_heap.clear();
            goto cleanup; }

        // printf("  ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size());
        for (int cnt = 0; !elim_heap.empty(); cnt++){
            Var elim = elim_heap.removeMin();

            if (asynch_interrupt) break;

            if (isEliminated(elim) || value(elim) != l_Undef) continue;

            if (verbosity >= 2 && cnt % 100 == 0)
                printf("c elimination left: %10d\r", elim_heap.size());

            if (use_asymm){
                // Temporarily freeze variable. Otherwise, it would immediately end up on the queue again:
                bool was_frozen = frozen[elim];
                frozen[elim] = true;
                if (!asymmVar(elim)){
                    ok = false; goto cleanup; }
                frozen[elim] = was_frozen; }

            // At this point, the variable may have been set by assymetric branching, so check it
            // again. Also, don't eliminate frozen variables:
            if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){
                ok = false; goto cleanup; }

            checkGarbage(simp_garbage_frac);
        }

        assert(subsumption_queue.size() == 0);
    }
 cleanup:

    // If no more simplification is needed, free all simplification-related data structures:
    if (turn_off_elim){
        touched  .clear(true);
        occurs   .clear(true);
        n_occ    .clear(true);
        elim_heap.clear(true);
        subsumption_queue.clear(true);

        use_simplification    = false;
        remove_satisfied      = true;
        ca.extra_clause_field = false;

        // Force full cleanup (this is safe and desirable since it only happens once):
        rebuildOrderHeap();
        garbageCollect();
    }else{
        // Cheaper cleanup:
        cleanUpClauses(); // TODO: can we make 'cleanUpClauses()' not be linear in the problem size somehow?
        checkGarbage();
    }

    if (verbosity >= 1 && elimclauses.size() > 0)
        printf("c |  Eliminated clauses:     %10.2f Mb                                      |\n",
               double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024));

    return ok;
}

void SimpSolver::cleanUpClauses()
{
  // if (!use_simplification) return;

    occurs.cleanAll();
    int i,j;
    for (i = j = 0; i < clauses.size(); i++)
        if (ca[clauses[i]].mark() == 0)
            clauses[j++] = clauses[i];

	if(i!=j)
    clauses.shrink(i - j);
}

//=================================================================================================
// Garbage Collection methods:

void SimpSolver::relocAll(ClauseAllocator& to)
{
   // printf("in reloc all\n");
    if (!use_simplification) return;

    // All occurs lists:
    //
    for (int i = 0; i < nVars(); i++){
        vec<CRef>& cs = occurs[i];
        for (int j = 0; j < cs.size(); j++)
            ca.reloc(cs[j], to);
    }

    // Subsumption queue:
    //
    for (int i = 0; i < subsumption_queue.size(); i++)
        ca.reloc(subsumption_queue[i], to);

    // Temporary clause:
    //
    ca.reloc(bwdsub_tmpunit, to);
	//printf("out of reloc all\n");
}

void SimpSolver::garbageCollect()
{
    // Initialize the next region to a size corresponding to the estimated utilization degree. This
    // is not precise but should avoid some unnecessary reallocations for the new region:
	//printf("in garbagecollect\n");
    ClauseAllocator to(ca.size() - ca.wasted());

    cleanUpClauses();
    to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields.
    relocAll(to);
	//if(!use_simplification)
    Solver::relocAll(to);
    if (verbosity >= 2)
        printf("c |  Garbage collection:   %12d bytes => %12d bytes             |\n",
               ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
    to.moveTo(ca);
	///////
	//printf("out of gargage collet\n");
}


text:
package com.reinvent.synergy.rest;

import com.reinvent.surus.model.Constants;
import com.reinvent.surus.system.PoolManager;
import com.reinvent.surus.system.TableContext;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Bohdan Mushkevych
 * Description: handles delete requests from UI
 */
public class ExampleDeleteHandler implements RequestHandler {
    protected Logger logger = Logger.getLogger(ExampleDeleteHandler.class.getSimpleName());

    protected HttpServletRequest request;
    protected HttpServletResponse response;

    protected PoolManager pmExample = TableContext.getPoolManager(Constants.TABLE_EXAMPLE);

    protected Integer domainId;
    protected boolean isValid;

    public ExampleDeleteHandler(HttpServletRequest req, HttpServletResponse resp) {
        request = req;
        response = resp;

        try {
            domainId = Integer.valueOf(request.getParameter(PARAMETER_DOMAIN_ID));
            isValid = true;
        } catch (Exception e) {
            logger.warn(String.format("Request is considered invalid (domain_id): (%s)",
                    request.getParameter(PARAMETER_DOMAIN_ID)), e);
            isValid = false;
        }
    }

    public void run() {
        if (!isValid) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        HTableInterface tExample = null;

        try {
            tExample = pmExample.getTable();

            Delete delete = new Delete(Bytes.toBytes(domainId));

            tExample.delete(delete);
            tExample.flushCommits();
            response.setStatus(HttpServletResponse.SC_OK);
        } catch (IOException e) {
            logger.warn(String.format("Exception on deleting Example record (domain): (%s)", domainId), e);
            response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
        } catch (Exception e) {
            logger.warn(String.format("Exception on deleting Example record (domain): (%s)", domainId), e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } finally {
            if (tExample != null) {
                pmExample.putTable(tExample);
            }
        }
    }
}


text:
package com.dale.ms.entities;

import java.sql.Timestamp;

/**
 * HmStore entity. @author MyEclipse Persistence Tools
 */

public class HmStore implements java.io.Serializable {

	// Fields

	private Long storeId;
	private Long userId;
	private String bussinessLicense;
	private String storeAddress;
	private String storeName;
	private String storeMobile;
	private String storeImg;
	private Timestamp createDate;
	private String qrCode;
	private String getuiClientId;
	private String deviceInfo;

	// Constructors

	/** default constructor */
	public HmStore() {
	}

	/** minimal constructor */
	public HmStore(Long userId) {
		this.userId = userId;
	}

	/** full constructor */
	public HmStore(Long userId, String bussinessLicense, String storeAddress,
			String storeName, String storeMobile, String storeImg,
			Timestamp createDate, String qrCode, String getuiClientId,
			String deviceInfo) {
		this.userId = userId;
		this.bussinessLicense = bussinessLicense;
		this.storeAddress = storeAddress;
		this.storeName = storeName;
		this.storeMobile = storeMobile;
		this.storeImg = storeImg;
		this.createDate = createDate;
		this.qrCode = qrCode;
		this.getuiClientId = getuiClientId;
		this.deviceInfo = deviceInfo;
	}

	// Property accessors

	public Long getStoreId() {
		return this.storeId;
	}

	public void setStoreId(Long storeId) {
		this.storeId = storeId;
	}

	public Long getUserId() {
		return this.userId;
	}

	public void setUserId(Long userId) {
		this.userId = userId;
	}

	public String getBussinessLicense() {
		return this.bussinessLicense;
	}

	public void setBussinessLicense(String bussinessLicense) {
		this.bussinessLicense = bussinessLicense;
	}

	public String getStoreAddress() {
		return this.storeAddress;
	}

	public void setStoreAddress(String storeAddress) {
		this.storeAddress = storeAddress;
	}

	public String getStoreName() {
		return this.storeName;
	}

	public void setStoreName(String storeName) {
		this.storeName = storeName;
	}

	public String getStoreMobile() {
		return this.storeMobile;
	}

	public void setStoreMobile(String storeMobile) {
		this.storeMobile = storeMobile;
	}

	public String getStoreImg() {
		return this.storeImg;
	}

	public void setStoreImg(String storeImg) {
		this.storeImg = storeImg;
	}

	public Timestamp getCreateDate() {
		return this.createDate;
	}

	public void setCreateDate(Timestamp createDate) {
		this.createDate = createDate;
	}

	public String getQrCode() {
		return this.qrCode;
	}

	public void setQrCode(String qrCode) {
		this.qrCode = qrCode;
	}

	public String getGetuiClientId() {
		return this.getuiClientId;
	}

	public void setGetuiClientId(String getuiClientId) {
		this.getuiClientId = getuiClientId;
	}

	public String getDeviceInfo() {
		return this.deviceInfo;
	}

	public void setDeviceInfo(String deviceInfo) {
		this.deviceInfo = deviceInfo;
	}

}


text:
echo "taking ownership"
sudo chown -R $(whoami):admin /usr/local /usr/local/bin /Library/Caches/Homebrew

echo "done!"


text:
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This script is used to download prebuilt clang binaries.

It is also used by package.py to build the prebuilt clang binaries."""

import argparse
import cStringIO
import distutils.spawn
import glob
import os
import pipes
import re
import shutil
import subprocess
import stat
import sys
import tarfile
import tempfile
import time
import urllib2
import zipfile

# Do NOT CHANGE this if you don't know what you're doing -- see
# https://code.google.com/p/chromium/wiki/UpdatingClang
# Reverting problematic clang rolls is safe, though.
CLANG_REVISION = '254049'

use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
if use_head_revision:
  CLANG_REVISION = 'HEAD'

# This is incremented when pushing a new build of Clang at the same revision.
CLANG_SUB_REVISION=1

PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)

# Path constants. (All of these should be absolute paths.)
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm')
LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
                                          'llvm-bootstrap-install')
CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
                              'Release+Asserts')
COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'compiler-rt')
CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
# compiler-rt is built as part of the regular LLVM build on Windows to get
# the 64-bit runtime, and out-of-tree elsewhere.
# TODO(thakis): Try to unify this.
if sys.platform == 'win32':
  COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
else:
  COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'compiler-rt')
LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx')
LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
LLVM_BUILD_TOOLS_DIR = os.path.abspath(
    os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')
BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
VERSION = '3.8.0'
ANDROID_NDK_DIR = os.path.join(
    CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk')

# URL for pre-built binaries.
CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang'

LLVM_REPO_URL='https://llvm.org/svn/llvm-project'
if 'LLVM_REPO_URL' in os.environ:
  LLVM_REPO_URL = os.environ['LLVM_REPO_URL']

def DownloadUrl(url, output_file):
  """Download url into output_file."""
  CHUNK_SIZE = 4096
  TOTAL_DOTS = 10
  sys.stdout.write('Downloading %s ' % url)
  sys.stdout.flush()
  response = urllib2.urlopen(url)
  total_size = int(response.info().getheader('Content-Length').strip())
  bytes_done = 0
  dots_printed = 0
  while True:
    chunk = response.read(CHUNK_SIZE)
    if not chunk:
      break
    output_file.write(chunk)
    bytes_done += len(chunk)
    num_dots = TOTAL_DOTS * bytes_done / total_size
    sys.stdout.write('.' * (num_dots - dots_printed))
    sys.stdout.flush()
    dots_printed = num_dots
  print ' Done.'

def DownloadAndUnpack(url, output_dir):
  with tempfile.TemporaryFile() as f:
    DownloadUrl(url, f)
    f.seek(0)
    if not os.path.exists(output_dir):
      os.makedirs(output_dir)
    if url.endswith('.zip'):
      zipfile.ZipFile(f).extractall(path=output_dir)
    else:
      tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir)

def ReadStampFile():
  """Return the contents of the stamp file, or '' if it doesn't exist."""
  try:
    with open(STAMP_FILE, 'r') as f:
      return f.read().rstrip()
  except IOError:
    return ''

def WriteStampFile(s):
  """Write s to the stamp file."""
  if not os.path.exists(os.path.dirname(STAMP_FILE)):
    os.makedirs(os.path.dirname(STAMP_FILE))
  with open(STAMP_FILE, 'w') as f:
    f.write(s)
    f.write('\n')

def GetSvnRevision(svn_repo):
  """Returns current revision of the svn repo at svn_repo."""
  svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True)
  m = re.search(r'Revision: (\d+)', svn_info)
  return m.group(1)

def RmTree(dir):
  """Delete dir."""
  def ChmodAndRetry(func, path, _):
    # Subversion can leave read-only files around.
    if not os.access(path, os.W_OK):
      os.chmod(path, stat.S_IWUSR)
      return func(path)
    raise

  shutil.rmtree(dir, onerror=ChmodAndRetry)

def RunCommand(command, msvc_arch=None, env=None, fail_hard=True):
  """Run command and return success (True) or failure; or if fail_hard is
     True, exit on failure.  If msvc_arch is set, runs the command in a
     shell with the msvc tools for that architecture."""

  if msvc_arch and sys.platform == 'win32':
    command = GetVSVersion().SetupScript(msvc_arch) + ['&&'] + command

  # https://docs.python.org/2/library/subprocess.html:
  # "On Unix with shell=True [...] if args is a sequence, the first item
  # specifies the command string, and any additional items will be treated as
  # additional arguments to the shell itself.  That is to say, Popen does the
  # equivalent of:
  #   Popen(['/bin/sh', '-c', args[0], args[1], ...])"
  #
  # We want to pass additional arguments to command[0], not to the shell,
  # so manually join everything into a single string.
  # Annoyingly, for "svn co url c:\path", pipes.quote() thinks that it should
  # quote c:\path but svn can't handle quoted paths on Windows.  Since on
  # Windows follow-on args are passed to args[0] instead of the shell, don't
  # do the single-string transformation there.
  if sys.platform != 'win32':
    command = ' '.join([pipes.quote(c) for c in command])
  print 'Running', command
  if subprocess.call(command, env=env, shell=True) == 0:
    return True
  print 'Failed.'
  if fail_hard:
    sys.exit(1)
  return False

def CopyFile(src, dst):
  """Copy a file from src to dst."""
  shutil.copy(src, dst)
  print "Copying %s to %s" % (src, dst)

def CopyDirectoryContents(src, dst, filename_filter=None):
  """Copy the files from directory src to dst
  with an optional filename filter."""
  dst = os.path.realpath(dst)  # realpath() in case dst ends in /..
  if not os.path.exists(dst):
    os.makedirs(dst)
  for root, _, files in os.walk(src):
    for f in files:
      if filename_filter and not re.match(filename_filter, f):
        continue
      CopyFile(os.path.join(root, f), dst)

def Checkout(name, url, dir):
  """Checkout the SVN module at url into dir. Use name for the log message."""
  print "Checking out %s r%s into '%s'" % (name, CLANG_REVISION, dir)

  command = ['svn', 'checkout', '--force', url + '@' + CLANG_REVISION, dir]
  if RunCommand(command, fail_hard=False):
    return

  if os.path.isdir(dir):
    print "Removing %s." % (dir)
    RmTree(dir)

  print "Retrying."
  RunCommand(command)

def DeleteChromeToolsShim():
  OLD_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'zzz-chrometools')
  shutil.rmtree(OLD_SHIM_DIR, ignore_errors=True)
  shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)

def CreateChromeToolsShim():
  """Hooks the Chrome tools into the LLVM build.

  Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build
  detects implicit tools in the tools subdirectory, so this helper install a
  shim CMakeLists.txt that forwards to the real directory for the Chrome tools.

  Note that the shim directory name intentionally has no - or _. The implicit
  tool detection logic munges them in a weird way."""
  assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
  os.mkdir(CHROME_TOOLS_SHIM_DIR)
  with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f:
    f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
            'Do not edit.\n')
    f.write('# Since tools/clang is located in another directory, use the \n')
    f.write('# two arg version to specify where build artifacts go. CMake\n')
    f.write('# disallows reuse of the same binary dir for multiple source\n')
    f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
    f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
    f.write('if (CHROMIUM_TOOLS_SRC)\n')
    f.write('  add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
              '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
    f.write('endif (CHROMIUM_TOOLS_SRC)\n')

def MaybeDownloadHostGcc(args):
  """Downloads gcc 4.8.2 if needed and makes sure args.gcc_toolchain is set."""
  if not sys.platform.startswith('linux') or args.gcc_toolchain:
    return

  if subprocess.check_output(['gcc', '-dumpversion']).rstrip() < '4.7.0':
    # We need a newer gcc version.
    gcc_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gcc482')
    if not os.path.exists(gcc_dir):
      print 'Downloading pre-built GCC 4.8.2...'
      DownloadAndUnpack(CDS_URL + '/tools/gcc482.tgz', LLVM_BUILD_TOOLS_DIR)
    args.gcc_toolchain = gcc_dir
  else:
    # Always set gcc_toolchain; llvm-symbolizer needs the bundled libstdc++.
    args.gcc_toolchain = \
        os.path.dirname(os.path.dirname(distutils.spawn.find_executable('gcc')))

def AddCMakeToPath():
  """Download CMake and add it to PATH."""
  if sys.platform == 'win32':
    zip_name = 'cmake-3.2.2-win32-x86.zip'
    cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR,
                             'cmake-3.2.2-win32-x86', 'bin')
  else:
    suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux'
    zip_name = 'cmake322_%s.tgz' % suffix
    cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake322', 'bin')
  if not os.path.exists(cmake_dir):
    DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
  os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')

vs_version = None
def GetVSVersion():
  global vs_version
  if vs_version:
    return vs_version

  # Try using the toolchain in depot_tools.
  # This sets environment variables used by SelectVisualStudioVersion below.
  sys.path.append(os.path.join(CHROMIUM_DIR, 'build'))
  import vs_toolchain
  vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()

  # Use gyp to find the MSVS installation, either in depot_tools as per above,
  # or a system-wide installation otherwise.
  sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib'))
  import gyp.MSVSVersion
  vs_version = gyp.MSVSVersion.SelectVisualStudioVersion('2013')
  return vs_version

def UpdateClang(args):
  print 'Updating Clang to %s...' % PACKAGE_VERSION

  need_gold_plugin = 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ or (
      sys.platform.startswith('linux') and
      'buildtype=Official' in os.environ.get('GYP_DEFINES', '') and
      'branding=Chrome' in os.environ.get('GYP_DEFINES', ''))

  if ReadStampFile() == PACKAGE_VERSION:
    print 'Clang is already up to date.'
    if not need_gold_plugin or os.path.exists(
        os.path.join(LLVM_BUILD_DIR, "lib/LLVMgold.so")):
      return 0

  # Reset the stamp file in case the build is unsuccessful.
  WriteStampFile('')

  if not args.force_local_build:
    cds_file = "clang-%s.tgz" %  PACKAGE_VERSION
    if sys.platform == 'win32':
      cds_full_url = CDS_URL + '/Win/' + cds_file
    elif sys.platform == 'darwin':
      cds_full_url = CDS_URL + '/Mac/' + cds_file
    else:
      assert sys.platform.startswith('linux')
      cds_full_url = CDS_URL + '/Linux_x64/' + cds_file

    # Check if there's a prebuilt binary and if so just fetch that. That's
    # faster, and goma relies on having matching binary hashes on client and
    # server too.
    print 'Trying to download prebuilt clang'

    try:
      if os.path.exists(LLVM_BUILD_DIR):
        RmTree(LLVM_BUILD_DIR)
      DownloadAndUnpack(cds_full_url, LLVM_BUILD_DIR)
      print 'clang %s unpacked' % PACKAGE_VERSION
      # Download the gold plugin if requested to by an environment variable.
      # This is used by the CFI ClusterFuzz bot, and it's required for official
      # builds on linux.
      if need_gold_plugin:
        RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
      WriteStampFile(PACKAGE_VERSION)
      return 0
    except urllib2.HTTPError:
      print 'Did not find prebuilt clang %s, building locally' % cds_file

  if args.with_android and not os.path.exists(ANDROID_NDK_DIR):
    print 'Android NDK not found at ' + ANDROID_NDK_DIR
    print 'The Android NDK is needed to build a Clang whose -fsanitize=address'
    print 'works on Android. See '
    print 'http://code.google.com/p/chromium/wiki/AndroidBuildInstructions'
    print 'for how to install the NDK, or pass --without-android.'
    return 1

  MaybeDownloadHostGcc(args)
  AddCMakeToPath()

  DeleteChromeToolsShim()

  Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
  Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
  if sys.platform == 'win32':
    Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
  Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
  if sys.platform == 'darwin':
    # clang needs a libc++ checkout, else -stdlib=libc++ won't find includes
    # (i.e. this is needed for bootstrap builds).
    Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR)
    # While we're bundling our own libc++ on OS X, we need to compile libc++abi
    # into it too (since OS X 10.6 doesn't have libc++abi.dylib either).
    Checkout('libcxxabi', LLVM_REPO_URL + '/libcxxabi/trunk', LIBCXXABI_DIR)

  cc, cxx = None, None
  libstdcpp = None
  if args.gcc_toolchain:  # This option is only used on Linux.
    # Use the specified gcc installation for building.
    cc = os.path.join(args.gcc_toolchain, 'bin', 'gcc')
    cxx = os.path.join(args.gcc_toolchain, 'bin', 'g++')

    if not os.access(cc, os.X_OK):
      print 'Invalid --gcc-toolchain: "%s"' % args.gcc_toolchain
      print '"%s" does not appear to be valid.' % cc
      return 1

    # Set LD_LIBRARY_PATH to make auxiliary targets (tablegen, bootstrap
    # compiler, etc.) find the .so.
    libstdcpp = subprocess.check_output(
        [cxx, '-print-file-name=libstdc++.so.6']).rstrip()
    os.environ['LD_LIBRARY_PATH'] = os.path.dirname(libstdcpp)

  cflags = cxxflags = ldflags = []

  # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
  # needed, on OS X it requires libc++. clang only automatically links to libc++
  # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run
  # on OS X versions as old as 10.7.
  # TODO(thakis): Some bots are still on 10.6 (nacl...), so for now bundle
  # libc++.dylib.  Remove this once all bots are on 10.7+, then use
  # -DLLVM_ENABLE_LIBCXX=ON and change deployment_target to 10.7.
  deployment_target = ''

  if sys.platform == 'darwin':
    # When building on 10.9, /usr/include usually doesn't exist, and while
    # Xcode's clang automatically sets a sysroot, self-built clangs don't.
    cflags = ['-isysroot', subprocess.check_output(
        ['xcrun', '--show-sdk-path']).rstrip()]
    cxxflags = ['-stdlib=libc++', '-nostdinc++',
                '-I' + os.path.join(LIBCXX_DIR, 'include')] + cflags
    if args.bootstrap:
      deployment_target = '10.6'

  base_cmake_args = ['-GNinja',
                     '-DCMAKE_BUILD_TYPE=Release',
                     '-DLLVM_ENABLE_ASSERTIONS=ON',
                     '-DLLVM_ENABLE_THREADS=OFF',
                     ]

  if args.bootstrap:
    print 'Building bootstrap compiler'
    if not os.path.exists(LLVM_BOOTSTRAP_DIR):
      os.makedirs(LLVM_BOOTSTRAP_DIR)
    os.chdir(LLVM_BOOTSTRAP_DIR)
    bootstrap_args = base_cmake_args + [
        '-DLLVM_TARGETS_TO_BUILD=host',
        '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
        '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
        '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
        ]
    if cc is not None:  bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
    if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
    RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64')
    RunCommand(['ninja'], msvc_arch='x64')
    if args.run_tests:
      RunCommand(['ninja', 'check-all'], msvc_arch='x64')
    RunCommand(['ninja', 'install'], msvc_arch='x64')
    if args.gcc_toolchain:
      # Copy that gcc's stdlibc++.so.6 to the build dir, so the bootstrap
      # compiler can start.
      CopyFile(libstdcpp, os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'lib'))

    if sys.platform == 'win32':
      cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
      cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
      # CMake has a hard time with backslashes in compiler paths:
      # https://stackoverflow.com/questions/13050827
      cc = cc.replace('\\', '/')
      cxx = cxx.replace('\\', '/')
    else:
      cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang')
      cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++')

    if args.gcc_toolchain:
      # Tell the bootstrap compiler to use a specific gcc prefix to search
      # for standard library headers and shared object files.
      cflags = ['--gcc-toolchain=' + args.gcc_toolchain]
      cxxflags = ['--gcc-toolchain=' + args.gcc_toolchain]
    print 'Building final compiler'

  if sys.platform == 'darwin':
    # Build libc++.dylib while some bots are still on OS X 10.6.
    libcxxbuild = os.path.join(LLVM_BUILD_DIR, 'libcxxbuild')
    if os.path.isdir(libcxxbuild):
      RmTree(libcxxbuild)
    libcxxflags = ['-O3', '-std=c++11', '-fstrict-aliasing']

    # libcxx and libcxxabi both have a file stdexcept.cpp, so put their .o files
    # into different subdirectories.
    os.makedirs(os.path.join(libcxxbuild, 'libcxx'))
    os.chdir(os.path.join(libcxxbuild, 'libcxx'))
    RunCommand(['c++', '-c'] + cxxflags + libcxxflags +
                glob.glob(os.path.join(LIBCXX_DIR, 'src', '*.cpp')))

    os.makedirs(os.path.join(libcxxbuild, 'libcxxabi'))
    os.chdir(os.path.join(libcxxbuild, 'libcxxabi'))
    RunCommand(['c++', '-c'] + cxxflags + libcxxflags +
               glob.glob(os.path.join(LIBCXXABI_DIR, 'src', '*.cpp')) +
               ['-I' + os.path.join(LIBCXXABI_DIR, 'include')])

    os.chdir(libcxxbuild)
    libdir = os.path.join(LIBCXX_DIR, 'lib')
    RunCommand(['cc'] + glob.glob('libcxx/*.o') + glob.glob('libcxxabi/*.o') +
        ['-o', 'libc++.1.dylib', '-dynamiclib', '-nodefaultlibs',
         '-current_version', '1', '-compatibility_version', '1', '-lSystem',
         '-install_name', '@executable_path/libc++.dylib',
         '-Wl,-unexported_symbols_list,' + libdir + '/libc++unexp.exp',
         '-Wl,-force_symbols_not_weak_list,' + libdir + '/notweak.exp',
         '-Wl,-force_symbols_weak_list,' + libdir + '/weak.exp'])
    if os.path.exists('libc++.dylib'):
      os.remove('libc++.dylib')
    os.symlink('libc++.1.dylib', 'libc++.dylib')
    ldflags += ['-stdlib=libc++', '-L' + libcxxbuild]

    if args.bootstrap:
      # Now that the libc++ headers have been installed and libc++.dylib is
      # built, delete the libc++ checkout again so that it's not part of the
      # main build below -- the libc++(abi) tests don't pass on OS X in
      # bootstrap builds (http://llvm.org/PR24068)
      RmTree(LIBCXX_DIR)
      RmTree(LIBCXXABI_DIR)
      cxxflags = ['-stdlib=libc++', '-nostdinc++',
                  '-I' + os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR,
                                      'include/c++/v1')
                  ] + cflags

  # Build clang.
  binutils_incdir = ''
  if sys.platform.startswith('linux'):
    binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include')

  # If building at head, define a macro that plugins can use for #ifdefing
  # out code that builds at head, but not at CLANG_REVISION or vice versa.
  if use_head_revision:
    cflags += ['-DLLVM_FORCE_HEAD_REVISION']
    cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']

  # Pin MSan to the old ABI.
  # TODO(eugenis): Remove when MSan migrates to new ABI (crbug.com/560589).
  cxxflags += [ '-DMSAN_LINUX_X86_64_OLD_MAPPING' ]

  CreateChromeToolsShim()

  deployment_env = None
  if deployment_target:
    deployment_env = os.environ.copy()
    deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target

  cmake_args = []
  # TODO(thakis): Unconditionally append this to base_cmake_args instead once
  # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
  cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
  if cc is not None:  cc_args.append('-DCMAKE_C_COMPILER=' + cc)
  if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
  cmake_args += base_cmake_args + [
      '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
      '-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly',
      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
      '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
      '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
      '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags),
      '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
      '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
      '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]

  if not os.path.exists(LLVM_BUILD_DIR):
    os.makedirs(LLVM_BUILD_DIR)
  os.chdir(LLVM_BUILD_DIR)
  RunCommand(['cmake'] + cmake_args + [LLVM_DIR],
             msvc_arch='x64', env=deployment_env)

  if args.gcc_toolchain:
    # Copy in the right stdlibc++.so.6 so clang can start.
    if not os.path.exists(os.path.join(LLVM_BUILD_DIR, 'lib')):
      os.mkdir(os.path.join(LLVM_BUILD_DIR, 'lib'))
    libstdcpp = subprocess.check_output(
        [cxx] + cxxflags + ['-print-file-name=libstdc++.so.6']).rstrip()
    CopyFile(libstdcpp, os.path.join(LLVM_BUILD_DIR, 'lib'))

  RunCommand(['ninja'], msvc_arch='x64')

  if args.tools:
    # If any Chromium tools were built, install those now.
    RunCommand(['ninja', 'cr-install'], msvc_arch='x64')

  if sys.platform == 'darwin':
    CopyFile(os.path.join(libcxxbuild, 'libc++.1.dylib'),
             os.path.join(LLVM_BUILD_DIR, 'bin'))
    # See http://crbug.com/256342
    RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
  elif sys.platform.startswith('linux'):
    RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])

  # Do an out-of-tree build of compiler-rt.
  # On Windows, this is used to get the 32-bit ASan run-time.
  # TODO(hans): Remove once the regular build above produces this.
  # On Mac and Linux, this is used to get the regular 64-bit run-time.
  # Do a clobbered build due to cmake changes.
  if os.path.isdir(COMPILER_RT_BUILD_DIR):
    RmTree(COMPILER_RT_BUILD_DIR)
  os.makedirs(COMPILER_RT_BUILD_DIR)
  os.chdir(COMPILER_RT_BUILD_DIR)
  # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
  # above).
  #if args.bootstrap and sys.platform == 'win32':
    # The bootstrap compiler produces 64-bit binaries by default.
    #cflags += ['-m32']
    #cxxflags += ['-m32']
  compiler_rt_args = base_cmake_args + [
      '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
      '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)]
  if sys.platform != 'win32':
    compiler_rt_args += ['-DLLVM_CONFIG_PATH=' +
                         os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config'),
                        '-DSANITIZER_MIN_OSX_VERSION="10.7"']
  # compiler-rt is part of the llvm checkout on Windows but a stand-alone
  # directory elsewhere, see the TODO above COMPILER_RT_DIR.
  RunCommand(['cmake'] + compiler_rt_args +
             [LLVM_DIR if sys.platform == 'win32' else COMPILER_RT_DIR],
             msvc_arch='x86', env=deployment_env)
  RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')

  # Copy select output to the main tree.
  # TODO(hans): Make this (and the .gypi and .isolate files) version number
  # independent.
  if sys.platform == 'win32':
    platform = 'windows'
  elif sys.platform == 'darwin':
    platform = 'darwin'
  else:
    assert sys.platform.startswith('linux')
    platform = 'linux'
  asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', platform)
  if sys.platform == 'win32':
    # TODO(thakis): This too is due to compiler-rt being part of the checkout
    # on Windows, see TODO above COMPILER_RT_DIR.
    asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
                                       VERSION, 'lib', platform)
  asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
                                     VERSION, 'lib', platform)
  # Blacklists:
  CopyDirectoryContents(os.path.join(asan_rt_lib_src_dir, '..', '..'),
                        os.path.join(asan_rt_lib_dst_dir, '..', '..'),
                        r'^.*blacklist\.txt$')
  # Headers:
  if sys.platform != 'win32':
    CopyDirectoryContents(
        os.path.join(COMPILER_RT_BUILD_DIR, 'include/sanitizer'),
        os.path.join(LLVM_BUILD_DIR, 'lib/clang', VERSION, 'include/sanitizer'))
  # Static and dynamic libraries:
  CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir)

  if sys.platform == 'win32':
    # Make an extra copy of the sanitizer headers, to be put on the include path
    # of the fallback compiler.
    sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
                                         VERSION, 'include', 'sanitizer')
    aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
                                             VERSION, 'include_sanitizer',
                                             'sanitizer')
    if not os.path.exists(aux_sanitizer_include_dir):
      os.makedirs(aux_sanitizer_include_dir)
    for _, _, files in os.walk(sanitizer_include_dir):
      for f in files:
        CopyFile(os.path.join(sanitizer_include_dir, f),
                 aux_sanitizer_include_dir)

  if args.with_android:
    make_toolchain = os.path.join(
        ANDROID_NDK_DIR, 'build', 'tools', 'make-standalone-toolchain.sh')
    for target_arch in ['aarch64', 'arm', 'i686']:
      # Make standalone Android toolchain for target_arch.
      toolchain_dir = os.path.join(
          LLVM_BUILD_DIR, 'android-toolchain-' + target_arch)
      RunCommand([
          make_toolchain,
          '--platform=android-' + ('21' if target_arch == 'aarch64' else '19'),
          '--install-dir="%s"' % toolchain_dir,
          '--system=linux-x86_64',
          '--stl=stlport',
          '--toolchain=' + {
              'aarch64': 'aarch64-linux-android-4.9',
              'arm': 'arm-linux-androideabi-4.9',
              'i686': 'x86-4.9',
          }[target_arch]])
      # Android NDK r9d copies a broken unwind.h into the toolchain, see
      # http://crbug.com/357890
      for f in glob.glob(os.path.join(toolchain_dir, 'include/c++/*/unwind.h')):
        os.remove(f)

      # Build ASan runtime for Android in a separate build tree.
      build_dir = os.path.join(LLVM_BUILD_DIR, 'android-' + target_arch)
      if not os.path.exists(build_dir):
        os.mkdir(os.path.join(build_dir))
      os.chdir(build_dir)
      if os.path.exists('CMakeCache.txt'):
        os.remove('CMakeCache.txt')

      cflags = ['--target=%s-linux-androideabi' % target_arch,
                '--sysroot=%s/sysroot' % toolchain_dir,
                '-B%s' % toolchain_dir]
      android_args = base_cmake_args + [
        '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
        '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
        '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
        '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
        '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
        '-DANDROID=1']
      RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR])
      RunCommand(['ninja', 'libclang_rt.asan-%s-android.so' % target_arch])

      # And copy it into the main build tree.
      runtime = 'libclang_rt.asan-%s-android.so' % target_arch
      for root, _, files in os.walk(build_dir):
        if runtime in files:
          shutil.copy(os.path.join(root, runtime), asan_rt_lib_dst_dir)

  # Run tests.
  if args.run_tests or use_head_revision:
    os.chdir(LLVM_BUILD_DIR)
    RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64')
  if args.run_tests:
    os.chdir(LLVM_BUILD_DIR)
    RunCommand(['ninja', 'check-all'], msvc_arch='x64')

  WriteStampFile(PACKAGE_VERSION)
  print 'Clang update was successful.'
  return 0

def main():
  parser = argparse.ArgumentParser(description='Build Clang.')
  parser.add_argument('--bootstrap', action='store_true',
                      help='first build clang with CC, then with itself.')
  parser.add_argument('--if-needed', action='store_true',
                      help="run only if the script thinks clang is needed")
  parser.add_argument('--force-local-build', action='store_true',
                      help="don't try to download prebuild binaries")
  parser.add_argument('--gcc-toolchain', help='set the version for which gcc '
                      'version be used for building; --gcc-toolchain=/opt/foo '
                      'picks /opt/foo/bin/gcc')
  parser.add_argument('--print-revision', action='store_true',
                      help='print current clang revision and exit.')
  parser.add_argument('--print-clang-version', action='store_true',
                      help='print current clang version (e.g. x.y.z) and exit.')
  parser.add_argument('--run-tests', action='store_true',
                      help='run tests after building; only for local builds')
  parser.add_argument('--tools', nargs='*',
                      help='select which chrome tools to build',
                      default=['plugins', 'blink_gc_plugin'])
  parser.add_argument('--without-android', action='store_false',
                      help='don\tt build Android ASan runtime (linux only)',
                      dest='with_android',
                      default=sys.platform.startswith('linux'))
  args = parser.parse_args()

  if args.if_needed:
    is_clang_required = False
    # clang is always used on Mac and Linux.
    if sys.platform == 'darwin' or sys.platform.startswith('linux'):
      is_clang_required = True
    # clang requested via $GYP_DEFINES.
    if re.search(r'\b(clang|asan|lsan|msan|tsan)=1',
                 os.environ.get('GYP_DEFINES', '')):
      is_clang_required = True
    # clang previously downloaded, keep it up-to-date.
    # If you don't want this, delete third_party/llvm-build on your machine.
    if os.path.isdir(LLVM_BUILD_DIR):
      is_clang_required = True
    if not is_clang_required:
      return 0
    if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')):
      print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
      return 0

  global CLANG_REVISION, PACKAGE_VERSION
  if args.print_revision:
    if use_head_revision:
      print GetSvnRevision(LLVM_DIR)
    else:
      print PACKAGE_VERSION
    return 0

  if args.print_clang_version:
    sys.stdout.write(VERSION)
    return 0

  # Don't buffer stdout, so that print statements are immediately flushed.
  # Do this only after --print-revision has been handled, else we'll get
  # an error message when this script is run from gn for some reason.
  sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

  if use_head_revision:
    # Use a real revision number rather than HEAD to make sure that the stamp
    # file logic works.
    CLANG_REVISION = GetSvnRevision(LLVM_REPO_URL)
    PACKAGE_VERSION = CLANG_REVISION + '-0'

    args.force_local_build = True
    if 'OS=android' not in os.environ.get('GYP_DEFINES', ''):
      # Only build the Android ASan rt on ToT bots when targetting Android.
      args.with_android = False

  return UpdateClang(args)

if __name__ == '__main__':
  sys.exit(main())


text:
"""
    ------------------------------------------------------------------------
    Routine to translate RA and DEC sky coordinates to X, Y pixel values in
    multiprocessing MPI mode

    Usage: mpiexec -np <ncpus> python sky2pix.py in.fits in_rd_deg.cat --quiet

    Input:
        ncpus: Number of physical cores or processers (or processes)
        image: Input image with basic header keywords
        skyfile: Input file with (ra, dec) pixel value in column 1 and 2

    [Options]:
        --help: help
        --version: program version
        --verbose: show result messages
        --quiet: don't show result messages
        --filename: output file name (default is pix2sky.dat)
        --degree: (ra, dec) in degrees? (default is yes)

    Output:
        sky2pix.out: Output file with (ra, dec) and corresponding (x, y)
        pixel values

    Author:
        Navtej Singh

    Organization:
        Centre for Astronomy, National University of Ireland, Galway, Ireland

    Version:
        10 January 2012     1.0     Original version
    ------------------------------------------------------------------------
"""

# Load python modules to be used in the routine
from optparse import OptionParser
import sky2pix_mpi as sm

# Entry point for SKY2PIX utility
if __name__ == '__main__':
    usage = "Usage: mpiexec -np ncpus python %prog [options] image skyfile"
    description = "Description. Utility to convert RA/DEC sky coordinates to X/Y pixel values in multiprocessing MPI mode."
    parser = OptionParser(usage = usage, version = "%prog 1.0", description = description)
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose", default = False,
                      help = "print result messages to stdout"
                      )
    parser.add_option("-q", "--quiet",
                    action="store_false", dest="verbose", default = True,
                    help = "don't print result messages to stdout"
                    )
    parser.add_option("-d", "--degree", dest = "degree", metavar="DEGREE",
                    action="store", help = "ra/dec in degree? [default is yes]",
                    choices=['yes', 'no'], default = 'yes'
                    )
    parser.add_option("-f", "--filename", dest = "filename",
                    action='store', metavar="FILE", help = "output file name [default is sky2pix.out]"
                    )
    (options, args) = parser.parse_args()

    # Check for number of input arguments
    if len( args ) != 2:
        parser.error("Incorrect number of arguments. Check help for more details.")

    sm.sky2pix(args[0], args[1], options.degree, options.filename, options.verbose)