public override bool Equals(object Object)
        {
            if (this == Object)
            {
                return(true);
            }

            if (Object == null)
            {
                return(false);
            }

            if (Object.GetType() != typeof(ENNoteRef))
            {
                return(false);
            }

            ENNoteRef other = (ENNoteRef)Object;

            if (other.Type == this.Type && this.Guid == other.Guid && (this.LinkedNotebook == other.LinkedNotebook || other.LinkedNotebook.IsEqual(this.LinkedNotebook)))
            {
                return(true);
            }

            return(false);
        }
		public static ENNoteRef NoteRefFromData(byte[] data)
		{
			MemoryStream memStream = new MemoryStream();
			BinaryFormatter binForm = new BinaryFormatter();
			memStream.Write(data, 0, data.Length);
			memStream.Seek(0, SeekOrigin.Begin);
			ENNoteRef obj = new ENNoteRef();
			obj = (ENNoteRef)binForm.Deserialize(memStream);
			return obj;
		}
        public static ENNoteRef NoteRefFromData(byte[] data)
        {
            MemoryStream    memStream = new MemoryStream();
            BinaryFormatter binForm   = new BinaryFormatter();

            memStream.Write(data, 0, data.Length);
            memStream.Seek(0, SeekOrigin.Begin);
            ENNoteRef obj = new ENNoteRef();

            obj = (ENNoteRef)binForm.Deserialize(memStream);
            return(obj);
        }
		public ENNoteRef UploadNote(ENNote note, ENSession.UploadPolicy policy, ENNotebook notebook, ENNoteRef noteToReplace)
		{

			if (note == null)
			{
				ENSDKLogger.ENSDKLogError("Must specify note");
				throw new ENInvalidDataException();
			}

			if (policy == UploadPolicy.Replace && noteToReplace == null || policy == UploadPolicy.ReplaceOrCreate && noteToReplace == null)
			{
				ENSDKLogger.ENSDKLogError("Must specify existing ID when requesting a replacement policy");
				throw new ENInvalidDataException();
			}

			if (policy == UploadPolicy.Create && noteToReplace != null)
			{
				ENSDKLogger.ENSDKLogError("Can't use create policy when specifying an existing note ref. Ignoring.");
				noteToReplace = null;
			}

			if (notebook != null && !notebook.AllowsWriting)
			{
				var errorMessage = "A specified notebook must not be readonly";
				ENSDKLogger.ENSDKLogError(errorMessage);
				throw new ArgumentException(errorMessage);
			}

			if (!IsAuthenticated)
			{
				throw new ENAuthExpiredException();
			}

			// Run size validation on any resources included with the note. This is done at upload time because
			// the sizes are a function of the user's service level, which can change.
			if (!note.ValidateForLimits())
			{
				ENSDKLogger.ENSDKLogError("Note failed limits validation. Cannot upload.");
				throw new ENLimitReachedException();
			}

			ENSessionUploadContext context = new ENSessionUploadContext();
			if (noteToReplace != null)
			{
				context.Note = note.EDAMNoteToReplaceServiceNoteGUID(noteToReplace.Guid);
			}
			else
			{
				context.Note = note.EDAMNote();
			}
			context.RefToReplace = noteToReplace;
			context.Notebook = notebook;
			context.Policy = policy;

			context = UploadNote_DetermineDestination(context);
			return context.NoteRef;
		}
		internal string AuthenticationTokenForNoteRef(ENNoteRef noteRef)
		{
			// Note that we may need to go over the wire to get a noncached token.

			string token = null;

			// Because this method is called from outside the normal exception handlers in the user/note
			// store objects, it requires protection from EDAM and Thrift exceptions.
			try
			{
				if (noteRef.Type == ENNoteRef.ENNoteRefType.TypePersonal)
				{
					token = PrimaryAuthenticationToken;
				}
				else if (noteRef.Type == ENNoteRef.ENNoteRefType.TypeBusiness)
				{
					token = ValidBusinessAuthenticationResult().AuthenticationToken;
				}
				else if (noteRef.Type == ENNoteRef.ENNoteRefType.TypeShared)
				{
					token = AuthenticationTokenForLinkedNotebookRef(noteRef.LinkedNotebook);
				}
			}
			catch (Exception ex)
			{
				ENSDKLogger.ENSDKLogError(string.Format("Caught exception getting auth token for note ref {0}: {1}", noteRef, ex.Message));
				token = null;
			}

			return token;
		}
		internal string ShardIdForNoteRef(ENNoteRef noteRef)
		{
			if (noteRef.Type == ENNoteRef.ENNoteRefType.TypePersonal)
			{
				return EdamUser.ShardId;
			}
			else if (noteRef.Type == ENNoteRef.ENNoteRefType.TypeBusiness)
			{
				return BusinessShardId;
			}
			else if (noteRef.Type == ENNoteRef.ENNoteRefType.TypeShared)
			{
				return noteRef.LinkedNotebook.ShardId;
			}
			return null;
		}
		internal ENNoteStoreClient NoteStoreForNoteRef(ENNoteRef noteRef)
		{
			if (noteRef.Type == ENNoteRef.ENNoteRefType.TypePersonal)
			{
				return PrimaryNoteStore;
			}
			else if (noteRef.Type == ENNoteRef.ENNoteRefType.TypeBusiness)
			{
				return BusinessNoteStore;
			}
			else if (noteRef.Type == ENNoteRef.ENNoteRefType.TypeShared)
			{
				ENLinkedNoteStoreClient linkedClient = (EvernoteSDK.ENLinkedNoteStoreClient)ENLinkedNoteStoreClient.NoteStoreClientForLinkedNotebookRef(noteRef.LinkedNotebook);
				linkedClient.DelegateObj = (EvernoteSDK.ENLinkedNoteStoreClient.IENLinkedNoteStoreClient)this;
				return linkedClient;
			}
			return null;
		}
		public byte[] DownloadThumbnailForNote(ENNoteRef noteRef, int maxDimension = 0)
		{
			if (noteRef == null)
			{
				ENSDKLogger.ENSDKLogError("noteRef parameter is required to get download thumbnail");
				throw new ENInvalidDataException();
			}

			if (!IsAuthenticated)
			{
				throw new ENAuthExpiredException();
			}

			// Clamp the maxDimension. Let 0 through as a sentinel for unspecified, and if the value is
			// already greater than the max we provide, then remove the parameter.
			if (maxDimension >= 300)
			{
				maxDimension = 0;
			}

			// Get the info we need for this note ref, then construct a standard request for the thumbnail.
			string authToken = AuthenticationTokenForNoteRef(noteRef);
			string shardId = ShardIdForNoteRef(noteRef);

			if (authToken == null || shardId == null)
			{
				return null;
			}

			// Only append the size param if we are explicitly providing one.
			string sizeParam = string.Empty;
			if (maxDimension > 0)
			{
				sizeParam = string.Format("?size={0}", maxDimension);
			}

			try
			{
				// Create a request using a URL that can receive a post. 
				WebRequest request = WebRequest.Create(string.Format("https://{0}/shard/{1}/thm/note/{2}{3}", SessionHost, shardId, noteRef.Guid, sizeParam));
				// Set the Method property of the request to POST.
				request.Method = "POST";
				// Create POST data and convert it to a byte array.
				string postData = "auth=" + authToken;
				byte[] byteArray = Encoding.Default.GetBytes(postData);
				// Set the ContentType property of the WebRequest.
				request.ContentType = "application/x-www-form-urlencoded";
				// Set the ContentLength property of the WebRequest.
				request.ContentLength = byteArray.Length;
				// Get the request stream.
				Stream dataStream = request.GetRequestStream();
				// Write the data to the request stream.
				dataStream.Write(byteArray, 0, byteArray.Length);
				// Close the Stream object.
				dataStream.Close();
				// Get the response.
				WebResponse response = request.GetResponse();
				// Get the stream containing content returned by the server.
				dataStream = response.GetResponseStream();
				// Open the stream using a StreamReader for easy access.
				StreamReader reader = new StreamReader(dataStream, Encoding.Default);
				// Read the content.
				string responseFromServer = reader.ReadToEnd();
				// Translate to byte array.
				byte[] imageBytes = Encoding.Default.GetBytes(responseFromServer);
				string strModified = System.Text.Encoding.Default.GetString(imageBytes);
				byte[] ba = Encoding.Default.GetBytes(strModified);
				// Clean up the streams.
				reader.Close();
				dataStream.Close();
				response.Close();
				return imageBytes;
			}
			catch (Exception)
			{
				return null;
			}
		}
		public ENNote DownloadNote(ENNoteRef noteRef)
		{
			if (noteRef == null)
			{
				ENSDKLogger.ENSDKLogError("noteRef parameter is required to get download note");
				throw new ENInvalidDataException();
			}

			if (!IsAuthenticated)
			{
				throw new ENAuthExpiredException();
			}

			// Find the note store client that works with this note.
			ENNoteStoreClient noteStore = NoteStoreForNoteRef(noteRef);

			// Fetch by guid. Always get the content and resources.
			try
			{
				Note note = noteStore.GetNote(noteRef.Guid, true, true, false, false);
				// Create an ENNote from the EDAMNote.
				ENNote resultNote = new ENNote(note);
				return resultNote;
			}
			catch (Exception)
			{
				return null;
			}
		}
		private ENSessionFindNotesContext FindNotes_ProcessResults(ENSessionFindNotesContext context)
		{
			// OK, now we have a complete list of note refs objects. If we need to do a local sort, then do so.
			if (context.order.HasFlag(SortOrder.RecentlyCreated))
			{
				if (context.sortAscending)
				{
					context.findMetadataResults.Sort((x, y) => x.Created.CompareTo(y.Created));
				}
				else
				{
					context.findMetadataResults.Sort((x, y) => y.Created.CompareTo(x.Created));
				}
			}
			else if (context.order.HasFlag(SortOrder.RecentlyCreated))
			{
				if (context.sortAscending)
				{
					context.findMetadataResults.Sort((x, y) => x.Updated.CompareTo(y.Updated));
				}
				else
				{
					context.findMetadataResults.Sort((x, y) => y.Updated.CompareTo(x.Updated));
				}
			}
			else
			{
				if (context.sortAscending)
				{
					context.findMetadataResults.Sort((x, y) => x.Title.CompareTo(y.Title));
				}
				else
				{
					context.findMetadataResults.Sort((x, y) => y.Title.CompareTo(x.Title));
				}
			}

			// Prepare a dictionary of all notebooks by GUID so lookup below is fast.
			Dictionary<string, ENNotebook> notebooksByGuid = null;
			if (context.scopeNotebook == null)
			{
				notebooksByGuid = new Dictionary<string, ENNotebook>();
				foreach (ENNotebook notebook in context.allNotebooks)
				{
					notebooksByGuid[notebook.Guid] = notebook;
				}
			}

			// Turn the metadata list into a list of note refs.
			List<ENSessionFindNotesResult> findNotesResults = new List<ENSessionFindNotesResult>();

			foreach (NoteMetadata metadata in context.findMetadataResults)
			{
				ENNoteRef @ref = new ENNoteRef();
				@ref.Guid = metadata.Guid;

				// Figure out which notebook this note belongs to. (If there's a scope notebook, it always belongs to that one.)
				ENNotebook notebook = null;
				if (context.scopeNotebook != null)
				{
					notebook = context.scopeNotebook;
				}
				else
				{
					notebooksByGuid.TryGetValue(metadata.NotebookGuid, out notebook);
				}
				if (notebook == null)
				{
					// This is probably a business notebook that we haven't explicitly joined, so we don't have it in our list.
					if (!(context.resultGuidsFromBusiness.Contains(metadata.Guid)))
					{
						// Oh, it's not from the business. We really can't find it. This is an error.
						ENSDKLogger.ENSDKLogError(string.Format("Found note metadata but can't determine owning notebook by guid. Metadata = {0}", metadata));
					}
					continue;
				}

				if (notebook.IsBusinessNotebook)
				{
					@ref.Type = ENNoteRef.ENNoteRefType.TypeBusiness;
					@ref.LinkedNotebook = ENLinkedNotebookRef.LinkedNotebookRefFromLinkedNotebook(notebook.LinkedNotebook);
				}
				else if (notebook.IsLinked)
				{
					@ref.Type = ENNoteRef.ENNoteRefType.TypeShared;
					@ref.LinkedNotebook = ENLinkedNotebookRef.LinkedNotebookRefFromLinkedNotebook(notebook.LinkedNotebook);
				}
				else
				{
					@ref.Type = ENNoteRef.ENNoteRefType.TypePersonal;
				}

				ENSessionFindNotesResult result = new ENSessionFindNotesResult();
				result.NoteRef = @ref;
				result.Notebook = notebook;
				result.Title = metadata.Title;
				result.Created = metadata.Created.ToDateTime();
				result.Updated = metadata.Updated.ToDateTime();

				findNotesResults.Add(result);

				// If the caller specified a max result count, and we've reached it, then stop fixing up
				// results here.
				if (context.maxResults > 0 && findNotesResults.Count > context.maxResults)
				{
					break;
				}
			}

			context.results = findNotesResults;
			return context;
		}
		public void DeleteNote(ENNoteRef noteRef)
		{
			if (!IsAuthenticated)
			{
				throw new ENAuthExpiredException();
			}

			ENNoteStoreClient noteStore = NoteStoreForNoteRef(noteRef);
			try
			{
				int usn = noteStore.DeleteNote(noteRef.Guid);
			}
			catch (Exception ex)
			{
				ENSDKLogger.ENSDKLogError(string.Format("Failed to deleteNote: {0}", ex.Message));
				throw new Exception(ex.Message, ex.InnerException);
			}
		}
		public string ShareNote(ENNoteRef noteRef)
		{
			if (!IsAuthenticated)
			{
				throw new ENAuthExpiredException();
			}

			ENNoteStoreClient noteStore = NoteStoreForNoteRef(noteRef);
			try
			{
				string noteKey = noteStore.ShareNote(noteRef.Guid);
				string shardId = ShardIdForNoteRef(noteRef);
				return ENShareUrlHelper.ShareUrlString(noteRef.Guid, shardId, noteKey, SessionHost, null);
			}
			catch (Exception ex)
			{
				ENSDKLogger.ENSDKLogError(string.Format("Failed to shareNote: {0}", ex.Message));
				throw new Exception(ex.Message, ex.InnerException);
			}
		}