private string GetProperties(ArgumentOptions arguments)
		{
			return string.Format("-Properties \"OutDir={0};{1}{2}\"",
				arguments.OutDir,
				arguments.Properties,
				string.IsNullOrWhiteSpace(AdditionalProperties) ? "" : ";" + AdditionalProperties
			);
		}
		public static PackageOptions LoadOrDefault(ArgumentOptions arguments)
		{
			var file = Path.Combine(arguments.WorkingDirectory, "package.builder.json");
			var options = (File.Exists(file))
				? JsonConvert.DeserializeObject<PackageOptions>(File.ReadAllText(file))
				: new PackageOptions();

			if (arguments.ForcePublishing)
				options.Publish.PublishOnBuild = true;

			return options;
		}
		public string GetBuildCommandArgs(ArgumentOptions arguments)
		{
			return string.Format(@"pack ""{0}"" {1} {2} {3} {4} -NonInteractive {5} {6} {7}",
				GetProjectOrNuspecFile(arguments),
				Symbols ? "-Symbols" : "",
				NoDefaultExcludes ? "-NoDefaultExcludes" : "",
				GetVerbosity(),
				GetProperties(arguments),
				GetOutputDirectory(arguments),
				GetBasePath(arguments),
				IncludeReferencedProjects ? "-IncludeReferencedProjects" : ""
			);
		}
		private static void PushPackage(ArgumentOptions args, PackageOptions options)
		{
			var startInfo = new ProcessStartInfo
			{
				Arguments = options.GetPushCommandArgs(args),
				FileName = Path.Combine(args.PathToNuGet, "NuGet.exe"),
				CreateNoWindow = false,
				UseShellExecute = false,
				WorkingDirectory = args.WorkingDirectory
			};

			Console.WriteLine("{0} {1}", startInfo.FileName, startInfo.Arguments);
			using (var process = Process.Start(startInfo))
			{
				process.WaitForExit(5000);
			}
		}
		//Publish Get-ChildItem -Path "C:\Users\Lars\Documents\visual studio 2013\Projects\ClassLibrary2" -File publish_*.cmd | Foreach { & $_.FullName 'apikey', 'https://mysource' }
		private static void CreatePublishCommand(ArgumentOptions args, PackageOptions options)
		{
			var solutionDir = Directory.GetParent(args.PathToNuGet + @"\..\..\..\").FullName;
			var outputFile = Path.Combine(solutionDir, string.Format("publish_{0}.cmd", args.TargetName));
			Console.WriteLine(outputFile);
			if (File.Exists(outputFile))
				File.Delete(outputFile);

			if (string.IsNullOrWhiteSpace(args.OverrideApiKey) && string.IsNullOrWhiteSpace(options.Publish.ApiKey))
				args.OverrideApiKey = "%1";

			if (string.IsNullOrWhiteSpace(args.OverrideSource) && string.IsNullOrWhiteSpace(options.Publish.Source))
				args.OverrideSource = "%2";

			File.WriteAllText(
				outputFile, 
				string.Format("\"{0}\" {1}", Path.Combine(args.PathToNuGet, "NuGet.exe"), options.GetPushCommandArgs(args))
			);
		}
		static int Main(string[] args)
		{
			var arguments = new ArgumentOptions();
			if (!Parser.Default.ParseArguments(args, arguments))
			{
				arguments.GetUsage();
				return 1;
			}

			var options = PackageOptions.LoadOrDefault(arguments);
			BuildPackage(arguments, options);
			if (options.Publish.PublishOnBuild)
			{
				PushPackage(arguments, options);
			}

			if (arguments.GeneratePublishCommand)
			{
				CreatePublishCommand(arguments, options);
			}

			return 0;
		}
		private string GetPackageSource(ArgumentOptions arguments)
		{
			var source = arguments.OverrideSource == null 
				? Publish.Source 
				: arguments.OverrideSource;

			return !string.IsNullOrWhiteSpace(source)
				? string.Format("-s {0}", source)
				: string.Empty;
		}
		private string GetPackagesToPush(ArgumentOptions arguments)
		{
			return string.Format("{0}\\{1}.*.nupkg", arguments.OutDir, arguments.TargetName);
		}
		private string GetBasePath(ArgumentOptions arguments)
		{
			return string.Format("-basepath \"{0}\"", arguments.OutDir);
		}
		private string GetOutputDirectory(ArgumentOptions arguments)
		{
			return string.Format("-OutputDirectory \"{0}\"", arguments.OutDir);
		}
		private string GetProjectOrNuspecFile(ArgumentOptions arguments)
		{
			return Path.Combine(arguments.WorkingDirectory, arguments.TargetName + ((UseNuspecFileOnly) ? ".nuspec" : arguments.ProjectExt));
		}
		public string GetPushCommandArgs(ArgumentOptions arguments)
		{
			return string.Format(@"push ""{0}"" {1} {2} {3} {4} -NonInteractive",
				GetPackagesToPush(arguments),
				GetApiKey(arguments),
				GetPackageSource(arguments),
				GetTimeout(),
				GetVerbosity()
			);
		}
		private string GetApiKey(ArgumentOptions arguments)
		{
			return arguments.OverrideApiKey == null 
				? Publish.ApiKey 
				: arguments.OverrideApiKey;
		}